blob: b0063850b36c0542bef8f3ee6b8250041a9593ae [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);
cristy33f41432009-10-09 01:25:24 +00001524 image_view=AcquireCacheView(image);
1525 p=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
cristy3ed852e2009-09-05 21:47:34 +00001526 if (p != (PixelPacket *) NULL)
1527 {
cristy33f41432009-10-09 01:25:24 +00001528 indexes=GetCacheViewAuthenticIndexQueue(image_view);
cristy3ed852e2009-09-05 21:47:34 +00001529 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 }
cristy33f41432009-10-09 01:25:24 +00001534 image_view=DestroyCacheView(image_view);
cristy3ed852e2009-09-05 21:47:34 +00001535 }
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);
cristy33f41432009-10-09 01:25:24 +00001754 image_view=AcquireCacheView(image);
1755 p=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1756 indexes=GetCacheViewAuthenticIndexQueue(image_view);
cristy3ed852e2009-09-05 21:47:34 +00001757 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 }
cristy33f41432009-10-09 01:25:24 +00001786 image_view=DestroyCacheView(image_view);
cristy3ed852e2009-09-05 21:47:34 +00001787 }
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)
cristy33f41432009-10-09 01:25:24 +00004370 {
4371 char
4372 key[MaxTextExtent];
4373
4374 MagickBooleanType
4375 status;
4376
4377 static long
4378 id = 0;
4379
4380 (void) FormatMagickString(key,MaxTextExtent,"%ld\n",id);
4381 status=SetImageRegistry(ImageRegistryType,key,image,
4382 &image->exception);
4383 s=newSViv(id++);
4384 }
cristy3ed852e2009-09-05 21:47:34 +00004385 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4386 continue;
4387 }
4388 if (LocaleNCompare(attribute,"index",5) == 0)
4389 {
4390 char
4391 name[MaxTextExtent];
4392
4393 int
4394 items;
4395
4396 long
4397 x,
4398 y;
4399
4400 register const IndexPacket
4401 *indexes;
4402
4403 register const PixelPacket
4404 *p;
4405
4406 CacheView
4407 *image_view;
4408
4409 if (image == (Image *) NULL)
4410 break;
4411 if (image->storage_class != PseudoClass)
4412 break;
4413 x=0;
4414 y=0;
4415 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
cristy33f41432009-10-09 01:25:24 +00004416 image_view=AcquireCacheView(image);
4417 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,&image->exception);
cristy3ed852e2009-09-05 21:47:34 +00004418 if (p != (const PixelPacket *) NULL)
4419 {
cristy33f41432009-10-09 01:25:24 +00004420 indexes=GetCacheViewVirtualIndexQueue(image_view);
cristy3ed852e2009-09-05 21:47:34 +00004421 (void) FormatMagickString(name,MaxTextExtent,QuantumFormat,
4422 *indexes);
4423 s=newSVpv(name,0);
4424 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4425 }
cristy33f41432009-10-09 01:25:24 +00004426 image_view=DestroyCacheView(image_view);
cristy3ed852e2009-09-05 21:47:34 +00004427 continue;
4428 }
4429 if (LocaleCompare(attribute,"iptc") == 0)
4430 {
4431 if (image != (Image *) NULL)
4432 {
4433 const StringInfo
4434 *profile;
4435
4436 profile=GetImageProfile(image,"iptc");
4437 if (profile != (const StringInfo *) NULL)
4438 s=newSVpv((const char *) GetStringInfoDatum(profile),
4439 GetStringInfoLength(profile));
4440 }
4441 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4442 continue;
4443 }
4444 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
4445 {
4446 if (image != (Image *) NULL)
4447 s=newSViv((long) image->iterations);
4448 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4449 continue;
4450 }
4451 if (LocaleCompare(attribute,"interlace") == 0)
4452 {
4453 j=info ? info->image_info->interlace : image->interlace;
4454 s=newSViv(j);
4455 (void) sv_setpv(s,MagickOptionToMnemonic(MagickInterlaceOptions,
4456 j));
4457 SvIOK_on(s);
4458 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4459 continue;
4460 }
4461 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4462 attribute);
4463 break;
4464 }
4465 case 'L':
4466 case 'l':
4467 {
4468 if (LocaleCompare(attribute,"label") == 0)
4469 {
4470 const char
4471 *value;
4472
4473 if (image == (Image *) NULL)
4474 break;
4475 value=GetImageProperty(image,"Label");
4476 if (value != (const char *) NULL)
4477 s=newSVpv(value,0);
4478 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4479 continue;
4480 }
4481 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
4482 {
4483 if (image != (Image *) NULL)
4484 s=newSViv((long) image->iterations);
4485 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4486 continue;
4487 }
4488 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4489 attribute);
4490 break;
4491 }
4492 case 'M':
4493 case 'm':
4494 {
4495 if (LocaleCompare(attribute,"magick") == 0)
4496 {
4497 if (info && *info->image_info->magick)
4498 s=newSVpv(info->image_info->magick,0);
4499 if (image != (Image *) NULL)
4500 s=newSVpv(image->magick,0);
4501 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4502 continue;
4503 }
4504 if (LocaleCompare(attribute,"map") == 0)
4505 {
4506 s=newSViv(GetMagickResource(MapResource));
4507 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4508 continue;
4509 }
4510 if (LocaleCompare(attribute,"maximum-error") == 0)
4511 {
4512 if (image != (Image *) NULL)
4513 s=newSVnv(image->error.normalized_maximum_error);
4514 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4515 continue;
4516 }
4517 if (LocaleCompare(attribute,"memory") == 0)
4518 {
4519 s=newSViv(GetMagickResource(MemoryResource));
4520 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4521 continue;
4522 }
4523 if (LocaleCompare(attribute,"mean-error") == 0)
4524 {
4525 if (image != (Image *) NULL)
4526 s=newSVnv(image->error.normalized_mean_error);
4527 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4528 continue;
4529 }
4530 if (LocaleCompare(attribute,"mime") == 0)
4531 {
4532 if (info && *info->image_info->magick)
4533 s=newSVpv(MagickToMime(info->image_info->magick),0);
4534 if (image != (Image *) NULL)
4535 s=newSVpv(MagickToMime(image->magick),0);
4536 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4537 continue;
4538 }
4539 if (LocaleCompare(attribute,"monochrome") == 0)
4540 {
4541 if (image == (Image *) NULL)
4542 continue;
4543 j=info ? info->image_info->monochrome :
4544 IsMonochromeImage(image,&image->exception);
4545 s=newSViv(j);
4546 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4547 continue;
4548 }
4549 if (LocaleCompare(attribute,"mattecolor") == 0)
4550 {
4551 if (image == (Image *) NULL)
4552 break;
4553 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
4554 QuantumFormat "," QuantumFormat "," QuantumFormat,
4555 image->matte_color.red,image->matte_color.green,
4556 image->matte_color.blue,image->matte_color.opacity);
4557 s=newSVpv(color,0);
4558 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4559 continue;
4560 }
4561 if (LocaleCompare(attribute,"matte") == 0)
4562 {
4563 if (image != (Image *) NULL)
4564 s=newSViv((long) image->matte);
4565 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4566 continue;
4567 }
4568 if (LocaleCompare(attribute,"montage") == 0)
4569 {
4570 if (image && image->montage)
4571 s=newSVpv(image->montage,0);
4572 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4573 continue;
4574 }
4575 if (LocaleCompare(attribute,"mime") == 0)
4576 {
4577 const char
4578 *magick;
4579
4580 magick=NULL;
4581 if (info && *info->image_info->magick)
4582 magick=info->image_info->magick;
4583 if (image != (Image *) NULL)
4584 magick=image->magick;
4585 if (magick)
4586 {
4587 char
4588 *mime;
4589
4590 mime=MagickToMime(magick);
4591 s=newSVpv(mime,0);
4592 mime=(char *) RelinquishMagickMemory(mime);
4593 }
4594 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4595 continue;
4596 }
4597 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4598 attribute);
4599 break;
4600 }
4601 case 'O':
4602 case 'o':
4603 {
4604 if (LocaleCompare(attribute,"orientation") == 0)
4605 {
4606 j=info ? info->image_info->orientation : image->orientation;
4607 s=newSViv(j);
4608 (void) sv_setpv(s,MagickOptionToMnemonic(MagickOrientationOptions,
4609 j));
4610 SvIOK_on(s);
4611 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4612 continue;
4613 }
4614 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4615 attribute);
4616 break;
4617 }
4618 case 'P':
4619 case 'p':
4620 {
4621 if (LocaleCompare(attribute,"page") == 0)
4622 {
4623 if (info && info->image_info->page)
4624 s=newSVpv(info->image_info->page,0);
4625 if (image != (Image *) NULL)
4626 {
4627 char
4628 geometry[MaxTextExtent];
4629
4630 (void) FormatMagickString(geometry,MaxTextExtent,
4631 "%lux%lu%+ld%+ld",image->page.width,image->page.height,
4632 image->page.x,image->page.y);
4633 s=newSVpv(geometry,0);
4634 }
4635 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4636 continue;
4637 }
4638 if (LocaleCompare(attribute,"page.x") == 0)
4639 {
4640 if (image != (Image *) NULL)
4641 s=newSViv((long) image->page.x);
4642 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4643 continue;
4644 }
4645 if (LocaleCompare(attribute,"page.y") == 0)
4646 {
4647 if (image != (Image *) NULL)
4648 s=newSViv((long) image->page.y);
4649 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4650 continue;
4651 }
4652 if (LocaleNCompare(attribute,"pixel",5) == 0)
4653 {
4654 char
4655 tuple[MaxTextExtent];
4656
4657 int
4658 items;
4659
4660 long
4661 x,
4662 y;
4663
4664 register const PixelPacket
4665 *p;
4666
4667 register const IndexPacket
4668 *indexes;
4669
4670 if (image == (Image *) NULL)
4671 break;
4672 x=0;
4673 y=0;
4674 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
4675 p=GetVirtualPixels(image,x,y,1,1,exception);
cristy33f41432009-10-09 01:25:24 +00004676 indexes=GetVirtualIndexQueue(image);
cristy3ed852e2009-09-05 21:47:34 +00004677 if (image->colorspace != CMYKColorspace)
4678 (void) FormatMagickString(tuple,MaxTextExtent,QuantumFormat ","
4679 QuantumFormat "," QuantumFormat "," QuantumFormat,
4680 p->red,p->green,p->blue,p->opacity);
4681 else
4682 (void) FormatMagickString(tuple,MaxTextExtent,QuantumFormat ","
4683 QuantumFormat "," QuantumFormat "," QuantumFormat ","
4684 QuantumFormat,p->red,p->green,p->blue,*indexes,p->opacity);
4685 s=newSVpv(tuple,0);
4686 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4687 continue;
4688 }
4689 if (LocaleCompare(attribute,"pointsize") == 0)
4690 {
4691 if (info)
4692 s=newSViv((long) info->image_info->pointsize);
4693 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4694 continue;
4695 }
4696 if (LocaleCompare(attribute,"preview") == 0)
4697 {
4698 s=newSViv(info->image_info->preview_type);
4699 (void) sv_setpv(s,MagickOptionToMnemonic(MagickPreviewOptions,
4700 info->image_info->preview_type));
4701 SvIOK_on(s);
4702 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4703 continue;
4704 }
4705 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4706 attribute);
4707 break;
4708 }
4709 case 'Q':
4710 case 'q':
4711 {
4712 if (LocaleCompare(attribute,"quality") == 0)
4713 {
4714 if (info)
4715 s=newSViv((long) info->image_info->quality);
4716 if (image != (Image *) NULL)
4717 s=newSViv((long) image->quality);
4718 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4719 continue;
4720 }
4721 if (LocaleCompare(attribute,"quantum") == 0)
4722 {
4723 if (info)
4724 s=newSViv((long) MAGICKCORE_QUANTUM_DEPTH);
4725 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4726 continue;
4727 }
4728 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4729 attribute);
4730 break;
4731 }
4732 case 'R':
4733 case 'r':
4734 {
4735 if (LocaleCompare(attribute,"rendering-intent") == 0)
4736 {
4737 s=newSViv(image->rendering_intent);
4738 (void) sv_setpv(s,MagickOptionToMnemonic(MagickIntentOptions,
4739 image->rendering_intent));
4740 SvIOK_on(s);
4741 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4742 continue;
4743 }
4744 if (LocaleCompare(attribute,"red-primary") == 0)
4745 {
4746 if (image == (Image *) NULL)
4747 break;
4748 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4749 image->chromaticity.red_primary.x,
4750 image->chromaticity.red_primary.y);
4751 s=newSVpv(color,0);
4752 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4753 continue;
4754 }
4755 if (LocaleCompare(attribute,"rows") == 0)
4756 {
4757 if (image != (Image *) NULL)
4758 s=newSViv((long) image->rows);
4759 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4760 continue;
4761 }
4762 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4763 attribute);
4764 break;
4765 }
4766 case 'S':
4767 case 's':
4768 {
4769 if (LocaleCompare(attribute,"sampling-factor") == 0)
4770 {
4771 if (info && info->image_info->sampling_factor)
4772 s=newSVpv(info->image_info->sampling_factor,0);
4773 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4774 continue;
4775 }
4776 if (LocaleCompare(attribute,"subimage") == 0)
4777 {
4778 if (info)
4779 s=newSViv((long) info->image_info->subimage);
4780 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4781 continue;
4782 }
4783 if (LocaleCompare(attribute,"subrange") == 0)
4784 {
4785 if (info)
4786 s=newSViv((long) info->image_info->subrange);
4787 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4788 continue;
4789 }
4790 if (LocaleCompare(attribute,"server") == 0) /* same as display */
4791 {
4792 if (info && info->image_info->server_name)
4793 s=newSVpv(info->image_info->server_name,0);
4794 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4795 continue;
4796 }
4797 if (LocaleCompare(attribute,"size") == 0)
4798 {
4799 if (info && info->image_info->size)
4800 s=newSVpv(info->image_info->size,0);
4801 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4802 continue;
4803 }
4804 if (LocaleCompare(attribute,"scene") == 0)
4805 {
4806 if (image != (Image *) NULL)
4807 s=newSViv((long) image->scene);
4808 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4809 continue;
4810 }
4811 if (LocaleCompare(attribute,"scenes") == 0)
4812 {
4813 if (image != (Image *) NULL)
4814 s=newSViv((long) info->image_info->number_scenes);
4815 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4816 continue;
4817 }
4818 if (LocaleCompare(attribute,"signature") == 0)
4819 {
4820 const char
4821 *value;
4822
4823 if (image == (Image *) NULL)
4824 break;
4825 (void) SignatureImage(image);
4826 value=GetImageProperty(image,"Signature");
4827 if (value != (const char *) NULL)
4828 s=newSVpv(value,0);
4829 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4830 continue;
4831 }
4832 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4833 attribute);
4834 break;
4835 }
4836 case 'T':
4837 case 't':
4838 {
4839 if (LocaleCompare(attribute,"taint") == 0)
4840 {
4841 if (image != (Image *) NULL)
4842 s=newSViv((long) IsTaintImage(image));
4843 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4844 continue;
4845 }
4846 if (LocaleCompare(attribute,"tile") == 0)
4847 {
4848 if (info && info->image_info->tile)
4849 s=newSVpv(info->image_info->tile,0);
4850 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4851 continue;
4852 }
4853 if (LocaleCompare(attribute,"texture") == 0)
4854 {
4855 if (info && info->image_info->texture)
4856 s=newSVpv(info->image_info->texture,0);
4857 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4858 continue;
4859 }
4860 if (LocaleCompare(attribute,"total-ink-density") == 0)
4861 {
4862 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4863 if (image != (Image *) NULL)
4864 s=newSVnv(GetImageTotalInkDensity(image));
4865 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4866 continue;
4867 }
4868 if (LocaleCompare(attribute,"type") == 0)
4869 {
4870 if (image == (Image *) NULL)
4871 break;
4872 j=(long) GetImageType(image,&image->exception);
4873 s=newSViv(j);
4874 (void) sv_setpv(s,MagickOptionToMnemonic(MagickTypeOptions,j));
4875 SvIOK_on(s);
4876 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4877 continue;
4878 }
4879 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4880 attribute);
4881 break;
4882 }
4883 case 'U':
4884 case 'u':
4885 {
4886 if (LocaleCompare(attribute,"units") == 0)
4887 {
4888 j=info ? info->image_info->units : image->units;
4889 if (info)
4890 if (info->image_info->units == UndefinedResolution)
4891 j=image->units;
4892 if (j == UndefinedResolution)
4893 s=newSVpv("undefined units",0);
4894 else
4895 if (j == PixelsPerInchResolution)
4896 s=newSVpv("pixels / inch",0);
4897 else
4898 s=newSVpv("pixels / centimeter",0);
4899 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4900 continue;
4901 }
4902 if (LocaleCompare(attribute,"user-time") == 0)
4903 {
4904 if (image != (Image *) NULL)
4905 s=newSVnv(GetUserTime(&image->timer));
4906 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4907 continue;
4908 }
4909 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4910 attribute);
4911 break;
4912 }
4913 case 'V':
4914 case 'v':
4915 {
4916 if (LocaleCompare(attribute,"verbose") == 0)
4917 {
4918 if (info)
4919 s=newSViv((long) info->image_info->verbose);
4920 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4921 continue;
4922 }
4923 if (LocaleCompare(attribute,"version") == 0)
4924 {
4925 s=newSVpv(GetMagickVersion((unsigned long *) NULL),0);
4926 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4927 continue;
4928 }
4929 if (LocaleCompare(attribute,"view") == 0)
4930 {
4931 if (info && info->image_info->view)
4932 s=newSVpv(info->image_info->view,0);
4933 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4934 continue;
4935 }
4936 if (LocaleCompare(attribute,"virtual-pixel") == 0)
4937 {
4938 if (image == (Image *) NULL)
4939 break;
4940 j=(long) GetImageVirtualPixelMethod(image);
4941 s=newSViv(j);
4942 (void) sv_setpv(s,MagickOptionToMnemonic(
4943 MagickVirtualPixelOptions,j));
4944 SvIOK_on(s);
4945 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4946 continue;
4947 }
4948 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4949 attribute);
4950 break;
4951 }
4952 case 'W':
4953 case 'w':
4954 {
4955 if (LocaleCompare(attribute,"white-point") == 0)
4956 {
4957 if (image == (Image *) NULL)
4958 break;
4959 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4960 image->chromaticity.white_point.x,
4961 image->chromaticity.white_point.y);
4962 s=newSVpv(color,0);
4963 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4964 continue;
4965 }
4966 if (LocaleCompare(attribute,"width") == 0)
4967 {
4968 if (image != (Image *) NULL)
4969 s=newSViv((long) image->columns);
4970 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4971 continue;
4972 }
4973 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4974 attribute);
4975 break;
4976 }
4977 case 'X':
4978 case 'x':
4979 {
4980 if (LocaleCompare(attribute,"x-resolution") == 0)
4981 {
4982 if (image != (Image *) NULL)
4983 s=newSVnv(image->x_resolution);
4984 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4985 continue;
4986 }
4987 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4988 attribute);
4989 break;
4990 }
4991 case 'Y':
4992 case 'y':
4993 {
4994 if (LocaleCompare(attribute,"y-resolution") == 0)
4995 {
4996 if (image != (Image *) NULL)
4997 s=newSVnv(image->y_resolution);
4998 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4999 continue;
5000 }
5001 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5002 attribute);
5003 break;
5004 }
5005 default:
5006 break;
5007 }
5008 if (image == (Image *) NULL)
5009 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5010 attribute)
5011 else
5012 {
5013 value=GetImageProperty(image,attribute);
5014 if (value != (const char *) NULL)
5015 {
5016 s=newSVpv(value,0);
5017 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5018 }
5019 else
5020 if (*attribute != '%')
5021 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5022 attribute)
5023 else
5024 {
5025 char
5026 *meta;
5027
5028 meta=InterpretImageProperties(info ? info->image_info :
5029 (ImageInfo *) NULL,image,attribute);
5030 s=newSVpv(meta,0);
5031 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5032 meta=(char *) RelinquishMagickMemory(meta);
5033 }
5034 }
5035 }
5036 exception=DestroyExceptionInfo(exception);
5037 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5038 }
5039
5040#
5041###############################################################################
5042# #
5043# #
5044# #
5045# G e t A u t h e n t i c P i x e l s #
5046# #
5047# #
5048# #
5049###############################################################################
5050#
5051#
5052void *
5053GetAuthenticPixels(ref,...)
5054 Image::Magick ref = NO_INIT
5055 ALIAS:
5056 getauthenticpixels = 1
5057 GetImagePixels = 2
5058 getimagepixels = 3
5059 CODE:
5060 {
5061 char
5062 *attribute;
5063
5064 ExceptionInfo
5065 *exception;
5066
5067 Image
5068 *image;
5069
5070 long
5071 i;
5072
5073 RectangleInfo
5074 region;
5075
5076 struct PackageInfo
5077 *info;
5078
5079 SV
5080 *perl_exception,
5081 *reference;
5082
5083 void
5084 *blob = NULL;
5085
5086 exception=AcquireExceptionInfo();
5087 perl_exception=newSVpv("",0);
5088 if (sv_isobject(ST(0)) == 0)
5089 {
5090 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5091 PackageName);
5092 goto PerlException;
5093 }
5094 reference=SvRV(ST(0));
5095
5096 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5097 if (image == (Image *) NULL)
5098 {
5099 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5100 PackageName);
5101 goto PerlException;
5102 }
5103
5104 region.x=0;
5105 region.y=0;
5106 region.width=image->columns;
5107 region.height=1;
5108 if (items == 1)
5109 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5110 for (i=2; i < items; i+=2)
5111 {
5112 attribute=(char *) SvPV(ST(i-1),na);
5113 switch (*attribute)
5114 {
5115 case 'g':
5116 case 'G':
5117 {
5118 if (LocaleCompare(attribute,"geometry") == 0)
5119 {
5120 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5121 break;
5122 }
5123 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5124 attribute);
5125 break;
5126 }
5127 case 'H':
5128 case 'h':
5129 {
5130 if (LocaleCompare(attribute,"height") == 0)
5131 {
5132 region.height=SvIV(ST(i));
5133 continue;
5134 }
5135 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5136 attribute);
5137 break;
5138 }
5139 case 'X':
5140 case 'x':
5141 {
5142 if (LocaleCompare(attribute,"x") == 0)
5143 {
5144 region.x=SvIV(ST(i));
5145 continue;
5146 }
5147 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5148 attribute);
5149 break;
5150 }
5151 case 'Y':
5152 case 'y':
5153 {
5154 if (LocaleCompare(attribute,"y") == 0)
5155 {
5156 region.y=SvIV(ST(i));
5157 continue;
5158 }
5159 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5160 attribute);
5161 break;
5162 }
5163 case 'W':
5164 case 'w':
5165 {
5166 if (LocaleCompare(attribute,"width") == 0)
5167 {
5168 region.width=SvIV(ST(i));
5169 continue;
5170 }
5171 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5172 attribute);
5173 break;
5174 }
5175 }
5176 }
5177 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5178 region.height,exception);
5179 if (blob != (void *) NULL)
5180 goto PerlEnd;
5181
5182 PerlException:
5183 InheritPerlException(exception,perl_exception);
5184 exception=DestroyExceptionInfo(exception);
5185 SvREFCNT_dec(perl_exception); /* throw away all errors */
5186
5187 PerlEnd:
5188 RETVAL = blob;
5189 }
5190 OUTPUT:
5191 RETVAL
5192
5193#
5194###############################################################################
5195# #
5196# #
5197# #
5198# G e t V i r t u a l P i x e l s #
5199# #
5200# #
5201# #
5202###############################################################################
5203#
5204#
5205void *
5206GetVirtualPixels(ref,...)
5207 Image::Magick ref = NO_INIT
5208 ALIAS:
5209 getvirtualpixels = 1
5210 AcquireImagePixels = 2
5211 acquireimagepixels = 3
5212 CODE:
5213 {
5214 char
5215 *attribute;
5216
5217 const void
5218 *blob = NULL;
5219
5220 ExceptionInfo
5221 *exception;
5222
5223 Image
5224 *image;
5225
5226 long
5227 i;
5228
5229 RectangleInfo
5230 region;
5231
5232 struct PackageInfo
5233 *info;
5234
5235 SV
5236 *perl_exception,
5237 *reference;
5238
5239 exception=AcquireExceptionInfo();
5240 perl_exception=newSVpv("",0);
5241 if (sv_isobject(ST(0)) == 0)
5242 {
5243 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5244 PackageName);
5245 goto PerlException;
5246 }
5247 reference=SvRV(ST(0));
5248
5249 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5250 if (image == (Image *) NULL)
5251 {
5252 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5253 PackageName);
5254 goto PerlException;
5255 }
5256
5257 region.x=0;
5258 region.y=0;
5259 region.width=image->columns;
5260 region.height=1;
5261 if (items == 1)
5262 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5263 for (i=2; i < items; i+=2)
5264 {
5265 attribute=(char *) SvPV(ST(i-1),na);
5266 switch (*attribute)
5267 {
5268 case 'g':
5269 case 'G':
5270 {
5271 if (LocaleCompare(attribute,"geometry") == 0)
5272 {
5273 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5274 break;
5275 }
5276 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5277 attribute);
5278 break;
5279 }
5280 case 'H':
5281 case 'h':
5282 {
5283 if (LocaleCompare(attribute,"height") == 0)
5284 {
5285 region.height=SvIV(ST(i));
5286 continue;
5287 }
5288 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5289 attribute);
5290 break;
5291 }
5292 case 'X':
5293 case 'x':
5294 {
5295 if (LocaleCompare(attribute,"x") == 0)
5296 {
5297 region.x=SvIV(ST(i));
5298 continue;
5299 }
5300 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5301 attribute);
5302 break;
5303 }
5304 case 'Y':
5305 case 'y':
5306 {
5307 if (LocaleCompare(attribute,"y") == 0)
5308 {
5309 region.y=SvIV(ST(i));
5310 continue;
5311 }
5312 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5313 attribute);
5314 break;
5315 }
5316 case 'W':
5317 case 'w':
5318 {
5319 if (LocaleCompare(attribute,"width") == 0)
5320 {
5321 region.width=SvIV(ST(i));
5322 continue;
5323 }
5324 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5325 attribute);
5326 break;
5327 }
5328 }
5329 }
5330 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
5331 region.height,exception);
5332 if (blob != (void *) NULL)
5333 goto PerlEnd;
5334
5335 PerlException:
5336 InheritPerlException(exception,perl_exception);
5337 exception=DestroyExceptionInfo(exception);
5338 SvREFCNT_dec(perl_exception); /* throw away all errors */
5339
5340 PerlEnd:
5341 RETVAL = (void *) blob;
5342 }
5343 OUTPUT:
5344 RETVAL
5345
5346#
5347###############################################################################
5348# #
5349# #
5350# #
5351# G e t A u t h e n t i c I n d e x Q u e u e #
5352# #
5353# #
5354# #
5355###############################################################################
5356#
5357#
5358void *
5359GetAuthenticIndexQueue(ref,...)
5360 Image::Magick ref = NO_INIT
5361 ALIAS:
5362 getauthenticindexqueue = 1
5363 GetIndexes = 2
5364 getindexes = 3
5365 CODE:
5366 {
5367 ExceptionInfo
5368 *exception;
5369
5370 Image
5371 *image;
5372
5373 struct PackageInfo
5374 *info;
5375
5376 SV
5377 *perl_exception,
5378 *reference;
5379
5380 void
5381 *blob = NULL;
5382
5383 exception=AcquireExceptionInfo();
5384 perl_exception=newSVpv("",0);
5385 if (sv_isobject(ST(0)) == 0)
5386 {
5387 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5388 PackageName);
5389 goto PerlException;
5390 }
5391 reference=SvRV(ST(0));
5392
5393 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5394 if (image == (Image *) NULL)
5395 {
5396 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5397 PackageName);
5398 goto PerlException;
5399 }
5400
5401 blob=(void *) GetAuthenticIndexQueue(image);
5402 if (blob != (void *) NULL)
5403 goto PerlEnd;
5404
5405 PerlException:
5406 InheritPerlException(exception,perl_exception);
5407 exception=DestroyExceptionInfo(exception);
5408 SvREFCNT_dec(perl_exception); /* throw away all errors */
5409
5410 PerlEnd:
5411 RETVAL = blob;
5412 }
5413 OUTPUT:
5414 RETVAL
5415
5416#
5417###############################################################################
5418# #
5419# #
5420# #
5421# G e t V i r t u a l I n d e x Q u e u e #
5422# #
5423# #
5424# #
5425###############################################################################
5426#
5427#
5428void *
5429GetVirtualIndexQueue(ref,...)
5430 Image::Magick ref = NO_INIT
5431 ALIAS:
5432 getvirtualindexqueue = 1
5433 CODE:
5434 {
5435 ExceptionInfo
5436 *exception;
5437
5438 Image
5439 *image;
5440
5441 struct PackageInfo
5442 *info;
5443
5444 SV
5445 *perl_exception,
5446 *reference;
5447
5448 void
5449 *blob = NULL;
5450
5451 exception=AcquireExceptionInfo();
5452 perl_exception=newSVpv("",0);
5453 if (sv_isobject(ST(0)) == 0)
5454 {
5455 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5456 PackageName);
5457 goto PerlException;
5458 }
5459 reference=SvRV(ST(0));
5460
5461 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5462 if (image == (Image *) NULL)
5463 {
5464 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5465 PackageName);
5466 goto PerlException;
5467 }
5468
5469 blob=(void *) GetVirtualIndexQueue(image);
5470 if (blob != (void *) NULL)
5471 goto PerlEnd;
5472
5473 PerlException:
5474 InheritPerlException(exception,perl_exception);
5475 exception=DestroyExceptionInfo(exception);
5476 SvREFCNT_dec(perl_exception); /* throw away all errors */
5477
5478 PerlEnd:
5479 RETVAL = blob;
5480 }
5481 OUTPUT:
5482 RETVAL
5483
5484#
5485###############################################################################
5486# #
5487# #
5488# #
5489# H i s t o g r a m #
5490# #
5491# #
5492# #
5493###############################################################################
5494#
5495#
5496void
5497Histogram(ref,...)
5498 Image::Magick ref=NO_INIT
5499 ALIAS:
5500 HistogramImage = 1
5501 histogram = 2
5502 histogramimage = 3
5503 PPCODE:
5504 {
5505 AV
5506 *av;
5507
5508 char
5509 message[MaxTextExtent];
5510
5511 ColorPacket
5512 *histogram;
5513
5514 ExceptionInfo
5515 *exception;
5516
5517 HV
5518 *hv;
5519
5520 Image
5521 *image;
5522
5523 register long
5524 i;
5525
5526 ssize_t
5527 count;
5528
5529 struct PackageInfo
5530 *info;
5531
5532 SV
5533 *av_reference,
5534 *perl_exception,
5535 *reference;
5536
5537 unsigned long
5538 number_colors;
5539
5540 exception=AcquireExceptionInfo();
5541 perl_exception=newSVpv("",0);
5542 av=NULL;
5543 if (sv_isobject(ST(0)) == 0)
5544 {
5545 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5546 PackageName);
5547 goto PerlException;
5548 }
5549 reference=SvRV(ST(0));
5550 hv=SvSTASH(reference);
5551 av=newAV();
5552 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
5553 SvREFCNT_dec(av);
5554 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5555 if (image == (Image *) NULL)
5556 {
5557 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5558 PackageName);
5559 goto PerlException;
5560 }
5561 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
5562 count=0;
5563 for ( ; image; image=image->next)
5564 {
5565 histogram=GetImageHistogram(image,&number_colors,&image->exception);
5566 if (histogram == (ColorPacket *) NULL)
5567 continue;
5568 count+=number_colors;
5569 EXTEND(sp,6*count);
5570 for (i=0; i < (long) number_colors; i++)
5571 {
5572 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5573 histogram[i].pixel.red);
5574 PUSHs(sv_2mortal(newSVpv(message,0)));
5575 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5576 histogram[i].pixel.green);
5577 PUSHs(sv_2mortal(newSVpv(message,0)));
5578 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5579 histogram[i].pixel.blue);
5580 PUSHs(sv_2mortal(newSVpv(message,0)));
5581 if (image->colorspace == CMYKColorspace)
5582 {
5583 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5584 histogram[i].index);
5585 PUSHs(sv_2mortal(newSVpv(message,0)));
5586 }
5587 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5588 histogram[i].pixel.opacity);
5589 PUSHs(sv_2mortal(newSVpv(message,0)));
5590 (void) FormatMagickString(message,MaxTextExtent,"%lu",
5591 (unsigned long) histogram[i].count);
5592 PUSHs(sv_2mortal(newSVpv(message,0)));
5593 }
5594 histogram=(ColorPacket *) RelinquishMagickMemory(histogram);
5595 }
5596
5597 PerlException:
5598 InheritPerlException(exception,perl_exception);
5599 exception=DestroyExceptionInfo(exception);
5600 SvREFCNT_dec(perl_exception);
5601 }
5602
5603#
5604###############################################################################
5605# #
5606# #
5607# #
5608# G e t P i x e l #
5609# #
5610# #
5611# #
5612###############################################################################
5613#
5614#
5615void
5616GetPixel(ref,...)
5617 Image::Magick ref=NO_INIT
5618 ALIAS:
5619 getpixel = 1
5620 getPixel = 2
5621 PPCODE:
5622 {
5623 AV
5624 *av;
5625
5626 char
5627 *attribute;
5628
5629 ChannelType
5630 channel;
5631
5632 ExceptionInfo
5633 *exception;
5634
5635 Image
5636 *image;
5637
5638 long
5639 option;
5640
5641 MagickBooleanType
5642 normalize;
5643
5644 RectangleInfo
5645 region;
5646
5647 register const IndexPacket
5648 *indexes;
5649
5650 register const PixelPacket
5651 *p;
5652
5653 register long
5654 i;
5655
5656 struct PackageInfo
5657 *info;
5658
5659 SV
5660 *perl_exception,
5661 *reference; /* reference is the SV* of ref=SvIV(reference) */
5662
5663 exception=AcquireExceptionInfo();
5664 perl_exception=newSVpv("",0);
5665 reference=SvRV(ST(0));
5666 av=(AV *) reference;
5667 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
5668 exception);
5669 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5670 if (image == (Image *) NULL)
5671 {
5672 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5673 PackageName);
5674 goto PerlException;
5675 }
5676 channel=DefaultChannels;
5677 normalize=MagickTrue;
5678 region.x=0;
5679 region.y=0;
5680 region.width=image->columns;
5681 region.height=1;
5682 if (items == 1)
5683 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5684 for (i=2; i < items; i+=2)
5685 {
5686 attribute=(char *) SvPV(ST(i-1),na);
5687 switch (*attribute)
5688 {
5689 case 'C':
5690 case 'c':
5691 {
5692 if (LocaleCompare(attribute,"channel") == 0)
5693 {
5694 long
5695 option;
5696
5697 option=ParseChannelOption(SvPV(ST(i),na));
5698 if (option < 0)
5699 {
5700 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5701 SvPV(ST(i),na));
5702 return;
5703 }
5704 channel=(ChannelType) option;
5705 break;
5706 }
5707 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5708 attribute);
5709 break;
5710 }
5711 case 'g':
5712 case 'G':
5713 {
5714 if (LocaleCompare(attribute,"geometry") == 0)
5715 {
5716 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5717 break;
5718 }
5719 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5720 attribute);
5721 break;
5722 }
5723 case 'N':
5724 case 'n':
5725 {
5726 if (LocaleCompare(attribute,"normalize") == 0)
5727 {
5728 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
5729 SvPV(ST(i),na));
5730 if (option < 0)
5731 {
5732 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5733 SvPV(ST(i),na));
5734 break;
5735 }
5736 normalize=option != 0 ? MagickTrue : MagickFalse;
5737 break;
5738 }
5739 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5740 attribute);
5741 break;
5742 }
5743 case 'x':
5744 case 'X':
5745 {
5746 if (LocaleCompare(attribute,"x") == 0)
5747 {
5748 region.x=SvIV(ST(i));
5749 break;
5750 }
5751 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5752 attribute);
5753 break;
5754 }
5755 case 'y':
5756 case 'Y':
5757 {
5758 if (LocaleCompare(attribute,"y") == 0)
5759 {
5760 region.y=SvIV(ST(i));
5761 break;
5762 }
5763 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5764 attribute);
5765 break;
5766 }
5767 default:
5768 {
5769 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5770 attribute);
5771 break;
5772 }
5773 }
5774 }
5775 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
5776 if (p == (const PixelPacket *) NULL)
5777 PUSHs(&sv_undef);
5778 else
5779 {
5780 double
5781 scale;
5782
cristy33f41432009-10-09 01:25:24 +00005783 indexes=GetVirtualIndexQueue(image);
cristy3ed852e2009-09-05 21:47:34 +00005784 scale=1.0;
5785 if (normalize != MagickFalse)
5786 scale=1.0/QuantumRange;
5787 if ((channel & RedChannel) != 0)
5788 PUSHs(sv_2mortal(newSVnv(scale*p->red)));
5789 if ((channel & GreenChannel) != 0)
5790 PUSHs(sv_2mortal(newSVnv(scale*p->green)));
5791 if ((channel & BlueChannel) != 0)
5792 PUSHs(sv_2mortal(newSVnv(scale*p->blue)));
5793 if (((channel & IndexChannel) != 0) &&
5794 (image->colorspace == CMYKColorspace))
5795 PUSHs(sv_2mortal(newSVnv(scale*(*indexes))));
5796 if ((channel & OpacityChannel) != 0)
5797 PUSHs(sv_2mortal(newSVnv(scale*p->opacity)));
5798 }
5799
5800 PerlException:
5801 InheritPerlException(exception,perl_exception);
5802 exception=DestroyExceptionInfo(exception);
5803 SvREFCNT_dec(perl_exception);
5804 }
5805
5806#
5807###############################################################################
5808# #
5809# #
5810# #
5811# G e t P i x e l s #
5812# #
5813# #
5814# #
5815###############################################################################
5816#
5817#
5818void
5819GetPixels(ref,...)
5820 Image::Magick ref=NO_INIT
5821 ALIAS:
5822 getpixels = 1
5823 getPixels = 2
5824 PPCODE:
5825 {
5826 AV
5827 *av;
5828
5829 char
5830 *attribute;
5831
5832 const char
5833 *map;
5834
5835 ExceptionInfo
5836 *exception;
5837
5838 Image
5839 *image;
5840
5841 long
5842 option;
5843
5844 MagickBooleanType
5845 normalize,
5846 status;
5847
5848 RectangleInfo
5849 region;
5850
5851 register long
5852 i;
5853
5854 struct PackageInfo
5855 *info;
5856
5857 SV
5858 *perl_exception,
5859 *reference; /* reference is the SV* of ref=SvIV(reference) */
5860
5861 exception=AcquireExceptionInfo();
5862 perl_exception=newSVpv("",0);
5863 reference=SvRV(ST(0));
5864 av=(AV *) reference;
5865 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
5866 exception);
5867 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5868 if (image == (Image *) NULL)
5869 {
5870 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5871 PackageName);
5872 goto PerlException;
5873 }
5874 map="RGB";
5875 if (image->matte != MagickFalse)
5876 map="RGBA";
5877 if (image->colorspace == CMYKColorspace)
5878 {
5879 map="CMYK";
5880 if (image->matte != MagickFalse)
5881 map="CMYKA";
5882 }
5883 normalize=MagickFalse;
5884 region.x=0;
5885 region.y=0;
5886 region.width=image->columns;
5887 region.height=1;
5888 if (items == 1)
5889 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5890 for (i=2; i < items; i+=2)
5891 {
5892 attribute=(char *) SvPV(ST(i-1),na);
5893 switch (*attribute)
5894 {
5895 case 'g':
5896 case 'G':
5897 {
5898 if (LocaleCompare(attribute,"geometry") == 0)
5899 {
5900 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5901 break;
5902 }
5903 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5904 attribute);
5905 break;
5906 }
5907 case 'H':
5908 case 'h':
5909 {
5910 if (LocaleCompare(attribute,"height") == 0)
5911 {
5912 region.height=SvIV(ST(i));
5913 break;
5914 }
5915 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5916 attribute);
5917 break;
5918 }
5919 case 'M':
5920 case 'm':
5921 {
5922 if (LocaleCompare(attribute,"map") == 0)
5923 {
5924 map=SvPV(ST(i),na);
5925 break;
5926 }
5927 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5928 attribute);
5929 break;
5930 }
5931 case 'N':
5932 case 'n':
5933 {
5934 if (LocaleCompare(attribute,"normalize") == 0)
5935 {
5936 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
5937 SvPV(ST(i),na));
5938 if (option < 0)
5939 {
5940 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5941 SvPV(ST(i),na));
5942 break;
5943 }
5944 normalize=option != 0 ? MagickTrue : MagickFalse;
5945 break;
5946 }
5947 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5948 attribute);
5949 break;
5950 }
5951 case 'W':
5952 case 'w':
5953 {
5954 if (LocaleCompare(attribute,"width") == 0)
5955 {
5956 region.width=SvIV(ST(i));
5957 break;
5958 }
5959 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5960 attribute);
5961 break;
5962 }
5963 case 'x':
5964 case 'X':
5965 {
5966 if (LocaleCompare(attribute,"x") == 0)
5967 {
5968 region.x=SvIV(ST(i));
5969 break;
5970 }
5971 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5972 attribute);
5973 break;
5974 }
5975 case 'y':
5976 case 'Y':
5977 {
5978 if (LocaleCompare(attribute,"y") == 0)
5979 {
5980 region.y=SvIV(ST(i));
5981 break;
5982 }
5983 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5984 attribute);
5985 break;
5986 }
5987 default:
5988 {
5989 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5990 attribute);
5991 break;
5992 }
5993 }
5994 }
5995 if (normalize != MagickFalse)
5996 {
5997 float
5998 *pixels;
5999
6000 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6001 region.height*sizeof(*pixels));
6002 if (pixels == (float *) NULL)
6003 {
6004 ThrowPerlException(exception,ResourceLimitError,
6005 "MemoryAllocationFailed",PackageName);
6006 goto PerlException;
6007 }
6008 status=ExportImagePixels(image,region.x,region.y,region.width,
6009 region.height,map,FloatPixel,pixels,exception);
6010 if (status == MagickFalse)
6011 PUSHs(&sv_undef);
6012 else
6013 {
6014 EXTEND(sp,strlen(map)*region.width*region.height);
6015 for (i=0; i < (long) (strlen(map)*region.width*region.height); i++)
6016 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6017 }
6018 pixels=(float *) RelinquishMagickMemory(pixels);
6019 }
6020 else
6021 {
6022 Quantum
6023 *pixels;
6024
6025 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6026 region.height*sizeof(*pixels));
6027 if (pixels == (Quantum *) NULL)
6028 {
6029 ThrowPerlException(exception,ResourceLimitError,
6030 "MemoryAllocationFailed",PackageName);
6031 goto PerlException;
6032 }
6033 status=ExportImagePixels(image,region.x,region.y,region.width,
6034 region.height,map,QuantumPixel,pixels,exception);
6035 if (status == MagickFalse)
6036 PUSHs(&sv_undef);
6037 else
6038 {
6039 EXTEND(sp,strlen(map)*region.width*region.height);
6040 for (i=0; i < (long) (strlen(map)*region.width*region.height); i++)
6041 PUSHs(sv_2mortal(newSViv(pixels[i])));
6042 }
6043 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6044 }
6045
6046 PerlException:
6047 InheritPerlException(exception,perl_exception);
6048 exception=DestroyExceptionInfo(exception);
6049 SvREFCNT_dec(perl_exception);
6050 }
6051
6052#
6053###############################################################################
6054# #
6055# #
6056# #
6057# I m a g e T o B l o b #
6058# #
6059# #
6060# #
6061###############################################################################
6062#
6063#
6064void
6065ImageToBlob(ref,...)
6066 Image::Magick ref=NO_INIT
6067 ALIAS:
6068 ImageToBlob = 1
6069 imagetoblob = 2
6070 toblob = 3
6071 blob = 4
6072 PPCODE:
6073 {
6074 char
6075 filename[MaxTextExtent];
6076
6077 ExceptionInfo
6078 *exception;
6079
6080 Image
6081 *image,
6082 *next;
6083
6084 long
6085 scene;
6086
6087 register long
6088 i;
6089
6090 struct PackageInfo
6091 *info,
6092 *package_info;
6093
6094 size_t
6095 length;
6096
6097 SV
6098 *perl_exception,
6099 *reference;
6100
6101 void
6102 *blob;
6103
6104 exception=AcquireExceptionInfo();
6105 perl_exception=newSVpv("",0);
6106 package_info=(struct PackageInfo *) NULL;
6107 if (sv_isobject(ST(0)) == 0)
6108 {
6109 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6110 PackageName);
6111 goto PerlException;
6112 }
6113 reference=SvRV(ST(0));
6114 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6115 if (image == (Image *) NULL)
6116 {
6117 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6118 PackageName);
6119 goto PerlException;
6120 }
6121 package_info=ClonePackageInfo(info,exception);
6122 for (i=2; i < items; i+=2)
6123 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6124 (void) CopyMagickString(filename,package_info->image_info->filename,
6125 MaxTextExtent);
6126 scene=0;
6127 for (next=image; next; next=next->next)
6128 {
6129 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
6130 next->scene=scene++;
6131 }
6132 SetImageInfo(package_info->image_info,MagickTrue,&image->exception);
6133 EXTEND(sp,(long) GetImageListLength(image));
6134 for ( ; image; image=image->next)
6135 {
6136 length=0;
6137 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6138 if (blob != (char *) NULL)
6139 {
6140 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6141 blob=(unsigned char *) RelinquishMagickMemory(blob);
6142 }
6143 if (package_info->image_info->adjoin)
6144 break;
6145 }
6146
6147 PerlException:
6148 if (package_info != (struct PackageInfo *) NULL)
6149 DestroyPackageInfo(package_info);
6150 InheritPerlException(exception,perl_exception);
6151 exception=DestroyExceptionInfo(exception);
6152 SvREFCNT_dec(perl_exception); /* throw away all errors */
6153 }
6154
6155#
6156###############################################################################
6157# #
6158# #
6159# #
6160# L a y e r s #
6161# #
6162# #
6163# #
6164###############################################################################
6165#
6166#
6167void
6168Layers(ref,...)
6169 Image::Magick ref=NO_INIT
6170 ALIAS:
6171 Layers = 1
6172 layers = 2
6173 OptimizeImageLayers = 3
6174 optimizelayers = 4
6175 optimizeimagelayers = 5
6176 PPCODE:
6177 {
6178 AV
6179 *av;
6180
6181 char
6182 *attribute;
6183
6184 CompositeOperator
6185 compose;
6186
6187 ExceptionInfo
6188 *exception;
6189
6190 HV
6191 *hv;
6192
6193 Image
6194 *image,
6195 *layers;
6196
6197 long
6198 option,
6199 sp;
6200
6201 MagickBooleanType
6202 dither;
6203
6204 ImageLayerMethod
6205 method;
6206
6207 register long
6208 i;
6209
6210 struct PackageInfo
6211 *info;
6212
6213 SV
6214 *av_reference,
6215 *perl_exception,
6216 *reference,
6217 *rv,
6218 *sv;
6219
6220 exception=AcquireExceptionInfo();
6221 perl_exception=newSVpv("",0);
6222 if (sv_isobject(ST(0)) == 0)
6223 {
6224 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6225 PackageName);
6226 goto PerlException;
6227 }
6228 reference=SvRV(ST(0));
6229 hv=SvSTASH(reference);
6230 av=newAV();
6231 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
6232 SvREFCNT_dec(av);
6233 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6234 if (image == (Image *) NULL)
6235 {
6236 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6237 PackageName);
6238 goto PerlException;
6239 }
6240 compose=image->compose;
6241 dither=MagickFalse;
6242 method=OptimizeLayer;
6243 for (i=2; i < items; i+=2)
6244 {
6245 attribute=(char *) SvPV(ST(i-1),na);
6246 switch (*attribute)
6247 {
6248 case 'C':
6249 case 'c':
6250 {
6251 if (LocaleCompare(attribute,"compose") == 0)
6252 {
6253 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
6254 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
6255 if (sp < 0)
6256 {
6257 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6258 SvPV(ST(i),na));
6259 break;
6260 }
6261 compose=(CompositeOperator) sp;
6262 break;
6263 }
6264 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6265 attribute);
6266 break;
6267 }
6268 case 'D':
6269 case 'd':
6270 {
6271 if (LocaleCompare(attribute,"dither") == 0)
6272 {
6273 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
6274 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
6275 if (sp < 0)
6276 {
6277 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6278 SvPV(ST(i),na));
6279 break;
6280 }
6281 dither=(MagickBooleanType) sp;
6282 break;
6283 }
6284 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6285 attribute);
6286 break;
6287 }
6288 case 'M':
6289 case 'm':
6290 {
6291 if (LocaleCompare(attribute,"method") == 0)
6292 {
6293 option=ParseMagickOption(MagickLayerOptions,MagickFalse,
6294 SvPV(ST(i),na));
6295 if (option < 0)
6296 {
6297 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6298 SvPV(ST(i),na));
6299 break;
6300 }
6301 method=(ImageLayerMethod) option;
6302 break;
6303 }
6304 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6305 attribute);
6306 break;
6307 }
6308 default:
6309 {
6310 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6311 attribute);
6312 break;
6313 }
6314 }
6315 }
6316 layers=(Image *) NULL;
6317 switch (method)
6318 {
6319 case CompareAnyLayer:
6320 case CompareClearLayer:
6321 case CompareOverlayLayer:
6322 default:
6323 {
6324 layers=CompareImageLayers(image,method,exception);
6325 break;
6326 }
6327 case MergeLayer:
6328 case FlattenLayer:
6329 case MosaicLayer:
6330 {
6331 layers=MergeImageLayers(image,method,exception);
6332 break;
6333 }
6334 case DisposeLayer:
6335 {
6336 layers=DisposeImages(image,exception);
6337 break;
6338 }
6339 case OptimizeImageLayer:
6340 {
6341 layers=OptimizeImageLayers(image,exception);
6342 break;
6343 }
6344 case OptimizePlusLayer:
6345 {
6346 layers=OptimizePlusImageLayers(image,exception);
6347 break;
6348 }
6349 case OptimizeTransLayer:
6350 {
6351 OptimizeImageTransparency(image,exception);
6352 InheritException(&(image->exception),exception);
6353 break;
6354 }
6355 case RemoveDupsLayer:
6356 {
6357 RemoveDuplicateLayers(&image,exception);
6358 InheritException(&(image->exception),exception);
6359 break;
6360 }
6361 case RemoveZeroLayer:
6362 {
6363 RemoveZeroDelayLayers(&image,exception);
6364 InheritException(&(image->exception),exception);
6365 break;
6366 }
6367 case OptimizeLayer:
6368 {
6369 QuantizeInfo
6370 *quantize_info;
6371
6372 /*
6373 General Purpose, GIF Animation Optimizer.
6374 */
6375 layers=CoalesceImages(image,exception);
6376 if (layers == (Image *) NULL)
6377 break;
6378 InheritException(&(layers->exception),exception);
6379 image=layers;
6380 layers=OptimizeImageLayers(image,exception);
6381 if (layers == (Image *) NULL)
6382 break;
6383 InheritException(&(layers->exception),exception);
6384 image=DestroyImageList(image);
6385 image=layers;
6386 layers=(Image *) NULL;
6387 OptimizeImageTransparency(image,exception);
6388 InheritException(&(image->exception),exception);
6389 quantize_info=AcquireQuantizeInfo(info->image_info);
6390 (void) RemapImages(quantize_info,image,(Image *) NULL);
6391 quantize_info=DestroyQuantizeInfo(quantize_info);
6392 break;
6393 }
6394 case CompositeLayer:
6395 {
6396 Image
6397 *source;
6398
6399 RectangleInfo
6400 geometry;
6401
6402 /*
6403 Split image sequence at the first 'NULL:' image.
6404 */
6405 source=image;
6406 while (source != (Image *) NULL)
6407 {
6408 source=GetNextImageInList(source);
6409 if ((source != (Image *) NULL) &&
6410 (LocaleCompare(source->magick,"NULL") == 0))
6411 break;
6412 }
6413 if (source != (Image *) NULL)
6414 {
6415 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
6416 (GetNextImageInList(source) == (Image *) NULL))
6417 source=(Image *) NULL;
6418 else
6419 {
6420 /*
6421 Separate the two lists, junk the null: image.
6422 */
6423 source=SplitImageList(source->previous);
6424 DeleteImageFromList(&source);
6425 }
6426 }
6427 if (source == (Image *) NULL)
6428 {
6429 (void) ThrowMagickException(exception,GetMagickModule(),
6430 OptionError,"MissingNullSeparator","layers Composite");
6431 break;
6432 }
6433 /*
6434 Adjust offset with gravity and virtual canvas.
6435 */
6436 SetGeometry(image,&geometry);
6437 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
6438 geometry.width=source->page.width != 0 ? source->page.width :
6439 source->columns;
6440 geometry.height=source->page.height != 0 ? source->page.height :
6441 source->rows;
6442 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
6443 image->columns,image->page.height != 0 ? image->page.height :
6444 image->rows,image->gravity,&geometry);
6445 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
6446 source=DestroyImageList(source);
6447 InheritException(&(image->exception),exception);
6448 break;
6449 }
6450 }
6451 if (layers != (Image *) NULL)
6452 {
6453 InheritException(&(layers->exception),exception);
6454 image=layers;
6455 }
6456 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
6457 goto PerlException;
6458 for ( ; image; image=image->next)
6459 {
6460 AddImageToRegistry(image);
6461 rv=newRV(sv);
6462 av_push(av,sv_bless(rv,hv));
6463 SvREFCNT_dec(sv);
6464 }
6465 exception=DestroyExceptionInfo(exception);
6466 ST(0)=av_reference;
6467 SvREFCNT_dec(perl_exception);
6468 XSRETURN(1);
6469
6470 PerlException:
6471 InheritPerlException(exception,perl_exception);
6472 exception=DestroyExceptionInfo(exception);
6473 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
6474 SvPOK_on(perl_exception);
6475 ST(0)=sv_2mortal(perl_exception);
6476 XSRETURN(1);
6477 }
6478
6479#
6480###############################################################################
6481# #
6482# #
6483# #
6484# M a g i c k T o M i m e #
6485# #
6486# #
6487# #
6488###############################################################################
6489#
6490#
6491SV *
6492MagickToMime(ref,name)
6493 Image::Magick ref=NO_INIT
6494 char *name
6495 ALIAS:
6496 magicktomime = 1
6497 CODE:
6498 {
6499 char
6500 *mime;
6501
6502 mime=MagickToMime(name);
6503 RETVAL=newSVpv(mime,0);
6504 mime=(char *) RelinquishMagickMemory(mime);
6505 }
6506 OUTPUT:
6507 RETVAL
6508
6509#
6510###############################################################################
6511# #
6512# #
6513# #
6514# M o g r i f y #
6515# #
6516# #
6517# #
6518###############################################################################
6519#
6520#
6521void
6522Mogrify(ref,...)
6523 Image::Magick ref=NO_INIT
6524 ALIAS:
6525 Comment = 1
6526 CommentImage = 2
6527 Label = 3
6528 LabelImage = 4
6529 AddNoise = 5
6530 AddNoiseImage = 6
6531 Colorize = 7
6532 ColorizeImage = 8
6533 Border = 9
6534 BorderImage = 10
6535 Blur = 11
6536 BlurImage = 12
6537 Chop = 13
6538 ChopImage = 14
6539 Crop = 15
6540 CropImage = 16
6541 Despeckle = 17
6542 DespeckleImage = 18
6543 Edge = 19
6544 EdgeImage = 20
6545 Emboss = 21
6546 EmbossImage = 22
6547 Enhance = 23
6548 EnhanceImage = 24
6549 Flip = 25
6550 FlipImage = 26
6551 Flop = 27
6552 FlopImage = 28
6553 Frame = 29
6554 FrameImage = 30
6555 Implode = 31
6556 ImplodeImage = 32
6557 Magnify = 33
6558 MagnifyImage = 34
6559 MedianFilter = 35
6560 MedianFilterImage = 36
6561 Minify = 37
6562 MinifyImage = 38
6563 OilPaint = 39
6564 OilPaintImage = 40
6565 ReduceNoise = 41
6566 ReduceNoiseImage = 42
6567 Roll = 43
6568 RollImage = 44
6569 Rotate = 45
6570 RotateImage = 46
6571 Sample = 47
6572 SampleImage = 48
6573 Scale = 49
6574 ScaleImage = 50
6575 Shade = 51
6576 ShadeImage = 52
6577 Sharpen = 53
6578 SharpenImage = 54
6579 Shear = 55
6580 ShearImage = 56
6581 Spread = 57
6582 SpreadImage = 58
6583 Swirl = 59
6584 SwirlImage = 60
6585 Resize = 61
6586 ResizeImage = 62
6587 Zoom = 63
6588 ZoomImage = 64
6589 Annotate = 65
6590 AnnotateImage = 66
6591 ColorFloodfill = 67
6592 ColorFloodfillImage= 68
6593 Composite = 69
6594 CompositeImage = 70
6595 Contrast = 71
6596 ContrastImage = 72
6597 CycleColormap = 73
6598 CycleColormapImage = 74
6599 Draw = 75
6600 DrawImage = 76
6601 Equalize = 77
6602 EqualizeImage = 78
6603 Gamma = 79
6604 GammaImage = 80
6605 Map = 81
6606 MapImage = 82
6607 MatteFloodfill = 83
6608 MatteFloodfillImage= 84
6609 Modulate = 85
6610 ModulateImage = 86
6611 Negate = 87
6612 NegateImage = 88
6613 Normalize = 89
6614 NormalizeImage = 90
6615 NumberColors = 91
6616 NumberColorsImage = 92
6617 Opaque = 93
6618 OpaqueImage = 94
6619 Quantize = 95
6620 QuantizeImage = 96
6621 Raise = 97
6622 RaiseImage = 98
6623 Segment = 99
6624 SegmentImage = 100
6625 Signature = 101
6626 SignatureImage = 102
6627 Solarize = 103
6628 SolarizeImage = 104
6629 Sync = 105
6630 SyncImage = 106
6631 Texture = 107
6632 TextureImage = 108
6633 Evaluate = 109
6634 EvaluateImage = 110
6635 Transparent = 111
6636 TransparentImage = 112
6637 Threshold = 113
6638 ThresholdImage = 114
6639 Charcoal = 115
6640 CharcoalImage = 116
6641 Trim = 117
6642 TrimImage = 118
6643 Wave = 119
6644 WaveImage = 120
6645 Separate = 121
6646 SeparateImage = 122
6647 Stereo = 125
6648 StereoImage = 126
6649 Stegano = 127
6650 SteganoImage = 128
6651 Deconstruct = 129
6652 DeconstructImage = 130
6653 GaussianBlur = 131
6654 GaussianBlurImage = 132
6655 Convolve = 133
6656 ConvolveImage = 134
6657 Profile = 135
6658 ProfileImage = 136
6659 UnsharpMask = 137
6660 UnsharpMaskImage = 138
6661 MotionBlur = 139
6662 MotionBlurImage = 140
6663 OrderedDither = 141
6664 OrderedDitherImage = 142
6665 Shave = 143
6666 ShaveImage = 144
6667 Level = 145
6668 LevelImage = 146
6669 Clip = 147
6670 ClipImage = 148
6671 AffineTransform = 149
6672 AffineTransformImage = 150
6673 Difference = 151
6674 DifferenceImage = 152
6675 AdaptiveThreshold = 153
6676 AdaptiveThresholdImage = 154
6677 Resample = 155
6678 ResampleImage = 156
6679 Describe = 157
6680 DescribeImage = 158
6681 BlackThreshold = 159
6682 BlackThresholdImage= 160
6683 WhiteThreshold = 161
6684 WhiteThresholdImage= 162
6685 RadialBlur = 163
6686 RadialBlurImage = 164
6687 Thumbnail = 165
6688 ThumbnailImage = 166
6689 Strip = 167
6690 StripImage = 168
6691 Tint = 169
6692 TintImage = 170
6693 Channel = 171
6694 ChannelImage = 172
6695 Splice = 173
6696 SpliceImage = 174
6697 Posterize = 175
6698 PosterizeImage = 176
6699 Shadow = 177
6700 ShadowImage = 178
6701 Identify = 179
6702 IdentifyImage = 180
6703 SepiaTone = 181
6704 SepiaToneImage = 182
6705 SigmoidalContrast = 183
6706 SigmoidalContrastImage = 184
6707 Extent = 185
6708 ExtentImage = 186
6709 Vignette = 187
6710 VignetteImage = 188
6711 ContrastStretch = 189
6712 ContrastStretchImage = 190
6713 Sans0 = 191
6714 Sans0Image = 192
6715 Sans1 = 193
6716 Sans1Image = 194
6717 AdaptiveSharpen = 195
6718 AdaptiveSharpenImage = 196
6719 Transpose = 197
6720 TransposeImage = 198
6721 Transverse = 199
6722 TransverseImage = 200
6723 AutoOrient = 201
6724 AutoOrientImage = 202
6725 AdaptiveBlur = 203
6726 AdaptiveBlurImage = 204
6727 Sketch = 205
6728 SketchImage = 206
6729 UniqueColors = 207
6730 UniqueColorsImage = 208
6731 AdaptiveResize = 209
6732 AdaptiveResizeImage= 210
6733 ClipMask = 211
6734 ClipMaskImage = 212
6735 LinearStretch = 213
6736 LinearStretchImage = 214
6737 RecolorImage = 215
6738 Recolor = 216
6739 Mask = 217
6740 MaskImage = 218
6741 Polaroid = 219
6742 PolaroidImage = 220
6743 FloodfillPaint = 221
6744 FloodfillPaintImage= 222
6745 Distort = 223
6746 DistortImage = 224
6747 Clut = 225
6748 ClutImage = 226
6749 LiquidRescale = 227
6750 LiquidRescaleImage = 228
6751 Encipher = 229
6752 EncipherImage = 230
6753 Decipher = 231
6754 DecipherImage = 232
6755 Deskew = 233
6756 DeskewImage = 234
6757 Remap = 235
6758 RemapImage = 236
6759 SparseColor = 237
6760 SparseColorImage = 238
6761 Function = 239
6762 FunctionImage = 240
6763 SelectiveBlur = 241
6764 SelectiveBlurImage = 242
6765 HaldClut = 243
6766 HaldClutImage = 244
6767 BlueShift = 245
6768 BlueShiftImage = 246
6769 ForwardFourierTransform = 247
6770 ForwardFourierTransformImage = 248
6771 InverseFourierTransform = 249
6772 InverseFourierTransformImage = 250
6773 ColorDecisionList = 251
6774 ColorDecisionListImage = 252
6775 AutoGamma = 253
6776 AutoGammaImage = 254
6777 AutoLevel = 255
6778 AutoLevelImage = 256
cristyee0f8d72009-09-19 00:58:29 +00006779 LevelColors = 257
6780 LevelColorsImage = 258
cristy1eb45dd2009-09-25 16:38:06 +00006781 Clamp = 259
6782 ClampImage = 260
cristy3ed852e2009-09-05 21:47:34 +00006783 MogrifyRegion = 666
6784 PPCODE:
6785 {
6786 AffineMatrix
6787 affine,
6788 current;
6789
6790 char
6791 attribute_flag[MaxArguments],
6792 message[MaxTextExtent];
6793
6794 ChannelType
6795 channel;
6796
6797 CompositeOperator
6798 compose;
6799
6800 const char
6801 *attribute,
6802 *value;
6803
6804 double
6805 angle;
6806
6807 ExceptionInfo
6808 *exception;
6809
6810 GeometryInfo
6811 geometry_info;
6812
6813 Image
6814 *image,
6815 *next,
6816 *region_image;
6817
6818 long
6819 base,
6820 j,
6821 number_images;
6822
6823 MagickBooleanType
6824 status;
6825
6826 MagickStatusType
6827 flags;
6828
6829 PixelPacket
6830 fill_color;
6831
6832 RectangleInfo
6833 geometry,
6834 region_info;
6835
6836 register long
6837 i;
6838
6839 struct PackageInfo
6840 *info;
6841
6842 struct Methods
6843 *rp;
6844
6845 SV
6846 *perl_exception,
6847 **pv,
6848 *reference,
6849 **reference_vector;
6850
6851 struct ArgumentList
6852 argument_list[MaxArguments];
6853
6854 exception=AcquireExceptionInfo();
6855 perl_exception=newSVpv("",0);
6856 reference_vector=NULL;
6857 region_image=NULL;
6858 number_images=0;
6859 base=2;
6860 if (sv_isobject(ST(0)) == 0)
6861 {
6862 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6863 PackageName);
6864 goto PerlException;
6865 }
6866 reference=SvRV(ST(0));
6867 region_info.width=0;
6868 region_info.height=0;
6869 region_info.x=0;
6870 region_info.y=0;
6871 region_image=(Image *) NULL;
6872 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
6873 if (ix && (ix != 666))
6874 {
6875 /*
6876 Called as Method(...)
6877 */
6878 ix=(ix+1)/2;
6879 rp=(&Methods[ix-1]);
6880 attribute=rp->name;
6881 }
6882 else
6883 {
6884 /*
6885 Called as Mogrify("Method",...)
6886 */
6887 attribute=(char *) SvPV(ST(1),na);
6888 if (ix)
6889 {
6890 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
6891 attribute=(char *) SvPV(ST(2),na);
6892 base++;
6893 }
6894 for (rp=Methods; ; rp++)
6895 {
6896 if (rp >= EndOf(Methods))
6897 {
6898 ThrowPerlException(exception,OptionError,
6899 "UnrecognizedPerlMagickMethod",attribute);
6900 goto PerlException;
6901 }
6902 if (strEQcase(attribute,rp->name))
6903 break;
6904 }
6905 ix=rp-Methods+1;
6906 base++;
6907 }
6908 if (image == (Image *) NULL)
6909 {
6910 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
6911 goto PerlException;
6912 }
6913 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
6914 Zero(&attribute_flag,NumberOf(attribute_flag),char);
6915 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
6916 {
6917 long
6918 longest;
6919
6920 Arguments
6921 *pp,
6922 *qq;
6923
6924 struct ArgumentList
6925 *al;
6926
6927 SV
6928 *sv;
6929
6930 longest=0;
6931 pp=(Arguments *) NULL;
6932 qq=rp->arguments;
6933 if (i == items)
6934 {
6935 pp=rp->arguments,
6936 sv=ST(i-1);
6937 }
6938 else
6939 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
6940 {
6941 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
6942 break;
6943 if (strEQcase(attribute,qq->method) > longest)
6944 {
6945 pp=qq;
6946 longest=strEQcase(attribute,qq->method);
6947 }
6948 }
6949 if (pp == (Arguments *) NULL)
6950 {
6951 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6952 attribute);
6953 goto continue_outer_loop;
6954 }
6955 al=(&argument_list[pp-rp->arguments]);
6956 switch (pp->type)
6957 {
6958 case ArrayReference:
6959 {
6960 if (SvTYPE(sv) != SVt_RV)
6961 {
6962 (void) FormatMagickString(message,MaxTextExtent,
6963 "invalid %.60s value",pp->method);
6964 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
6965 goto continue_outer_loop;
6966 }
6967 al->array_reference=SvRV(sv);
6968 break;
6969 }
6970 case RealReference:
6971 {
6972 al->real_reference=SvNV(sv);
6973 break;
6974 }
6975 case FileReference:
6976 {
6977 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
6978 break;
6979 }
6980 case ImageReference:
6981 {
6982 if (!sv_isobject(sv) ||
6983 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
6984 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
6985 {
6986 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6987 PackageName);
6988 goto PerlException;
6989 }
6990 break;
6991 }
6992 case IntegerReference:
6993 {
6994 al->long_reference=SvIV(sv);
6995 break;
6996 }
6997 case StringReference:
6998 {
6999 al->string_reference=(char *) SvPV(sv,al->length);
7000 if (sv_isobject(sv))
7001 al->image_reference=SetupList(aTHX_ SvRV(sv),
7002 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7003 break;
7004 }
7005 default:
7006 {
7007 /*
7008 Is a string; look up name.
7009 */
7010 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7011 {
7012 al->string_reference=(char *) SvPV(sv,al->length);
7013 al->long_reference=(-1);
7014 break;
7015 }
7016 al->long_reference=ParseMagickOption((MagickOption) pp->type,
7017 MagickFalse,SvPV(sv,na));
7018 if (pp->type == MagickChannelOptions)
7019 al->long_reference=ParseChannelOption(SvPV(sv,na));
7020 if ((al->long_reference < 0) && ((al->long_reference=SvIV(sv)) <= 0))
7021 {
7022 (void) FormatMagickString(message,MaxTextExtent,
7023 "invalid %.60s value",pp->method);
7024 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7025 goto continue_outer_loop;
7026 }
7027 break;
7028 }
7029 }
7030 attribute_flag[pp-rp->arguments]++;
7031 continue_outer_loop: ;
7032 }
7033 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7034 pv=reference_vector;
7035 SetGeometryInfo(&geometry_info);
7036 channel=DefaultChannels;
7037 for (next=image; next; next=next->next)
7038 {
7039 image=next;
7040 SetGeometry(image,&geometry);
7041 if ((region_info.width*region_info.height) != 0)
7042 {
7043 region_image=image;
7044 image=CropImage(image,&region_info,exception);
7045 }
7046 switch (ix)
7047 {
7048 default:
7049 {
7050 (void) FormatMagickString(message,MaxTextExtent,"%ld",(long) ix);
7051 ThrowPerlException(exception,OptionError,
7052 "UnrecognizedPerlMagickMethod",message);
7053 goto PerlException;
7054 }
7055 case 1: /* Comment */
7056 {
7057 if (attribute_flag[0] == 0)
7058 argument_list[0].string_reference=(char *) NULL;
7059 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7060 info ? info->image_info : (ImageInfo *) NULL,image,
7061 argument_list[0].string_reference));
7062 break;
7063 }
7064 case 2: /* Label */
7065 {
7066 if (attribute_flag[0] == 0)
7067 argument_list[0].string_reference=(char *) NULL;
7068 (void) SetImageProperty(image,"label",InterpretImageProperties(
7069 info ? info->image_info : (ImageInfo *) NULL,image,
7070 argument_list[0].string_reference));
7071 break;
7072 }
7073 case 3: /* AddNoise */
7074 {
7075 if (attribute_flag[0] == 0)
7076 argument_list[0].long_reference=UniformNoise;
7077 if (attribute_flag[1] != 0)
7078 channel=(ChannelType) argument_list[1].long_reference;
7079 image=AddNoiseImageChannel(image,channel,(NoiseType)
7080 argument_list[0].long_reference,exception);
7081 break;
7082 }
7083 case 4: /* Colorize */
7084 {
7085 PixelPacket
7086 target;
7087
7088 (void) GetOneVirtualPixel(image,0,0,&target,exception);
7089 if (attribute_flag[0] != 0)
7090 (void) QueryColorDatabase(argument_list[0].string_reference,&target,
7091 exception);
7092 if (attribute_flag[1] == 0)
7093 argument_list[1].string_reference="100%";
7094 image=ColorizeImage(image,argument_list[1].string_reference,target,
7095 exception);
7096 break;
7097 }
7098 case 5: /* Border */
7099 {
7100 geometry.width=0;
7101 geometry.height=0;
7102 if (attribute_flag[0] != 0)
7103 {
7104 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7105 &geometry,exception);
7106 if ((flags & HeightValue) == 0)
7107 geometry.height=geometry.width;
7108 }
7109 if (attribute_flag[1] != 0)
7110 geometry.width=argument_list[1].long_reference;
7111 if (attribute_flag[2] != 0)
7112 geometry.height=argument_list[2].long_reference;
7113 if (attribute_flag[3] != 0)
7114 QueryColorDatabase(argument_list[3].string_reference,
7115 &image->border_color,exception);
7116 if (attribute_flag[4] != 0)
7117 QueryColorDatabase(argument_list[4].string_reference,
7118 &image->border_color,exception);
7119 if (attribute_flag[5] != 0)
7120 QueryColorDatabase(argument_list[5].string_reference,
7121 &image->border_color,exception);
7122 if (attribute_flag[6] != 0)
7123 image->compose=(CompositeOperator) argument_list[6].long_reference;
7124 image=BorderImage(image,&geometry,exception);
7125 break;
7126 }
7127 case 6: /* Blur */
7128 {
7129 if (attribute_flag[0] != 0)
7130 {
7131 flags=ParseGeometry(argument_list[0].string_reference,
7132 &geometry_info);
7133 if ((flags & SigmaValue) == 0)
7134 geometry_info.sigma=1.0;
7135 }
7136 if (attribute_flag[1] != 0)
7137 geometry_info.rho=argument_list[1].real_reference;
7138 if (attribute_flag[2] != 0)
7139 geometry_info.sigma=argument_list[2].real_reference;
7140 if (attribute_flag[3] != 0)
7141 channel=(ChannelType) argument_list[3].long_reference;
7142 image=BlurImageChannel(image,channel,geometry_info.rho,
7143 geometry_info.sigma,exception);
7144 break;
7145 }
7146 case 7: /* Chop */
7147 {
7148 if (attribute_flag[0] != 0)
7149 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7150 &geometry,exception);
7151 if (attribute_flag[1] != 0)
7152 geometry.width=argument_list[1].long_reference;
7153 if (attribute_flag[2] != 0)
7154 geometry.height=argument_list[2].long_reference;
7155 if (attribute_flag[3] != 0)
7156 geometry.x=argument_list[3].long_reference;
7157 if (attribute_flag[4] != 0)
7158 geometry.y=argument_list[4].long_reference;
7159 image=ChopImage(image,&geometry,exception);
7160 break;
7161 }
7162 case 8: /* Crop */
7163 {
7164 if (attribute_flag[0] != 0)
7165 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7166 &geometry,exception);
7167 if (attribute_flag[1] != 0)
7168 geometry.width=argument_list[1].long_reference;
7169 if (attribute_flag[2] != 0)
7170 geometry.height=argument_list[2].long_reference;
7171 if (attribute_flag[3] != 0)
7172 geometry.x=argument_list[3].long_reference;
7173 if (attribute_flag[4] != 0)
7174 geometry.y=argument_list[4].long_reference;
7175 if (attribute_flag[5] != 0)
7176 image->fuzz=
7177 StringToDouble(argument_list[5].string_reference,QuantumRange);
7178 image=CropImage(image,&geometry,exception);
7179 break;
7180 }
7181 case 9: /* Despeckle */
7182 {
7183 image=DespeckleImage(image,exception);
7184 break;
7185 }
7186 case 10: /* Edge */
7187 {
7188 if (attribute_flag[0] != 0)
7189 geometry_info.rho=argument_list[0].real_reference;
7190 image=EdgeImage(image,geometry_info.rho,exception);
7191 break;
7192 }
7193 case 11: /* Emboss */
7194 {
7195 if (attribute_flag[0] != 0)
7196 {
7197 flags=ParseGeometry(argument_list[0].string_reference,
7198 &geometry_info);
7199 if ((flags & SigmaValue) == 0)
7200 geometry_info.sigma=1.0;
7201 }
7202 if (attribute_flag[1] != 0)
7203 geometry_info.rho=argument_list[1].real_reference;
7204 if (attribute_flag[2] != 0)
7205 geometry_info.sigma=argument_list[2].real_reference;
7206 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
7207 exception);
7208 break;
7209 }
7210 case 12: /* Enhance */
7211 {
7212 image=EnhanceImage(image,exception);
7213 break;
7214 }
7215 case 13: /* Flip */
7216 {
7217 image=FlipImage(image,exception);
7218 break;
7219 }
7220 case 14: /* Flop */
7221 {
7222 image=FlopImage(image,exception);
7223 break;
7224 }
7225 case 15: /* Frame */
7226 {
7227 FrameInfo
7228 frame_info;
7229
7230 if (attribute_flag[0] != 0)
7231 {
7232 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7233 &geometry,exception);
7234 if ((flags & HeightValue) == 0)
7235 geometry.height=geometry.width;
7236 frame_info.width=geometry.width;
7237 frame_info.height=geometry.height;
7238 frame_info.outer_bevel=geometry.x;
7239 frame_info.inner_bevel=geometry.y;
7240 }
7241 if (attribute_flag[1] != 0)
7242 frame_info.width=argument_list[1].long_reference;
7243 if (attribute_flag[2] != 0)
7244 frame_info.height=argument_list[2].long_reference;
7245 if (attribute_flag[3] != 0)
7246 frame_info.inner_bevel=argument_list[3].long_reference;
7247 if (attribute_flag[4] != 0)
7248 frame_info.outer_bevel=argument_list[4].long_reference;
7249 if (attribute_flag[5] != 0)
7250 QueryColorDatabase(argument_list[5].string_reference,&fill_color,
7251 exception);
7252 if (attribute_flag[6] != 0)
7253 QueryColorDatabase(argument_list[6].string_reference,&fill_color,
7254 exception);
7255 frame_info.x=(long) frame_info.width;
7256 frame_info.y=(long) frame_info.height;
7257 frame_info.width=image->columns+2*frame_info.x;
7258 frame_info.height=image->rows+2*frame_info.y;
7259 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
7260 image->matte_color=fill_color;
7261 if (attribute_flag[7] != 0)
7262 image->compose=(CompositeOperator) argument_list[7].long_reference;
7263 image=FrameImage(image,&frame_info,exception);
7264 break;
7265 }
7266 case 16: /* Implode */
7267 {
7268 if (attribute_flag[0] == 0)
7269 argument_list[0].real_reference=0.5;
7270 if (attribute_flag[1] != 0)
7271 image->interpolate=(InterpolatePixelMethod)
7272 argument_list[1].long_reference;
7273 image=ImplodeImage(image,argument_list[0].real_reference,
7274 exception);
7275 break;
7276 }
7277 case 17: /* Magnify */
7278 {
7279 image=MagnifyImage(image,exception);
7280 break;
7281 }
7282 case 18: /* MedianFilter */
7283 {
7284 if (attribute_flag[0] == 0)
7285 argument_list[0].real_reference=0.0;
7286 image=MedianFilterImage(image,argument_list[0].real_reference,
7287 exception);
7288 break;
7289 }
7290 case 19: /* Minify */
7291 {
7292 image=MinifyImage(image,exception);
7293 break;
7294 }
7295 case 20: /* OilPaint */
7296 {
7297 if (attribute_flag[0] == 0)
7298 argument_list[0].real_reference=0.0;
7299 image=OilPaintImage(image,argument_list[0].real_reference,
7300 exception);
7301 break;
7302 }
7303 case 21: /* ReduceNoise */
7304 {
7305 if (attribute_flag[0] == 0)
7306 argument_list[0].real_reference=0.0;
7307 image=ReduceNoiseImage(image,argument_list[0].real_reference,
7308 exception);
7309 break;
7310 }
7311 case 22: /* Roll */
7312 {
7313 if (attribute_flag[0] != 0)
7314 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7315 &geometry,exception);
7316 if (attribute_flag[1] != 0)
7317 geometry.x=argument_list[1].long_reference;
7318 if (attribute_flag[2] != 0)
7319 geometry.y=argument_list[2].long_reference;
7320 image=RollImage(image,geometry.x,geometry.y,exception);
7321 break;
7322 }
7323 case 23: /* Rotate */
7324 {
7325 if (attribute_flag[0] == 0)
7326 argument_list[0].real_reference=90.0;
7327 if (attribute_flag[1] != 0)
7328 QueryColorDatabase(argument_list[1].string_reference,
7329 &image->background_color,exception);
7330 if (attribute_flag[2] != 0)
7331 QueryColorDatabase(argument_list[2].string_reference,
7332 &image->background_color,exception);
7333 if (attribute_flag[3] != 0)
7334 QueryColorDatabase(argument_list[3].string_reference,
7335 &image->background_color,exception);
7336 image=RotateImage(image,argument_list[0].real_reference,exception);
7337 break;
7338 }
7339 case 24: /* Sample */
7340 {
7341 if (attribute_flag[0] != 0)
7342 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7343 &geometry,exception);
7344 if (attribute_flag[1] != 0)
7345 geometry.width=argument_list[1].long_reference;
7346 if (attribute_flag[2] != 0)
7347 geometry.height=argument_list[2].long_reference;
7348 image=SampleImage(image,geometry.width,geometry.height,exception);
7349 break;
7350 }
7351 case 25: /* Scale */
7352 {
7353 if (attribute_flag[0] != 0)
7354 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7355 &geometry,exception);
7356 if (attribute_flag[1] != 0)
7357 geometry.width=argument_list[1].long_reference;
7358 if (attribute_flag[2] != 0)
7359 geometry.height=argument_list[2].long_reference;
7360 image=ScaleImage(image,geometry.width,geometry.height,exception);
7361 break;
7362 }
7363 case 26: /* Shade */
7364 {
7365 if (attribute_flag[0] != 0)
7366 {
7367 flags=ParseGeometry(argument_list[0].string_reference,
7368 &geometry_info);
7369 if ((flags & SigmaValue) == 0)
7370 geometry_info.sigma=0.0;
7371 }
7372 if (attribute_flag[1] != 0)
7373 geometry_info.rho=argument_list[1].real_reference;
7374 if (attribute_flag[2] != 0)
7375 geometry_info.sigma=argument_list[2].real_reference;
7376 image=ShadeImage(image,
7377 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse,
7378 geometry_info.rho,geometry_info.sigma,exception);
7379 break;
7380 }
7381 case 27: /* Sharpen */
7382 {
7383 if (attribute_flag[0] != 0)
7384 {
7385 flags=ParseGeometry(argument_list[0].string_reference,
7386 &geometry_info);
7387 if ((flags & SigmaValue) == 0)
7388 geometry_info.sigma=1.0;
7389 }
7390 if (attribute_flag[1] != 0)
7391 geometry_info.rho=argument_list[1].real_reference;
7392 if (attribute_flag[2] != 0)
7393 geometry_info.sigma=argument_list[2].real_reference;
7394 if (attribute_flag[3] != 0)
7395 channel=(ChannelType) argument_list[3].long_reference;
7396 image=SharpenImageChannel(image,channel,geometry_info.rho,
7397 geometry_info.sigma,exception);
7398 break;
7399 }
7400 case 28: /* Shear */
7401 {
7402 if (attribute_flag[0] != 0)
7403 {
7404 flags=ParseGeometry(argument_list[0].string_reference,
7405 &geometry_info);
7406 if ((flags & SigmaValue) == 0)
7407 geometry_info.sigma=geometry_info.rho;
7408 }
7409 if (attribute_flag[1] != 0)
7410 geometry_info.rho=argument_list[1].real_reference;
7411 if (attribute_flag[2] != 0)
7412 geometry_info.sigma=argument_list[2].real_reference;
7413 if (attribute_flag[3] != 0)
7414 QueryColorDatabase(argument_list[3].string_reference,
7415 &image->background_color,exception);
7416 if (attribute_flag[4] != 0)
7417 QueryColorDatabase(argument_list[4].string_reference,
7418 &image->background_color,exception);
7419 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
7420 exception);
7421 break;
7422 }
7423 case 29: /* Spread */
7424 {
7425 if (attribute_flag[0] == 0)
7426 argument_list[0].real_reference=1.0;
7427 image=SpreadImage(image,argument_list[0].real_reference,exception);
7428 break;
7429 }
7430 case 30: /* Swirl */
7431 {
7432 if (attribute_flag[0] == 0)
7433 argument_list[0].real_reference=50.0;
7434 if (attribute_flag[1] != 0)
7435 image->interpolate=(InterpolatePixelMethod)
7436 argument_list[1].long_reference;
7437 image=SwirlImage(image,argument_list[0].real_reference,exception);
7438 break;
7439 }
7440 case 31: /* Resize */
7441 case 32: /* Zoom */
7442 {
7443 if (attribute_flag[0] != 0)
7444 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7445 &geometry,exception);
7446 if (attribute_flag[1] != 0)
7447 geometry.width=argument_list[1].long_reference;
7448 if (attribute_flag[2] != 0)
7449 geometry.height=argument_list[2].long_reference;
7450 if (attribute_flag[3] == 0)
7451 argument_list[3].long_reference=(long) UndefinedFilter;
7452 if (attribute_flag[4] != 0)
7453 SetImageArtifact(image,"filter:support",
7454 argument_list[4].string_reference);
7455 if (attribute_flag[5] == 0)
7456 argument_list[5].real_reference=1.0;
7457 image=ResizeImage(image,geometry.width,geometry.height,
7458 (FilterTypes) argument_list[3].long_reference,
7459 argument_list[5].real_reference,exception);
7460 break;
7461 }
7462 case 33: /* Annotate */
7463 {
7464 DrawInfo
7465 *draw_info;
7466
7467 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
7468 (DrawInfo *) NULL);
7469 if (attribute_flag[0] != 0)
7470 {
7471 char
7472 *text;
7473
7474 text=InterpretImageProperties(info ? info->image_info :
7475 (ImageInfo *) NULL,image,argument_list[0].string_reference);
7476 (void) CloneString(&draw_info->text,text);
7477 text=DestroyString(text);
7478 }
7479 if (attribute_flag[1] != 0)
7480 (void) CloneString(&draw_info->font,
7481 argument_list[1].string_reference);
7482 if (attribute_flag[2] != 0)
7483 draw_info->pointsize=argument_list[2].real_reference;
7484 if (attribute_flag[3] != 0)
7485 (void) CloneString(&draw_info->density,
7486 argument_list[3].string_reference);
7487 if (attribute_flag[4] != 0)
7488 (void) QueryColorDatabase(argument_list[4].string_reference,
7489 &draw_info->undercolor,exception);
7490 if (attribute_flag[5] != 0)
7491 {
7492 (void) QueryColorDatabase(argument_list[5].string_reference,
7493 &draw_info->stroke,exception);
7494 if (argument_list[5].image_reference != (Image *) NULL)
7495 draw_info->stroke_pattern=CloneImage(
7496 argument_list[5].image_reference,0,0,MagickTrue,exception);
7497 }
7498 if (attribute_flag[6] != 0)
7499 {
7500 (void) QueryColorDatabase(argument_list[6].string_reference,
7501 &draw_info->fill,exception);
7502 if (argument_list[6].image_reference != (Image *) NULL)
7503 draw_info->fill_pattern=CloneImage(
7504 argument_list[6].image_reference,0,0,MagickTrue,exception);
7505 }
7506 if (attribute_flag[7] != 0)
7507 {
7508 (void) CloneString(&draw_info->geometry,
7509 argument_list[7].string_reference);
7510 flags=ParsePageGeometry(image,argument_list[7].string_reference,
7511 &geometry,exception);
7512 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
7513 geometry_info.sigma=geometry_info.xi;
7514 }
7515 if (attribute_flag[8] != 0)
7516 (void) QueryColorDatabase(argument_list[8].string_reference,
7517 &draw_info->fill,exception);
7518 if (attribute_flag[11] != 0)
7519 draw_info->gravity=(GravityType) argument_list[11].long_reference;
7520 if (attribute_flag[25] != 0)
7521 {
7522 AV
7523 *av;
7524
7525 av=(AV *) argument_list[25].array_reference;
7526 if ((av_len(av) != 3) && (av_len(av) != 5))
7527 {
7528 ThrowPerlException(exception,OptionError,
7529 "affine matrix must have 4 or 6 elements",PackageName);
7530 goto PerlException;
7531 }
7532 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
7533 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
7534 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
7535 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
7536 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
7537 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
7538 {
7539 ThrowPerlException(exception,OptionError,
7540 "affine matrix is singular",PackageName);
7541 goto PerlException;
7542 }
7543 if (av_len(av) == 5)
7544 {
7545 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
7546 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
7547 }
7548 }
7549 for (j=12; j < 17; j++)
7550 {
7551 if (attribute_flag[j] == 0)
7552 continue;
7553 value=argument_list[j].string_reference;
7554 angle=argument_list[j].real_reference;
7555 current=draw_info->affine;
7556 GetAffineMatrix(&affine);
7557 switch (j)
7558 {
7559 case 12:
7560 {
7561 /*
7562 Translate.
7563 */
7564 flags=ParseGeometry(value,&geometry_info);
7565 affine.tx=geometry_info.xi;
7566 affine.ty=geometry_info.psi;
7567 if ((flags & PsiValue) == 0)
7568 affine.ty=affine.tx;
7569 break;
7570 }
7571 case 13:
7572 {
7573 /*
7574 Scale.
7575 */
7576 flags=ParseGeometry(value,&geometry_info);
7577 affine.sx=geometry_info.rho;
7578 affine.sy=geometry_info.sigma;
7579 if ((flags & SigmaValue) == 0)
7580 affine.sy=affine.sx;
7581 break;
7582 }
7583 case 14:
7584 {
7585 /*
7586 Rotate.
7587 */
7588 if (angle == 0.0)
7589 break;
7590 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
7591 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
7592 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
7593 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
7594 break;
7595 }
7596 case 15:
7597 {
7598 /*
7599 SkewX.
7600 */
7601 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
7602 break;
7603 }
7604 case 16:
7605 {
7606 /*
7607 SkewY.
7608 */
7609 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
7610 break;
7611 }
7612 }
7613 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
7614 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
7615 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
7616 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
7617 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
7618 current.tx;
7619 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
7620 current.ty;
7621 }
7622 if (attribute_flag[9] == 0)
7623 argument_list[9].real_reference=0.0;
7624 if (attribute_flag[10] == 0)
7625 argument_list[10].real_reference=0.0;
7626 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
7627 {
7628 char
7629 geometry[MaxTextExtent];
7630
7631 (void) FormatMagickString(geometry,MaxTextExtent,"%+f%+f",
7632 (double) argument_list[9].real_reference+draw_info->affine.tx,
7633 (double) argument_list[10].real_reference+draw_info->affine.ty);
7634 (void) CloneString(&draw_info->geometry,geometry);
7635 }
7636 if (attribute_flag[17] != 0)
7637 draw_info->stroke_width=argument_list[17].real_reference;
7638 if (attribute_flag[18] != 0)
7639 {
7640 draw_info->text_antialias=argument_list[18].long_reference != 0 ?
7641 MagickTrue : MagickFalse;
7642 draw_info->stroke_antialias=draw_info->text_antialias;
7643 }
7644 if (attribute_flag[19] != 0)
7645 (void) CloneString(&draw_info->family,
7646 argument_list[19].string_reference);
7647 if (attribute_flag[20] != 0)
7648 draw_info->style=(StyleType) argument_list[20].long_reference;
7649 if (attribute_flag[21] != 0)
7650 draw_info->stretch=(StretchType) argument_list[21].long_reference;
7651 if (attribute_flag[22] != 0)
7652 draw_info->weight=argument_list[22].long_reference;
7653 if (attribute_flag[23] != 0)
7654 draw_info->align=(AlignType) argument_list[23].long_reference;
7655 if (attribute_flag[24] != 0)
7656 (void) CloneString(&draw_info->encoding,
7657 argument_list[24].string_reference);
7658 if (attribute_flag[25] != 0)
7659 draw_info->fill_pattern=CloneImage(
7660 argument_list[25].image_reference,0,0,MagickTrue,exception);
7661 if (attribute_flag[26] != 0)
7662 draw_info->fill_pattern=CloneImage(
7663 argument_list[26].image_reference,0,0,MagickTrue,exception);
7664 if (attribute_flag[27] != 0)
7665 draw_info->stroke_pattern=CloneImage(
7666 argument_list[27].image_reference,0,0,MagickTrue,exception);
7667 if (attribute_flag[29] != 0)
7668 draw_info->kerning=argument_list[29].real_reference;
7669 if (attribute_flag[30] != 0)
cristyb32b90a2009-09-07 21:45:48 +00007670 draw_info->interline_spacing=argument_list[30].real_reference;
7671 if (attribute_flag[31] != 0)
7672 draw_info->interword_spacing=argument_list[31].real_reference;
cristy3ed852e2009-09-05 21:47:34 +00007673 (void) AnnotateImage(image,draw_info);
7674 draw_info=DestroyDrawInfo(draw_info);
7675 break;
7676 }
7677 case 34: /* ColorFloodfill */
7678 {
7679 DrawInfo
7680 *draw_info;
7681
7682 MagickBooleanType
7683 invert;
7684
7685 MagickPixelPacket
7686 target;
7687
7688 draw_info=CloneDrawInfo(info ? info->image_info :
7689 (ImageInfo *) NULL,(DrawInfo *) NULL);
7690 if (attribute_flag[0] != 0)
7691 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7692 &geometry,exception);
7693 if (attribute_flag[1] != 0)
7694 geometry.x=argument_list[1].long_reference;
7695 if (attribute_flag[2] != 0)
7696 geometry.y=argument_list[2].long_reference;
7697 if (attribute_flag[3] != 0)
7698 (void) QueryColorDatabase(argument_list[3].string_reference,
7699 &draw_info->fill,exception);
7700 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
7701 exception);
7702 invert=MagickFalse;
7703 if (attribute_flag[4] != 0)
7704 {
7705 QueryMagickColor(argument_list[4].string_reference,&target,
7706 exception);
7707 invert=MagickTrue;
7708 }
7709 if (attribute_flag[5] != 0)
7710 image->fuzz=StringToDouble(argument_list[5].string_reference,
7711 QuantumRange);
7712 if (attribute_flag[6] != 0)
7713 invert=(MagickBooleanType) argument_list[6].long_reference;
7714 (void) FloodfillPaintImage(image,DefaultChannels,draw_info,&target,
7715 geometry.x,geometry.y,invert);
7716 draw_info=DestroyDrawInfo(draw_info);
7717 break;
7718 }
7719 case 35: /* Composite */
7720 {
7721 char
7722 composite_geometry[MaxTextExtent];
7723
7724 Image
7725 *composite_image,
7726 *rotate_image;
7727
7728 compose=OverCompositeOp;
7729 if (attribute_flag[0] != 0)
7730 composite_image=argument_list[0].image_reference;
7731 else
7732 {
7733 ThrowPerlException(exception,OptionError,
7734 "CompositeImageRequired",PackageName);
7735 goto PerlException;
7736 }
7737 /*
7738 Parameter Handling used for BOTH normal and tiled composition.
7739 */
7740 if (attribute_flag[1] != 0) /* compose */
7741 compose=(CompositeOperator) argument_list[1].long_reference;
7742 if (attribute_flag[6] != 0) /* opacity */
7743 {
7744 if (compose != DissolveCompositeOp)
7745 (void) SetImageOpacity(composite_image,(Quantum) (QuantumRange-
7746 StringToDouble(argument_list[6].string_reference,
7747 QuantumRange)));
7748 else
7749 {
7750 double
7751 opacity;
7752
7753 long
7754 y;
7755
7756 MagickBooleanType
7757 sync;
7758
7759 register long
7760 x;
7761
7762 register PixelPacket
7763 *q;
7764
7765 CacheView
7766 *composite_view;
7767
7768 /*
7769 Handle dissolve composite operator (patch by
7770 Kevin A. McGrail).
7771 */
7772 (void) CloneString(&image->geometry,
7773 argument_list[6].string_reference);
7774 opacity=(Quantum) (QuantumRange-StringToDouble(
7775 argument_list[6].string_reference,QuantumRange));
7776 if (composite_image->matte != MagickTrue)
7777 (void) SetImageOpacity(composite_image,OpaqueOpacity);
cristy33f41432009-10-09 01:25:24 +00007778 composite_view=AcquireCacheView(composite_image);
cristy3ed852e2009-09-05 21:47:34 +00007779 for (y=0; y < (long) composite_image->rows ; y++)
7780 {
cristy33f41432009-10-09 01:25:24 +00007781 q=GetCacheViewAuthenticPixels(composite_view,0,y,(long)
7782 composite_image->columns,1,exception);
cristy3ed852e2009-09-05 21:47:34 +00007783 for (x=0; x < (long) composite_image->columns; x++)
7784 {
7785 if (q->opacity == OpaqueOpacity)
7786 q->opacity=RoundToQuantum(opacity);
7787 q++;
7788 }
7789 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
7790 if (sync == MagickFalse)
7791 break;
7792 }
cristy33f41432009-10-09 01:25:24 +00007793 composite_view=DestroyCacheView(composite_view);
cristy3ed852e2009-09-05 21:47:34 +00007794 }
7795 }
7796 if (attribute_flag[9] != 0) /* "color=>" */
7797 QueryColorDatabase(argument_list[9].string_reference,
7798 &composite_image->background_color,exception);
7799 if (attribute_flag[12] != 0) /* "interpolate=>" */
7800 image->interpolate=(InterpolatePixelMethod)
7801 argument_list[12].long_reference;
7802 if (attribute_flag[13] != 0) /* "args=>" */
7803 (void) SetImageArtifact(composite_image,"compose:args",
7804 argument_list[13].string_reference);
7805 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
7806 (void) SetImageArtifact(composite_image,"compose:args",
7807 argument_list[14].string_reference);
7808 /*
7809 Tiling Composition (with orthogonal rotate).
7810 */
7811 rotate_image=(Image *) NULL;
7812 if (attribute_flag[8] != 0) /* "rotate=>" */
7813 {
7814 /*
7815 Rotate image.
7816 */
7817 rotate_image=RotateImage(composite_image,
7818 argument_list[8].real_reference,exception);
7819 if (rotate_image == (Image *) NULL)
7820 break;
7821 }
7822 if (attribute_flag[7] && argument_list[7].long_reference) /* tile */
7823 {
7824 long
7825 x,
7826 y;
7827
7828 /*
7829 Tile the composite image.
7830 */
7831 if (attribute_flag[8] != 0) /* "tile=>" */
7832 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
7833 "false");
7834 else
7835 (void) SetImageArtifact(composite_image,
7836 "compose:outside-overlay","false");
7837 for (y=0; y < (long) image->rows; y+=composite_image->rows)
7838 for (x=0; x < (long) image->columns; x+=composite_image->columns)
7839 {
7840 if (attribute_flag[8] != 0) /* rotate */
7841 (void) CompositeImage(image,compose,rotate_image,x,y);
7842 else
7843 (void) CompositeImage(image,compose,composite_image,x,y);
7844 }
7845 if (attribute_flag[8] != 0) /* rotate */
7846 rotate_image=DestroyImage(rotate_image);
7847 break;
7848 }
7849 /*
7850 Parameter Handling used used ONLY for normal composition.
7851 */
7852 if (attribute_flag[5] != 0) /* gravity */
7853 image->gravity=(GravityType) argument_list[5].long_reference;
7854 if (attribute_flag[2] != 0) /* geometry offset */
7855 {
7856 SetGeometry(image,&geometry);
7857 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
7858 &geometry);
7859 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
7860 &geometry);
7861 }
7862 if (attribute_flag[3] != 0) /* x offset */
7863 geometry.x=argument_list[3].long_reference;
7864 if (attribute_flag[4] != 0) /* y offset */
7865 geometry.y=argument_list[4].long_reference;
7866 if (attribute_flag[10] != 0) /* mask */
7867 {
7868 if ((image->compose == DisplaceCompositeOp) ||
7869 (image->compose == DistortCompositeOp))
7870 {
7871 /*
7872 Merge Y displacement into X displacement image.
7873 */
7874 composite_image=CloneImage(composite_image,0,0,MagickTrue,
7875 &image->exception);
7876 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
7877 argument_list[10].image_reference,0,0);
7878 }
7879 else
7880 {
7881 /*
7882 Set a blending mask for the composition.
7883 */
7884 image->mask=CloneImage(argument_list[10].image_reference,0,0,
7885 MagickTrue,&image->exception);
7886 (void) NegateImage(image->mask,MagickFalse);
7887 }
7888 }
7889 if (attribute_flag[11] != 0) /* channel */
7890 channel=(ChannelType) argument_list[11].long_reference;
7891 /*
7892 Composite two images (normal composition).
7893 */
7894 (void) FormatMagickString(composite_geometry,MaxTextExtent,
7895 "%lux%lu%+ld%+ld",composite_image->columns,composite_image->rows,
7896 geometry.x,geometry.y);
7897 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
7898 exception);
7899 if (attribute_flag[8] == 0) /* no rotate */
7900 CompositeImageChannel(image,channel,compose,composite_image,
7901 geometry.x,geometry.y);
7902 else
7903 {
7904 /*
7905 Position adjust rotated image then composite.
7906 */
7907 geometry.x-=(long) (rotate_image->columns-
7908 composite_image->columns)/2;
7909 geometry.y-=(long) (rotate_image->rows-composite_image->rows)/2;
7910 CompositeImageChannel(image,channel,compose,rotate_image,
7911 geometry.x,geometry.y);
7912 rotate_image=DestroyImage(rotate_image);
7913 }
7914 if (attribute_flag[10] != 0) /* mask */
7915 {
7916 if ((image->compose == DisplaceCompositeOp) ||
7917 (image->compose == DistortCompositeOp))
7918 composite_image=DestroyImage(composite_image);
7919 else
7920 image->mask=DestroyImage(image->mask);
7921 }
7922 break;
7923 }
7924 case 36: /* Contrast */
7925 {
7926 if (attribute_flag[0] == 0)
7927 argument_list[0].long_reference=0;
7928 (void) ContrastImage(image,argument_list[0].long_reference != 0 ?
7929 MagickTrue : MagickFalse);
7930 break;
7931 }
7932 case 37: /* CycleColormap */
7933 {
7934 if (attribute_flag[0] == 0)
7935 argument_list[0].long_reference=6;
7936 (void) CycleColormapImage(image,argument_list[0].long_reference);
7937 break;
7938 }
7939 case 38: /* Draw */
7940 {
7941 DrawInfo
7942 *draw_info;
7943
7944 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
7945 (DrawInfo *) NULL);
7946 (void) CloneString(&draw_info->primitive,"point");
7947 if (attribute_flag[0] != 0)
7948 {
7949 if (argument_list[0].long_reference < 0)
7950 (void) CloneString(&draw_info->primitive,
7951 argument_list[0].string_reference);
7952 else
7953 (void) CloneString(&draw_info->primitive,MagickOptionToMnemonic(
7954 MagickPrimitiveOptions,argument_list[0].long_reference));
7955 }
7956 if (attribute_flag[1] != 0)
7957 {
7958 if (LocaleCompare(draw_info->primitive,"path") == 0)
7959 {
7960 (void) ConcatenateString(&draw_info->primitive," '");
7961 ConcatenateString(&draw_info->primitive,
7962 argument_list[1].string_reference);
7963 (void) ConcatenateString(&draw_info->primitive,"'");
7964 }
7965 else
7966 {
7967 (void) ConcatenateString(&draw_info->primitive," ");
7968 ConcatenateString(&draw_info->primitive,
7969 argument_list[1].string_reference);
7970 }
7971 }
7972 if (attribute_flag[2] != 0)
7973 {
7974 (void) ConcatenateString(&draw_info->primitive," ");
7975 (void) ConcatenateString(&draw_info->primitive,
7976 MagickOptionToMnemonic(MagickMethodOptions,
7977 argument_list[2].long_reference));
7978 }
7979 if (attribute_flag[3] != 0)
7980 {
7981 (void) QueryColorDatabase(argument_list[3].string_reference,
7982 &draw_info->stroke,exception);
7983 if (argument_list[3].image_reference != (Image *) NULL)
7984 draw_info->stroke_pattern=CloneImage(
7985 argument_list[3].image_reference,0,0,MagickTrue,exception);
7986 }
7987 if (attribute_flag[4] != 0)
7988 {
7989 (void) QueryColorDatabase(argument_list[4].string_reference,
7990 &draw_info->fill,exception);
7991 if (argument_list[4].image_reference != (Image *) NULL)
7992 draw_info->fill_pattern=CloneImage(
7993 argument_list[4].image_reference,0,0,MagickTrue,exception);
7994 }
7995 if (attribute_flag[5] != 0)
7996 draw_info->stroke_width=argument_list[5].real_reference;
7997 if (attribute_flag[6] != 0)
7998 (void) CloneString(&draw_info->font,
7999 argument_list[6].string_reference);
8000 if (attribute_flag[7] != 0)
8001 (void) QueryColorDatabase(argument_list[7].string_reference,
8002 &draw_info->border_color,exception);
8003 if (attribute_flag[8] != 0)
8004 draw_info->affine.tx=argument_list[8].real_reference;
8005 if (attribute_flag[9] != 0)
8006 draw_info->affine.ty=argument_list[9].real_reference;
8007 if (attribute_flag[20] != 0)
8008 {
8009 AV
8010 *av;
8011
8012 av=(AV *) argument_list[20].array_reference;
8013 if ((av_len(av) != 3) && (av_len(av) != 5))
8014 {
8015 ThrowPerlException(exception,OptionError,
8016 "affine matrix must have 4 or 6 elements",PackageName);
8017 goto PerlException;
8018 }
8019 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8020 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8021 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8022 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8023 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8024 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8025 {
8026 ThrowPerlException(exception,OptionError,
8027 "affine matrix is singular",PackageName);
8028 goto PerlException;
8029 }
8030 if (av_len(av) == 5)
8031 {
8032 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8033 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8034 }
8035 }
8036 for (j=10; j < 15; j++)
8037 {
8038 if (attribute_flag[j] == 0)
8039 continue;
8040 value=argument_list[j].string_reference;
8041 angle=argument_list[j].real_reference;
8042 current=draw_info->affine;
8043 GetAffineMatrix(&affine);
8044 switch (j)
8045 {
8046 case 10:
8047 {
8048 /*
8049 Translate.
8050 */
8051 flags=ParseGeometry(value,&geometry_info);
8052 affine.tx=geometry_info.xi;
8053 affine.ty=geometry_info.psi;
8054 if ((flags & PsiValue) == 0)
8055 affine.ty=affine.tx;
8056 break;
8057 }
8058 case 11:
8059 {
8060 /*
8061 Scale.
8062 */
8063 flags=ParseGeometry(value,&geometry_info);
8064 affine.sx=geometry_info.rho;
8065 affine.sy=geometry_info.sigma;
8066 if ((flags & SigmaValue) == 0)
8067 affine.sy=affine.sx;
8068 break;
8069 }
8070 case 12:
8071 {
8072 /*
8073 Rotate.
8074 */
8075 if (angle == 0.0)
8076 break;
8077 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8078 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8079 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8080 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8081 break;
8082 }
8083 case 13:
8084 {
8085 /*
8086 SkewX.
8087 */
8088 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8089 break;
8090 }
8091 case 14:
8092 {
8093 /*
8094 SkewY.
8095 */
8096 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8097 break;
8098 }
8099 }
8100 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8101 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8102 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8103 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8104 draw_info->affine.tx=
8105 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8106 draw_info->affine.ty=
8107 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8108 }
8109 if (attribute_flag[15] != 0)
8110 draw_info->fill_pattern=CloneImage(
8111 argument_list[15].image_reference,0,0,MagickTrue,exception);
8112 if (attribute_flag[16] != 0)
8113 draw_info->pointsize=argument_list[16].real_reference;
8114 if (attribute_flag[17] != 0)
8115 {
8116 draw_info->stroke_antialias=argument_list[17].long_reference != 0
8117 ? MagickTrue : MagickFalse;
8118 draw_info->text_antialias=draw_info->stroke_antialias;
8119 }
8120 if (attribute_flag[18] != 0)
8121 (void) CloneString(&draw_info->density,
8122 argument_list[18].string_reference);
8123 if (attribute_flag[19] != 0)
8124 draw_info->stroke_width=argument_list[19].real_reference;
8125 if (attribute_flag[21] != 0)
8126 draw_info->dash_offset=argument_list[21].real_reference;
8127 if (attribute_flag[22] != 0)
8128 {
8129 AV
8130 *av;
8131
8132 av=(AV *) argument_list[22].array_reference;
8133 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
8134 av_len(av)+1UL,sizeof(draw_info->dash_pattern));
8135 if (draw_info->dash_pattern != (double *) NULL)
8136 {
8137 for (i=0; i <= av_len(av); i++)
8138 draw_info->dash_pattern[i]=(double)
8139 SvNV(*(av_fetch(av,i,0)));
8140 draw_info->dash_pattern[i]=0.0;
8141 }
8142 }
8143 if (attribute_flag[23] != 0)
8144 image->interpolate=(InterpolatePixelMethod)
8145 argument_list[23].long_reference;
8146 if ((attribute_flag[24] != 0) &&
8147 (draw_info->fill_pattern != (Image *) NULL))
8148 flags=ParsePageGeometry(draw_info->fill_pattern,
8149 argument_list[24].string_reference,
8150 &draw_info->fill_pattern->tile_offset,exception);
8151 if (attribute_flag[25] != 0)
8152 {
8153 (void) ConcatenateString(&draw_info->primitive," '");
8154 (void) ConcatenateString(&draw_info->primitive,
8155 argument_list[25].string_reference);
8156 (void) ConcatenateString(&draw_info->primitive,"'");
8157 }
8158 if (attribute_flag[26] != 0)
8159 draw_info->fill_pattern=CloneImage(
8160 argument_list[26].image_reference,0,0,MagickTrue,exception);
8161 if (attribute_flag[27] != 0)
8162 draw_info->stroke_pattern=CloneImage(
8163 argument_list[27].image_reference,0,0,MagickTrue,exception);
8164 if (attribute_flag[28] != 0)
8165 (void) CloneString(&draw_info->primitive,
8166 argument_list[28].string_reference);
8167 if (attribute_flag[29] != 0)
8168 draw_info->kerning=argument_list[29].real_reference;
8169 if (attribute_flag[30] != 0)
cristyb32b90a2009-09-07 21:45:48 +00008170 draw_info->interline_spacing=argument_list[30].real_reference;
8171 if (attribute_flag[31] != 0)
8172 draw_info->interword_spacing=argument_list[31].real_reference;
cristy3ed852e2009-09-05 21:47:34 +00008173 DrawImage(image,draw_info);
8174 draw_info=DestroyDrawInfo(draw_info);
8175 break;
8176 }
8177 case 39: /* Equalize */
8178 {
8179 if (attribute_flag[0] != 0)
8180 channel=(ChannelType) argument_list[0].long_reference;
8181 EqualizeImageChannel(image,channel);
8182 break;
8183 }
8184 case 40: /* Gamma */
8185 {
8186 if (attribute_flag[1] != 0)
8187 channel=(ChannelType) argument_list[1].long_reference;
8188 if (attribute_flag[2] == 0)
8189 argument_list[2].real_reference=1.0;
8190 if (attribute_flag[3] == 0)
8191 argument_list[3].real_reference=1.0;
8192 if (attribute_flag[4] == 0)
8193 argument_list[4].real_reference=1.0;
8194 if (attribute_flag[0] == 0)
8195 {
8196 (void) FormatMagickString(message,MaxTextExtent,"%g,%g,%g",
8197 (double) argument_list[2].real_reference,
8198 (double) argument_list[3].real_reference,
8199 (double) argument_list[4].real_reference);
8200 argument_list[0].string_reference=message;
8201 }
8202 if (strchr(argument_list[0].string_reference,',') != (char *) NULL)
8203 (void) GammaImage(image,argument_list[0].string_reference);
8204 else
8205 (void) GammaImageChannel(image,channel,
8206 atof(argument_list[0].string_reference));
8207 break;
8208 }
8209 case 41: /* Map */
8210 {
8211 QuantizeInfo
8212 *quantize_info;
8213
8214 if (attribute_flag[0] == 0)
8215 {
8216 ThrowPerlException(exception,OptionError,"MapImageRequired",
8217 PackageName);
8218 goto PerlException;
8219 }
8220 quantize_info=AcquireQuantizeInfo(info->image_info);
8221 if (attribute_flag[1] != 0)
8222 quantize_info->dither=(MagickBooleanType)
8223 argument_list[1].long_reference;
8224 (void) RemapImages(quantize_info,image,
8225 argument_list[0].image_reference);
8226 quantize_info=DestroyQuantizeInfo(quantize_info);
8227 break;
8228 }
8229 case 42: /* MatteFloodfill */
8230 {
8231 DrawInfo
8232 *draw_info;
8233
8234 MagickBooleanType
8235 invert;
8236
8237 MagickPixelPacket
8238 target;
8239
8240 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8241 (DrawInfo *) NULL);
8242 if (attribute_flag[0] != 0)
8243 if (attribute_flag[0] != 0)
8244 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8245 &geometry,exception);
8246 if (attribute_flag[1] != 0)
8247 geometry.x=argument_list[1].long_reference;
8248 if (attribute_flag[2] != 0)
8249 geometry.y=argument_list[2].long_reference;
8250 if (image->matte == MagickFalse)
8251 (void) SetImageOpacity(image,OpaqueOpacity);
8252 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
8253 exception);
8254 if (attribute_flag[4] != 0)
8255 QueryMagickColor(argument_list[4].string_reference,&target,
8256 exception);
8257 if (attribute_flag[3] != 0)
8258 target.opacity=StringToDouble(argument_list[3].string_reference,
8259 QuantumRange);
8260 if (attribute_flag[5] != 0)
8261 image->fuzz=StringToDouble(argument_list[5].string_reference,
8262 QuantumRange);
8263 invert=MagickFalse;
8264 if (attribute_flag[6] != 0)
8265 invert=(MagickBooleanType) argument_list[6].long_reference;
8266 (void) FloodfillPaintImage(image,OpacityChannel,draw_info,&target,
8267 geometry.x,geometry.y,invert);
8268 draw_info=DestroyDrawInfo(draw_info);
8269 break;
8270 }
8271 case 43: /* Modulate */
8272 {
8273 char
8274 modulate[MaxTextExtent];
8275
8276 ColorspaceType
8277 colorspace;
8278
8279 colorspace=image->colorspace;
8280 geometry_info.rho=100.0;
8281 geometry_info.sigma=100.0;
8282 geometry_info.xi=100.0;
8283 if (attribute_flag[0] != 0)
8284 (void)ParseGeometry(argument_list[0].string_reference,
8285 &geometry_info);
8286 if (attribute_flag[1] != 0)
8287 geometry_info.xi=argument_list[1].real_reference;
8288 if (attribute_flag[2] != 0)
8289 geometry_info.sigma=argument_list[2].real_reference;
8290 if (attribute_flag[3] != 0)
8291 {
8292 (void) SetImageColorspace(image,HWBColorspace);
8293 geometry_info.sigma=argument_list[3].real_reference;
8294 }
8295 if (attribute_flag[4] != 0)
8296 geometry_info.rho=argument_list[4].real_reference;
8297 if (attribute_flag[5] != 0)
8298 {
8299 (void) SetImageColorspace(image,HSLColorspace);
8300 geometry_info.sigma=argument_list[5].real_reference;
8301 }
8302 if (attribute_flag[6] != 0)
8303 {
8304 (void) SetImageColorspace(image,HWBColorspace);
8305 geometry_info.rho=argument_list[6].real_reference;
8306 }
8307 (void) FormatMagickString(modulate,MaxTextExtent,"%g,%g,%g",
8308 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
8309 (void) ModulateImage(image,modulate);
8310 (void) SetImageColorspace(image,colorspace);
8311 break;
8312 }
8313 case 44: /* Negate */
8314 {
8315 if (attribute_flag[0] == 0)
8316 argument_list[0].long_reference=0;
8317 if (attribute_flag[1] != 0)
8318 channel=(ChannelType) argument_list[1].long_reference;
8319 (void) NegateImageChannel(image,channel,
8320 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse);
8321 break;
8322 }
8323 case 45: /* Normalize */
8324 {
8325 if (attribute_flag[0] != 0)
8326 channel=(ChannelType) argument_list[0].long_reference;
8327 NormalizeImageChannel(image,channel);
8328 break;
8329 }
8330 case 46: /* NumberColors */
8331 break;
8332 case 47: /* Opaque */
8333 {
8334 MagickBooleanType
8335 invert;
8336
8337 MagickPixelPacket
8338 fill_color,
8339 target;
8340
8341 (void) QueryMagickColor("none",&target,exception);
8342 (void) QueryMagickColor("none",&fill_color,exception);
8343 if (attribute_flag[0] != 0)
8344 (void) QueryMagickColor(argument_list[0].string_reference,
8345 &target,exception);
8346 if (attribute_flag[1] != 0)
8347 (void) QueryMagickColor(argument_list[1].string_reference,
8348 &fill_color,exception);
8349 if (attribute_flag[2] != 0)
8350 image->fuzz=StringToDouble(argument_list[2].string_reference,
8351 QuantumRange);
8352 if (attribute_flag[3] != 0)
8353 channel=(ChannelType) argument_list[3].long_reference;
8354 invert=MagickFalse;
8355 if (attribute_flag[4] != 0)
8356 invert=(MagickBooleanType) argument_list[4].long_reference;
8357 (void) OpaquePaintImageChannel(image,channel,&target,&fill_color,
8358 invert);
8359 break;
8360 }
8361 case 48: /* Quantize */
8362 {
8363 QuantizeInfo
8364 *quantize_info;
8365
8366 quantize_info=AcquireQuantizeInfo(info->image_info);
8367 if (attribute_flag[0] != 0)
8368 quantize_info->number_colors=(unsigned long)
8369 argument_list[0].long_reference;
8370 if (attribute_flag[1] != 0)
8371 quantize_info->tree_depth=(unsigned long)
8372 argument_list[1].long_reference;
8373 if (attribute_flag[2] != 0)
8374 quantize_info->colorspace=(ColorspaceType)
8375 argument_list[2].long_reference;
8376 if (attribute_flag[3] != 0)
8377 quantize_info->dither=argument_list[3].long_reference != 0 ?
8378 MagickTrue : MagickFalse;
8379 if (attribute_flag[4] != 0)
8380 quantize_info->measure_error=
8381 argument_list[4].long_reference != 0 ? MagickTrue : MagickFalse;
8382 if (attribute_flag[5] != 0)
8383 (void) QueryColorDatabase(argument_list[5].string_reference,
8384 &image->transparent_color,exception);
8385 if (attribute_flag[5] && argument_list[5].long_reference)
8386 {
8387 (void) QuantizeImages(quantize_info,image);
8388 goto PerlException;
8389 }
8390 if (attribute_flag[6] != 0)
8391 quantize_info->dither_method=(DitherMethod)
8392 argument_list[6].long_reference;
8393 if ((image->storage_class == DirectClass) ||
8394 (image->colors > quantize_info->number_colors) ||
8395 (quantize_info->colorspace == GRAYColorspace))
8396 (void) QuantizeImage(quantize_info,image);
8397 else
8398 CompressImageColormap(image);
8399 quantize_info=DestroyQuantizeInfo(quantize_info);
8400 break;
8401 }
8402 case 49: /* Raise */
8403 {
8404 if (attribute_flag[0] != 0)
8405 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8406 &geometry,exception);
8407 if (attribute_flag[1] != 0)
8408 geometry.width=argument_list[1].long_reference;
8409 if (attribute_flag[2] != 0)
8410 geometry.height=argument_list[2].long_reference;
8411 if (attribute_flag[3] == 0)
8412 argument_list[3].long_reference=1;
8413 (void) RaiseImage(image,&geometry,argument_list[3].long_reference !=
8414 0 ? MagickTrue : MagickFalse);
8415 break;
8416 }
8417 case 50: /* Segment */
8418 {
8419 ColorspaceType
8420 colorspace;
8421
8422 double
8423 cluster_threshold,
8424 smoothing_threshold;
8425
8426 MagickBooleanType
8427 verbose;
8428
8429 cluster_threshold=1.0;
8430 smoothing_threshold=1.5;
8431 colorspace=RGBColorspace;
8432 verbose=MagickFalse;
8433 if (attribute_flag[0] != 0)
8434 {
8435 flags=ParseGeometry(argument_list[0].string_reference,
8436 &geometry_info);
8437 cluster_threshold=geometry_info.rho;
8438 if (flags & SigmaValue)
8439 smoothing_threshold=geometry_info.sigma;
8440 }
8441 if (attribute_flag[1] != 0)
8442 cluster_threshold=argument_list[1].real_reference;
8443 if (attribute_flag[2] != 0)
8444 smoothing_threshold=argument_list[2].real_reference;
8445 if (attribute_flag[3] != 0)
8446 colorspace=(ColorspaceType) argument_list[3].long_reference;
8447 if (attribute_flag[4] != 0)
8448 verbose=argument_list[4].long_reference != 0 ?
8449 MagickTrue : MagickFalse;
8450 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
8451 smoothing_threshold);
8452 break;
8453 }
8454 case 51: /* Signature */
8455 {
8456 (void) SignatureImage(image);
8457 break;
8458 }
8459 case 52: /* Solarize */
8460 {
8461 geometry_info.rho=QuantumRange/2.0;
8462 if (attribute_flag[0] != 0)
8463 flags=ParseGeometry(argument_list[0].string_reference,
8464 &geometry_info);
8465 if (attribute_flag[1] != 0)
8466 geometry_info.rho=StringToDouble(argument_list[1].string_reference,
8467 QuantumRange);
8468 (void) SolarizeImage(image,geometry_info.rho);
8469 break;
8470 }
8471 case 53: /* Sync */
8472 {
8473 (void) SyncImage(image);
8474 break;
8475 }
8476 case 54: /* Texture */
8477 {
8478 if (attribute_flag[0] == 0)
8479 break;
8480 TextureImage(image,argument_list[0].image_reference);
8481 break;
8482 }
8483 case 55: /* Evalute */
8484 {
8485 MagickEvaluateOperator
8486 op;
8487
8488 op=SetEvaluateOperator;
8489 if (attribute_flag[0] == MagickFalse)
8490 argument_list[0].real_reference=0.0;
8491 if (attribute_flag[1] != MagickFalse)
8492 op=(MagickEvaluateOperator) argument_list[1].long_reference;
8493 if (attribute_flag[2] != MagickFalse)
8494 channel=(ChannelType) argument_list[2].long_reference;
8495 (void) EvaluateImageChannel(image,channel,op,
8496 argument_list[0].real_reference,exception);
8497 break;
8498 }
8499 case 56: /* Transparent */
8500 {
8501 double
8502 opacity;
8503
8504 MagickBooleanType
8505 invert;
8506
8507 MagickPixelPacket
8508 target;
8509
8510 (void) QueryMagickColor("none",&target,exception);
8511 if (attribute_flag[0] != 0)
8512 (void) QueryMagickColor(argument_list[0].string_reference,&target,
8513 exception);
8514 opacity=TransparentOpacity;
8515 if (attribute_flag[1] != 0)
8516 opacity=StringToDouble(argument_list[1].string_reference,
8517 QuantumRange);
8518 if (attribute_flag[2] != 0)
8519 image->fuzz=StringToDouble(argument_list[2].string_reference,
8520 QuantumRange);
8521 if (attribute_flag[3] == 0)
8522 argument_list[3].long_reference=0;
8523 invert=MagickFalse;
8524 if (attribute_flag[3] != 0)
8525 invert=(MagickBooleanType) argument_list[3].long_reference;
8526 (void) TransparentPaintImage(image,&target,RoundToQuantum(opacity),
8527 invert);
8528 break;
8529 }
8530 case 57: /* Threshold */
8531 {
8532 double
8533 threshold;
8534
8535 if (attribute_flag[0] == 0)
8536 argument_list[0].string_reference="50%";
8537 if (attribute_flag[1] != 0)
8538 channel=(ChannelType) argument_list[1].long_reference;
8539 threshold=StringToDouble(argument_list[0].string_reference,
8540 QuantumRange);
8541 (void) BilevelImageChannel(image,channel,threshold);
8542 break;
8543 }
8544 case 58: /* Charcoal */
8545 {
8546 if (attribute_flag[0] != 0)
8547 {
8548 flags=ParseGeometry(argument_list[0].string_reference,
8549 &geometry_info);
8550 if ((flags & SigmaValue) == 0)
8551 geometry_info.sigma=1.0;
8552 }
8553 if (attribute_flag[1] != 0)
8554 geometry_info.rho=argument_list[1].real_reference;
8555 if (attribute_flag[2] != 0)
8556 geometry_info.sigma=argument_list[2].real_reference;
8557 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
8558 exception);
8559 break;
8560 }
8561 case 59: /* Trim */
8562 {
8563 if (attribute_flag[0] != 0)
8564 image->fuzz=StringToDouble(argument_list[0].string_reference,
8565 QuantumRange);
8566 image=TrimImage(image,exception);
8567 break;
8568 }
8569 case 60: /* Wave */
8570 {
8571 if (attribute_flag[0] != 0)
8572 {
8573 flags=ParseGeometry(argument_list[0].string_reference,
8574 &geometry_info);
8575 if ((flags & SigmaValue) == 0)
8576 geometry_info.sigma=1.0;
8577 }
8578 if (attribute_flag[1] != 0)
8579 geometry_info.rho=argument_list[1].real_reference;
8580 if (attribute_flag[2] != 0)
8581 geometry_info.sigma=argument_list[2].real_reference;
8582 if (attribute_flag[3] != 0)
8583 image->interpolate=(InterpolatePixelMethod)
8584 argument_list[3].long_reference;
8585 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
8586 exception);
8587 break;
8588 }
8589 case 61: /* Separate */
8590 {
8591 if (attribute_flag[0] != 0)
8592 channel=(ChannelType) argument_list[0].long_reference;
8593 (void) SeparateImageChannel(image,channel);
8594 break;
8595 }
8596 case 63: /* Stereo */
8597 {
8598 if (attribute_flag[0] == 0)
8599 {
8600 ThrowPerlException(exception,OptionError,"StereoImageRequired",
8601 PackageName);
8602 goto PerlException;
8603 }
8604 if (attribute_flag[1] != 0)
8605 geometry.x=argument_list[1].long_reference;
8606 if (attribute_flag[2] != 0)
8607 geometry.y=argument_list[2].long_reference;
8608 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
8609 geometry.x,geometry.y,exception);
8610 break;
8611 }
8612 case 64: /* Stegano */
8613 {
8614 if (attribute_flag[0] == 0)
8615 {
8616 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
8617 PackageName);
8618 goto PerlException;
8619 }
8620 if (attribute_flag[1] == 0)
8621 argument_list[1].long_reference=0;
8622 image->offset=argument_list[1].long_reference;
8623 image=SteganoImage(image,argument_list[0].image_reference,exception);
8624 break;
8625 }
8626 case 65: /* Deconstruct */
8627 {
8628 image=DeconstructImages(image,exception);
8629 break;
8630 }
8631 case 66: /* GaussianBlur */
8632 {
8633 if (attribute_flag[0] != 0)
8634 {
8635 flags=ParseGeometry(argument_list[0].string_reference,
8636 &geometry_info);
8637 if ((flags & SigmaValue) == 0)
8638 geometry_info.sigma=1.0;
8639 }
8640 if (attribute_flag[1] != 0)
8641 geometry_info.rho=argument_list[1].real_reference;
8642 if (attribute_flag[2] != 0)
8643 geometry_info.sigma=argument_list[2].real_reference;
8644 if (attribute_flag[3] != 0)
8645 channel=(ChannelType) argument_list[3].long_reference;
8646 image=GaussianBlurImageChannel(image,channel,geometry_info.rho,
8647 geometry_info.sigma,exception);
8648 break;
8649 }
8650 case 67: /* Convolve */
8651 {
8652 AV
8653 *av;
8654
8655 double
8656 *kernel;
8657
8658 unsigned long
8659 order;
8660
8661 if (attribute_flag[0] == 0)
8662 break;
8663 if (attribute_flag[1] != 0)
8664 channel=(ChannelType) argument_list[1].long_reference;
8665 if (attribute_flag[2] != 0)
8666 image->bias=StringToDouble(argument_list[2].string_reference,
8667 QuantumRange);
8668 av=(AV *) argument_list[0].array_reference;
8669 order=(unsigned long) sqrt(av_len(av)+1);
8670 kernel=(double *) AcquireQuantumMemory(order,order*sizeof(*kernel));
8671 if (kernel == (double *) NULL)
8672 {
8673 ThrowPerlException(exception,ResourceLimitFatalError,
8674 "MemoryAllocationFailed",PackageName);
8675 goto PerlException;
8676 }
8677 for (j=0; (j < (long) (order*order)) && (j < (av_len(av)+1)); j++)
8678 kernel[j]=(double) SvNV(*(av_fetch(av,j,0)));
8679 for ( ; j < (long) (order*order); j++)
8680 kernel[j]=0.0;
8681 image=ConvolveImageChannel(image,channel,order,kernel,exception);
8682 kernel=(double *) RelinquishMagickMemory(kernel);
8683 break;
8684 }
8685 case 68: /* Profile */
8686 {
8687 const char
8688 *name;
8689
8690 Image
8691 *profile_image;
8692
8693 ImageInfo
8694 *profile_info;
8695
8696 StringInfo
8697 *profile;
8698
8699 name="*";
8700 if (attribute_flag[0] != 0)
8701 name=argument_list[0].string_reference;
8702 if (attribute_flag[2] != 0)
8703 image->rendering_intent=(RenderingIntent)
8704 argument_list[2].long_reference;
8705 if (attribute_flag[3] != 0)
8706 image->black_point_compensation=
8707 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse;
8708 if (attribute_flag[1] != 0)
8709 {
8710 if (argument_list[1].length == 0)
8711 {
8712 /*
8713 Remove a profile from the image.
8714 */
8715 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
8716 MagickTrue);
8717 break;
8718 }
8719 /*
8720 Associate user supplied profile with the image.
8721 */
8722 profile=AcquireStringInfo(argument_list[1].length);
8723 SetStringInfoDatum(profile,(const unsigned char *)
8724 argument_list[1].string_reference);
8725 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
8726 (unsigned long) GetStringInfoLength(profile),MagickFalse);
8727 profile=DestroyStringInfo(profile);
8728 break;
8729 }
8730 /*
8731 Associate a profile with the image.
8732 */
8733 profile_info=
8734 CloneImageInfo(info ? info->image_info : (ImageInfo *) NULL);
8735 (void) CopyMagickString(profile_info->filename,name,MaxTextExtent);
8736 profile_image=ReadImages(profile_info,&image->exception);
8737 if (profile_image == (Image *) NULL)
8738 break;
8739 ResetImageProfileIterator(profile_image);
8740 name=GetNextImageProfile(profile_image);
8741 while (name != (const char *) NULL)
8742 {
8743 const StringInfo
8744 *profile;
8745
8746 profile=GetImageProfile(profile_image,name);
8747 if (profile != (const StringInfo *) NULL)
8748 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
8749 (unsigned long) GetStringInfoLength(profile),MagickFalse);
8750 name=GetNextImageProfile(profile_image);
8751 }
8752 profile_image=DestroyImage(profile_image);
8753 profile_info=DestroyImageInfo(profile_info);
8754 break;
8755 }
8756 case 69: /* UnsharpMask */
8757 {
8758 if (attribute_flag[0] != 0)
8759 {
8760 flags=ParseGeometry(argument_list[0].string_reference,
8761 &geometry_info);
8762 if ((flags & SigmaValue) == 0)
8763 geometry_info.sigma=1.0;
8764 if ((flags & XiValue) == 0)
8765 geometry_info.xi=1.0;
8766 if ((flags & PsiValue) == 0)
8767 geometry_info.psi=0.5;
8768 }
8769 if (attribute_flag[1] != 0)
8770 geometry_info.rho=argument_list[1].real_reference;
8771 if (attribute_flag[2] != 0)
8772 geometry_info.sigma=argument_list[2].real_reference;
8773 if (attribute_flag[3] != 0)
8774 geometry_info.xi=argument_list[3].real_reference;
8775 if (attribute_flag[4] != 0)
8776 geometry_info.psi=argument_list[4].real_reference;
8777 if (attribute_flag[5] != 0)
8778 channel=(ChannelType) argument_list[5].long_reference;
8779 image=UnsharpMaskImageChannel(image,channel,geometry_info.rho,
8780 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
8781 break;
8782 }
8783 case 70: /* MotionBlur */
8784 {
8785 if (attribute_flag[0] != 0)
8786 {
8787 flags=ParseGeometry(argument_list[0].string_reference,
8788 &geometry_info);
8789 if ((flags & SigmaValue) == 0)
8790 geometry_info.sigma=1.0;
8791 if ((flags & XiValue) == 0)
8792 geometry_info.xi=1.0;
8793 }
8794 if (attribute_flag[1] != 0)
8795 geometry_info.rho=argument_list[1].real_reference;
8796 if (attribute_flag[2] != 0)
8797 geometry_info.sigma=argument_list[2].real_reference;
8798 if (attribute_flag[3] != 0)
8799 geometry_info.xi=argument_list[3].real_reference;
8800 if (attribute_flag[4] != 0)
8801 channel=(ChannelType) argument_list[4].long_reference;
8802 image=MotionBlurImageChannel(image,channel,geometry_info.rho,geometry_info.sigma,
8803 geometry_info.xi,exception);
8804 break;
8805 }
8806 case 71: /* OrderedDither */
8807 {
8808 if (attribute_flag[0] == 0)
8809 argument_list[0].string_reference="o8x8";
8810 if (attribute_flag[1] != 0)
8811 channel=(ChannelType) argument_list[1].long_reference;
8812 (void) OrderedPosterizeImageChannel(image,channel,
8813 argument_list[0].string_reference,exception);
8814 break;
8815 }
8816 case 72: /* Shave */
8817 {
8818 if (attribute_flag[0] != 0)
8819 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8820 &geometry,exception);
8821 if (attribute_flag[1] != 0)
8822 geometry.width=argument_list[1].long_reference;
8823 if (attribute_flag[2] != 0)
8824 geometry.height=argument_list[2].long_reference;
8825 image=ShaveImage(image,&geometry,exception);
8826 break;
8827 }
8828 case 73: /* Level */
8829 {
8830 double
8831 black_point,
8832 gamma,
8833 white_point;
8834
8835 black_point=0.0;
8836 white_point=(MagickRealType) image->columns*image->rows;
8837 gamma=1.0;
8838 if (attribute_flag[0] != 0)
8839 {
8840 flags=ParseGeometry(argument_list[0].string_reference,
8841 &geometry_info);
8842 black_point=geometry_info.rho;
8843 if ((flags & SigmaValue) != 0)
8844 white_point=geometry_info.sigma;
8845 if ((flags & XiValue) != 0)
8846 gamma=geometry_info.xi;
8847 if ((flags & PercentValue) != 0)
8848 {
8849 black_point*=(double) (QuantumRange/100.0);
8850 white_point*=(double) (QuantumRange/100.0);
8851 }
8852 if ((flags & SigmaValue) == 0)
8853 white_point=(double) QuantumRange-black_point;
8854 }
8855 if (attribute_flag[1] != 0)
8856 black_point=argument_list[1].real_reference;
8857 if (attribute_flag[2] != 0)
8858 white_point=argument_list[2].real_reference;
8859 if (attribute_flag[3] != 0)
8860 gamma=argument_list[3].real_reference;
8861 if (attribute_flag[4] != 0)
8862 channel=(ChannelType) argument_list[4].long_reference;
8863 if (attribute_flag[5] != 0)
8864 {
8865 argument_list[0].real_reference=argument_list[5].real_reference;
8866 attribute_flag[0]=attribute_flag[5];
8867 }
8868 (void) LevelImageChannel(image,channel,black_point,white_point,gamma);
8869 break;
8870 }
8871 case 74: /* Clip */
8872 {
8873 if (attribute_flag[0] == 0)
8874 argument_list[0].string_reference="#1";
8875 if (attribute_flag[1] == 0)
8876 argument_list[1].long_reference=MagickTrue;
8877 (void) ClipImagePath(image,argument_list[0].string_reference,
8878 argument_list[1].long_reference != 0 ? MagickTrue : MagickFalse);
8879 break;
8880 }
8881 case 75: /* AffineTransform */
8882 {
8883 DrawInfo
8884 *draw_info;
8885
8886 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8887 (DrawInfo *) NULL);
8888 if (attribute_flag[0] != 0)
8889 {
8890 AV
8891 *av;
8892
8893 av=(AV *) argument_list[0].array_reference;
8894 if ((av_len(av) != 3) && (av_len(av) != 5))
8895 {
8896 ThrowPerlException(exception,OptionError,
8897 "affine matrix must have 4 or 6 elements",PackageName);
8898 goto PerlException;
8899 }
8900 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8901 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8902 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8903 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8904 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8905 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8906 {
8907 ThrowPerlException(exception,OptionError,
8908 "affine matrix is singular",PackageName);
8909 goto PerlException;
8910 }
8911 if (av_len(av) == 5)
8912 {
8913 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8914 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8915 }
8916 }
8917 for (j=1; j < 6; j++)
8918 {
8919 if (attribute_flag[j] == 0)
8920 continue;
8921 value=argument_list[j].string_reference;
8922 angle=argument_list[j].real_reference;
8923 current=draw_info->affine;
8924 GetAffineMatrix(&affine);
8925 switch (j)
8926 {
8927 case 1:
8928 {
8929 /*
8930 Translate.
8931 */
8932 flags=ParseGeometry(value,&geometry_info);
8933 affine.tx=geometry_info.xi;
8934 affine.ty=geometry_info.psi;
8935 if ((flags & PsiValue) == 0)
8936 affine.ty=affine.tx;
8937 break;
8938 }
8939 case 2:
8940 {
8941 /*
8942 Scale.
8943 */
8944 flags=ParseGeometry(value,&geometry_info);
8945 affine.sx=geometry_info.rho;
8946 affine.sy=geometry_info.sigma;
8947 if ((flags & SigmaValue) == 0)
8948 affine.sy=affine.sx;
8949 break;
8950 }
8951 case 3:
8952 {
8953 /*
8954 Rotate.
8955 */
8956 if (angle == 0.0)
8957 break;
8958 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8959 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8960 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8961 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8962 break;
8963 }
8964 case 4:
8965 {
8966 /*
8967 SkewX.
8968 */
8969 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8970 break;
8971 }
8972 case 5:
8973 {
8974 /*
8975 SkewY.
8976 */
8977 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8978 break;
8979 }
8980 }
8981 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8982 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8983 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8984 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8985 draw_info->affine.tx=
8986 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8987 draw_info->affine.ty=
8988 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8989 }
8990 if (attribute_flag[6] != 0)
8991 image->interpolate=(InterpolatePixelMethod)
8992 argument_list[6].long_reference;
8993 if (attribute_flag[7] != 0)
8994 QueryColorDatabase(argument_list[7].string_reference,
8995 &image->background_color,exception);
8996 image=AffineTransformImage(image,&draw_info->affine,exception);
8997 draw_info=DestroyDrawInfo(draw_info);
8998 break;
8999 }
9000 case 76: /* Difference */
9001 {
9002 if (attribute_flag[0] == 0)
9003 {
9004 ThrowPerlException(exception,OptionError,
9005 "ReferenceImageRequired",PackageName);
9006 goto PerlException;
9007 }
9008 if (attribute_flag[1] != 0)
9009 image->fuzz=StringToDouble(argument_list[1].string_reference,
9010 QuantumRange);
9011 (void) IsImagesEqual(image,argument_list[0].image_reference);
9012 break;
9013 }
9014 case 77: /* AdaptiveThreshold */
9015 {
9016 if (attribute_flag[0] != 0)
9017 {
9018 flags=ParseGeometry(argument_list[0].string_reference,
9019 &geometry_info);
9020 if ((flags & PercentValue) != 0)
9021 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9022 }
9023 if (attribute_flag[1] != 0)
9024 geometry_info.rho=argument_list[1].long_reference;
9025 if (attribute_flag[2] != 0)
9026 geometry_info.sigma=argument_list[2].long_reference;
9027 if (attribute_flag[3] != 0)
9028 geometry_info.xi=argument_list[3].long_reference;;
9029 image=AdaptiveThresholdImage(image,(unsigned long) geometry_info.rho,
9030 (unsigned long) geometry_info.sigma,(long) geometry_info.xi,
9031 exception);
9032 break;
9033 }
9034 case 78: /* Resample */
9035 {
9036 unsigned long
9037 height,
9038 width;
9039
9040 if (attribute_flag[0] != 0)
9041 {
9042 flags=ParseGeometry(argument_list[0].string_reference,
9043 &geometry_info);
9044 if ((flags & SigmaValue) == 0)
9045 geometry_info.sigma=geometry_info.rho;
9046 }
9047 if (attribute_flag[1] != 0)
9048 geometry_info.rho=argument_list[1].real_reference;
9049 if (attribute_flag[2] != 0)
9050 geometry_info.sigma=argument_list[2].real_reference;
9051 if (attribute_flag[3] == 0)
9052 argument_list[3].long_reference=(long) UndefinedFilter;
9053 if (attribute_flag[4] == 0)
9054 SetImageArtifact(image,"filter:support",
9055 argument_list[4].string_reference);
9056 if (attribute_flag[5] != 0)
9057 argument_list[5].real_reference=1.0;
9058 width=(unsigned long) (geometry_info.rho*image->columns/
9059 (image->x_resolution == 0.0 ? 72.0 : image->x_resolution)+0.5);
9060 height=(unsigned long) (geometry_info.sigma*image->rows/
9061 (image->y_resolution == 0.0 ? 72.0 : image->y_resolution)+0.5);
9062 image=ResizeImage(image,width,height,(FilterTypes)
9063 argument_list[3].long_reference,argument_list[5].real_reference,
9064 exception);
9065 if (image != (Image *) NULL)
9066 {
9067 image->x_resolution=geometry_info.rho;
9068 image->y_resolution=geometry_info.sigma;
9069 }
9070 break;
9071 }
9072 case 79: /* Describe */
9073 {
9074 if (attribute_flag[0] == 0)
9075 argument_list[0].file_reference=(FILE *) NULL;
9076 (void) IdentifyImage(image,argument_list[0].file_reference,
9077 MagickTrue);
9078 break;
9079 }
9080 case 80: /* BlackThreshold */
9081 {
9082 if (attribute_flag[0] == 0)
9083 argument_list[0].string_reference="50%";
9084 if (attribute_flag[2] != 0)
9085 channel=(ChannelType) argument_list[2].long_reference;
9086 BlackThresholdImageChannel(image,channel,
9087 argument_list[0].string_reference,exception);
9088 break;
9089 }
9090 case 81: /* WhiteThreshold */
9091 {
9092 if (attribute_flag[0] == 0)
9093 argument_list[0].string_reference="50%";
9094 if (attribute_flag[2] != 0)
9095 channel=(ChannelType) argument_list[2].long_reference;
9096 WhiteThresholdImageChannel(image,channel,
9097 argument_list[0].string_reference,exception);
9098 break;
9099 }
9100 case 82: /* RadialBlur */
9101 {
9102 if (attribute_flag[0] != 0)
9103 {
9104 flags=ParseGeometry(argument_list[0].string_reference,
9105 &geometry_info);
9106 if ((flags & SigmaValue) == 0)
9107 geometry_info.sigma=1.0;
9108 }
9109 if (attribute_flag[1] != 0)
9110 geometry_info.rho=argument_list[1].real_reference;
9111 if (attribute_flag[2] != 0)
9112 channel=(ChannelType) argument_list[2].long_reference;
9113 image=RadialBlurImageChannel(image,channel,geometry_info.rho,
9114 exception);
9115 break;
9116 }
9117 case 83: /* Thumbnail */
9118 {
9119 if (attribute_flag[0] != 0)
9120 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9121 &geometry,exception);
9122 if (attribute_flag[1] != 0)
9123 geometry.width=argument_list[1].long_reference;
9124 if (attribute_flag[2] != 0)
9125 geometry.height=argument_list[2].long_reference;
9126 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
9127 break;
9128 }
9129 case 84: /* Strip */
9130 {
9131 (void) StripImage(image);
9132 break;
9133 }
9134 case 85: /* Tint */
9135 {
9136 PixelPacket
9137 target;
9138
9139 (void) GetOneVirtualPixel(image,0,0,&target,exception);
9140 if (attribute_flag[0] != 0)
9141 (void) QueryColorDatabase(argument_list[0].string_reference,&target,
9142 exception);
9143 if (attribute_flag[1] == 0)
9144 argument_list[1].string_reference="100";
9145 image=TintImage(image,argument_list[1].string_reference,target,
9146 exception);
9147 break;
9148 }
9149 case 86: /* Channel */
9150 {
9151 if (attribute_flag[0] != 0)
9152 channel=(ChannelType) argument_list[0].long_reference;
9153 (void) SeparateImageChannel(image,channel);
9154 break;
9155 }
9156 case 87: /* Splice */
9157 {
9158 if (attribute_flag[0] != 0)
9159 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
9160 &geometry,exception);
9161 if (attribute_flag[1] != 0)
9162 geometry.width=argument_list[1].long_reference;
9163 if (attribute_flag[2] != 0)
9164 geometry.height=argument_list[2].long_reference;
9165 if (attribute_flag[3] != 0)
9166 geometry.x=argument_list[3].long_reference;
9167 if (attribute_flag[4] != 0)
9168 geometry.y=argument_list[4].long_reference;
9169 if (attribute_flag[5] != 0)
9170 image->fuzz=StringToDouble(argument_list[5].string_reference,
9171 QuantumRange);
9172 if (attribute_flag[6] != 0)
9173 (void) QueryColorDatabase(argument_list[6].string_reference,
9174 &image->background_color,exception);
9175 if (attribute_flag[7] != 0)
9176 image->gravity=(GravityType) argument_list[7].long_reference;
9177 image=SpliceImage(image,&geometry,exception);
9178 break;
9179 }
9180 case 88: /* Posterize */
9181 {
9182 if (attribute_flag[0] == 0)
9183 argument_list[0].long_reference=3;
9184 if (attribute_flag[1] == 0)
9185 argument_list[1].long_reference=0;
9186 (void) PosterizeImage(image,argument_list[0].long_reference,
9187 argument_list[1].long_reference ? MagickTrue : MagickFalse);
9188 break;
9189 }
9190 case 89: /* Shadow */
9191 {
9192 if (attribute_flag[0] != 0)
9193 {
9194 flags=ParseGeometry(argument_list[0].string_reference,
9195 &geometry_info);
9196 if ((flags & SigmaValue) == 0)
9197 geometry_info.sigma=1.0;
9198 if ((flags & XiValue) == 0)
9199 geometry_info.xi=4.0;
9200 if ((flags & PsiValue) == 0)
9201 geometry_info.psi=4.0;
9202 }
9203 if (attribute_flag[1] != 0)
9204 geometry_info.rho=argument_list[1].real_reference;
9205 if (attribute_flag[2] != 0)
9206 geometry_info.sigma=argument_list[2].real_reference;
9207 if (attribute_flag[3] != 0)
9208 geometry_info.xi=argument_list[3].long_reference;
9209 if (attribute_flag[4] != 0)
9210 geometry_info.psi=argument_list[4].long_reference;
9211 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
9212 (long) (geometry_info.xi+0.5),(long) (geometry_info.psi+0.5),
9213 exception);
9214 break;
9215 }
9216 case 90: /* Identify */
9217 {
9218 if (attribute_flag[0] == 0)
9219 argument_list[0].file_reference=(FILE *) NULL;
9220 (void) IdentifyImage(image,argument_list[0].file_reference,
9221 MagickTrue);
9222 break;
9223 }
9224 case 91: /* SepiaTone */
9225 {
9226 if (attribute_flag[0] == 0)
9227 argument_list[0].real_reference=80.0*QuantumRange/100.0;
9228 image=SepiaToneImage(image,argument_list[0].real_reference,
9229 exception);
9230 break;
9231 }
9232 case 92: /* SigmoidalContrast */
9233 {
9234 MagickBooleanType
9235 sharpen;
9236
9237 if (attribute_flag[0] != 0)
9238 {
9239 flags=ParseGeometry(argument_list[0].string_reference,
9240 &geometry_info);
9241 if ((flags & SigmaValue) == 0)
9242 geometry_info.sigma=QuantumRange/2.0;
9243 if ((flags & PercentValue) != 0)
9244 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
9245 }
9246 if (attribute_flag[1] != 0)
9247 geometry_info.rho=argument_list[1].real_reference;
9248 if (attribute_flag[2] != 0)
9249 geometry_info.sigma=argument_list[2].real_reference;
9250 if (attribute_flag[3] != 0)
9251 channel=(ChannelType) argument_list[3].long_reference;
9252 sharpen=MagickTrue;
9253 if (attribute_flag[4] != 0)
9254 sharpen=argument_list[4].long_reference != 0 ? MagickTrue :
9255 MagickFalse;
9256 (void) SigmoidalContrastImageChannel(image,channel,sharpen,
9257 geometry_info.rho,geometry_info.sigma);
9258 break;
9259 }
9260 case 93: /* Extent */
9261 {
9262 GravityType
9263 gravity;
9264
9265 gravity=image->gravity;
9266 if (attribute_flag[7] != 0)
9267 gravity=(GravityType) argument_list[7].long_reference;
9268 if (attribute_flag[0] != 0)
9269 {
9270 SetGeometry(image,&geometry);
9271 (void) ParseAbsoluteGeometry(argument_list[0].string_reference,
9272 &geometry);
9273 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
9274 &geometry);
9275 }
9276 if (attribute_flag[1] != 0)
9277 geometry.width=argument_list[1].long_reference;
9278 if (attribute_flag[2] != 0)
9279 geometry.height=argument_list[2].long_reference;
9280 if (attribute_flag[3] != 0)
9281 geometry.x=argument_list[3].long_reference;
9282 if (attribute_flag[4] != 0)
9283 geometry.y=argument_list[4].long_reference;
9284 if (attribute_flag[5] != 0)
9285 image->fuzz=StringToDouble(argument_list[5].string_reference,
9286 QuantumRange);
9287 if (attribute_flag[6] != 0)
9288 (void) QueryColorDatabase(argument_list[6].string_reference,
9289 &image->background_color,exception);
9290 GravityAdjustGeometry(image->columns,image->rows,gravity,&geometry);
9291 image=ExtentImage(image,&geometry,exception);
9292 break;
9293 }
9294 case 94: /* Vignette */
9295 {
9296 if (attribute_flag[0] != 0)
9297 {
9298 flags=ParseGeometry(argument_list[0].string_reference,
9299 &geometry_info);
9300 if ((flags & SigmaValue) == 0)
9301 geometry_info.sigma=1.0;
9302 if ((flags & XiValue) == 0)
9303 geometry_info.xi=0.1*image->columns;
9304 if ((flags & PsiValue) == 0)
9305 geometry_info.psi=0.1*image->rows;
9306 }
9307 if (attribute_flag[1] != 0)
9308 geometry_info.rho=argument_list[1].real_reference;
9309 if (attribute_flag[2] != 0)
9310 geometry_info.sigma=argument_list[2].real_reference;
9311 if (attribute_flag[3] != 0)
9312 geometry_info.xi=argument_list[3].long_reference;
9313 if (attribute_flag[4] != 0)
9314 geometry_info.psi=argument_list[4].long_reference;
9315 if (attribute_flag[5] != 0)
9316 (void) QueryColorDatabase(argument_list[5].string_reference,
9317 &image->background_color,exception);
9318 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
9319 (long) (geometry_info.xi+0.5),(long) (geometry_info.psi+0.5),
9320 exception);
9321 break;
9322 }
9323 case 95: /* ContrastStretch */
9324 {
9325 double
9326 black_point,
9327 white_point;
9328
9329 black_point=0.0;
9330 white_point=(MagickRealType) image->columns*image->rows;
9331 if (attribute_flag[0] != 0)
9332 {
9333 flags=ParseGeometry(argument_list[0].string_reference,
9334 &geometry_info);
9335 black_point=geometry_info.rho;
9336 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
9337 black_point;
9338 if ((flags & PercentValue) != 0)
9339 {
9340 black_point*=(double) image->columns*image->rows/100.0;
9341 white_point*=(double) image->columns*image->rows/100.0;
9342 }
9343 white_point=(MagickRealType) image->columns*image->rows-
9344 white_point;
9345 }
9346 if (attribute_flag[1] != 0)
9347 black_point=argument_list[1].real_reference;
9348 if (attribute_flag[2] != 0)
9349 white_point=argument_list[2].real_reference;
9350 if (attribute_flag[4] != 0)
9351 channel=(ChannelType) argument_list[4].long_reference;
9352 (void) ContrastStretchImageChannel(image,channel,black_point,
9353 white_point);
9354 break;
9355 }
9356 case 96: /* Sans0 */
9357 {
9358 break;
9359 }
9360 case 97: /* Sans1 */
9361 {
9362 break;
9363 }
9364 case 98: /* AdaptiveSharpen */
9365 {
9366 if (attribute_flag[0] != 0)
9367 {
9368 flags=ParseGeometry(argument_list[0].string_reference,
9369 &geometry_info);
9370 if ((flags & SigmaValue) == 0)
9371 geometry_info.sigma=1.0;
9372 }
9373 if (attribute_flag[1] != 0)
9374 geometry_info.rho=argument_list[1].real_reference;
9375 if (attribute_flag[2] != 0)
9376 geometry_info.sigma=argument_list[2].real_reference;
9377 if (attribute_flag[3] != 0)
9378 channel=(ChannelType) argument_list[3].long_reference;
9379 image=AdaptiveSharpenImageChannel(image,channel,geometry_info.rho,
9380 geometry_info.sigma,exception);
9381 break;
9382 }
9383 case 99: /* Transpose */
9384 {
9385 image=TransposeImage(image,exception);
9386 break;
9387 }
9388 case 100: /* Tranverse */
9389 {
9390 image=TransverseImage(image,exception);
9391 break;
9392 }
9393 case 101: /* AutoOrient */
9394 {
9395 switch (image->orientation)
9396 {
9397 case TopRightOrientation:
9398 {
9399 image=FlopImage(image,exception);
9400 break;
9401 }
9402 case BottomRightOrientation:
9403 {
9404 image=RotateImage(image,180.0,exception);
9405 break;
9406 }
9407 case BottomLeftOrientation:
9408 {
9409 image=FlipImage(image,exception);
9410 break;
9411 }
9412 case LeftTopOrientation:
9413 {
9414 image=TransposeImage(image,exception);
9415 break;
9416 }
9417 case RightTopOrientation:
9418 {
9419 image=RotateImage(image,90.0,exception);
9420 break;
9421 }
9422 case RightBottomOrientation:
9423 {
9424 image=TransverseImage(image,exception);
9425 break;
9426 }
9427 case LeftBottomOrientation:
9428 {
9429 image=RotateImage(image,270.0,exception);
9430 break;
9431 }
9432 default:
9433 break;
9434 }
9435 break;
9436 }
9437 case 102: /* AdaptiveBlur */
9438 {
9439 if (attribute_flag[0] != 0)
9440 {
9441 flags=ParseGeometry(argument_list[0].string_reference,
9442 &geometry_info);
9443 if ((flags & SigmaValue) == 0)
9444 geometry_info.sigma=1.0;
9445 }
9446 if (attribute_flag[1] != 0)
9447 geometry_info.rho=argument_list[1].real_reference;
9448 if (attribute_flag[2] != 0)
9449 geometry_info.sigma=argument_list[2].real_reference;
9450 if (attribute_flag[3] != 0)
9451 channel=(ChannelType) argument_list[3].long_reference;
9452 image=AdaptiveBlurImageChannel(image,channel,geometry_info.rho,
9453 geometry_info.sigma,exception);
9454 break;
9455 }
9456 case 103: /* Sketch */
9457 {
9458 if (attribute_flag[0] != 0)
9459 {
9460 flags=ParseGeometry(argument_list[0].string_reference,
9461 &geometry_info);
9462 if ((flags & SigmaValue) == 0)
9463 geometry_info.sigma=1.0;
9464 if ((flags & XiValue) == 0)
9465 geometry_info.xi=1.0;
9466 }
9467 if (attribute_flag[1] != 0)
9468 geometry_info.rho=argument_list[1].real_reference;
9469 if (attribute_flag[2] != 0)
9470 geometry_info.sigma=argument_list[2].real_reference;
9471 if (attribute_flag[3] != 0)
9472 geometry_info.xi=argument_list[3].real_reference;
9473 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
9474 geometry_info.xi,exception);
9475 break;
9476 }
9477 case 104: /* UniqueColors */
9478 {
9479 image=UniqueImageColors(image,exception);
9480 break;
9481 }
9482 case 105: /* AdaptiveResize */
9483 {
9484 if (attribute_flag[0] != 0)
9485 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9486 &geometry,exception);
9487 if (attribute_flag[1] != 0)
9488 geometry.width=argument_list[1].long_reference;
9489 if (attribute_flag[2] != 0)
9490 geometry.height=argument_list[2].long_reference;
9491 if (attribute_flag[3] != 0)
9492 image->filter=(FilterTypes) argument_list[4].long_reference;
9493 if (attribute_flag[4] != 0)
9494 SetImageArtifact(image,"filter:support",
9495 argument_list[4].string_reference);
9496 if (attribute_flag[5] != 0)
9497 image->blur=argument_list[5].real_reference;
9498 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
9499 exception);
9500 break;
9501 }
9502 case 106: /* ClipMask */
9503 {
9504 if (attribute_flag[0] == 0)
9505 {
9506 ThrowPerlException(exception,OptionError,"MaskImageRequired",
9507 PackageName);
9508 goto PerlException;
9509 }
9510 image->clip_mask=CloneImage(argument_list[0].image_reference,0,0,
9511 MagickTrue,exception);
9512 (void) NegateImage(image->clip_mask,MagickFalse);
9513 break;
9514 }
9515 case 107: /* LinearStretch */
9516 {
9517 double
9518 black_point,
9519 white_point;
9520
9521 black_point=0.0;
9522 white_point=(MagickRealType) image->columns*image->rows;
9523 if (attribute_flag[0] != 0)
9524 {
9525 flags=ParseGeometry(argument_list[0].string_reference,
9526 &geometry_info);
9527 if ((flags & SigmaValue) != 0)
9528 white_point=geometry_info.sigma;
9529 if ((flags & PercentValue) != 0)
9530 {
9531 black_point*=(double) image->columns*image->rows/100.0;
9532 white_point*=(double) image->columns*image->rows/100.0;
9533 }
9534 if ((flags & SigmaValue) == 0)
9535 white_point=(double) image->columns*image->rows-black_point;
9536 }
9537 if (attribute_flag[1] != 0)
9538 black_point=argument_list[1].real_reference;
9539 if (attribute_flag[2] != 0)
9540 white_point=argument_list[2].real_reference;
9541 (void) LinearStretchImage(image,black_point,white_point);
9542 break;
9543 }
9544 case 108: /* Recolor */
9545 {
9546 AV
9547 *av;
9548
9549 double
9550 *color_matrix;
9551
9552 unsigned long
9553 order;
9554
9555 if (attribute_flag[0] == 0)
9556 break;
9557 av=(AV *) argument_list[0].array_reference;
9558 order=(unsigned long) sqrt(av_len(av)+1);
9559 color_matrix=(double *) AcquireQuantumMemory(order,order*
9560 sizeof(*color_matrix));
9561 if (color_matrix == (double *) NULL)
9562 {
9563 ThrowPerlException(exception,ResourceLimitFatalError,
9564 "MemoryAllocationFailed",PackageName);
9565 goto PerlException;
9566 }
9567 for (j=0; (j < (long) (order*order)) && (j < (av_len(av)+1)); j++)
9568 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
9569 for ( ; j < (long) (order*order); j++)
9570 color_matrix[j]=0.0;
9571 image=RecolorImage(image,order,color_matrix,exception);
9572 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
9573 break;
9574 }
9575 case 109: /* Mask */
9576 {
9577 if (attribute_flag[0] == 0)
9578 {
9579 ThrowPerlException(exception,OptionError,"MaskImageRequired",
9580 PackageName);
9581 goto PerlException;
9582 }
9583 image->mask=CloneImage(argument_list[0].image_reference,0,0,
9584 MagickTrue,exception);
9585 (void) NegateImage(image->mask,MagickFalse);
9586 break;
9587 }
9588 case 110: /* Polaroid */
9589 {
9590 DrawInfo
9591 *draw_info;
9592
9593 double
9594 angle;
9595
9596 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9597 (DrawInfo *) NULL);
9598 if (attribute_flag[0] != 0)
9599 (void) SetImageProperty(image,"caption",InterpretImageProperties(
9600 info ? info->image_info : (ImageInfo *) NULL,image,
9601 argument_list[0].string_reference));
9602 angle=0.0;
9603 if (attribute_flag[1] != 0)
9604 angle=argument_list[1].real_reference;
9605 if (attribute_flag[2] != 0)
9606 (void) CloneString(&draw_info->font,
9607 argument_list[2].string_reference);
9608 if (attribute_flag[3] != 0)
9609 (void) QueryColorDatabase(argument_list[3].string_reference,
9610 &draw_info->stroke,exception);
9611 if (attribute_flag[4] != 0)
9612 (void) QueryColorDatabase(argument_list[4].string_reference,
9613 &draw_info->fill,exception);
9614 if (attribute_flag[5] != 0)
9615 draw_info->stroke_width=argument_list[5].real_reference;
9616 if (attribute_flag[6] != 0)
9617 draw_info->pointsize=argument_list[6].real_reference;
9618 if (attribute_flag[7] != 0)
9619 draw_info->gravity=(GravityType) argument_list[7].long_reference;
9620 if (attribute_flag[8] != 0)
9621 (void) QueryColorDatabase(argument_list[8].string_reference,
9622 &image->background_color,exception);
9623 image=PolaroidImage(image,draw_info,angle,exception);
9624 draw_info=DestroyDrawInfo(draw_info);
9625 break;
9626 }
9627 case 111: /* FloodfillPaint */
9628 {
9629 DrawInfo
9630 *draw_info;
9631
9632 MagickBooleanType
9633 invert;
9634
9635 MagickPixelPacket
9636 target;
9637
9638 draw_info=CloneDrawInfo(info ? info->image_info :
9639 (ImageInfo *) NULL,(DrawInfo *) NULL);
9640 if (attribute_flag[0] != 0)
9641 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9642 &geometry,exception);
9643 if (attribute_flag[1] != 0)
9644 geometry.x=argument_list[1].long_reference;
9645 if (attribute_flag[2] != 0)
9646 geometry.y=argument_list[2].long_reference;
9647 if (attribute_flag[3] != 0)
9648 (void) QueryColorDatabase(argument_list[3].string_reference,
9649 &draw_info->fill,exception);
9650 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
9651 exception);
9652 if (attribute_flag[4] != 0)
9653 QueryMagickColor(argument_list[4].string_reference,&target,
9654 exception);
9655 if (attribute_flag[5] != 0)
9656 image->fuzz=StringToDouble(argument_list[5].string_reference,
9657 QuantumRange);
9658 if (attribute_flag[6] != 0)
9659 channel=(ChannelType) argument_list[6].long_reference;
9660 invert=MagickFalse;
9661 if (attribute_flag[7] != 0)
9662 invert=(MagickBooleanType) argument_list[7].long_reference;
9663 (void) FloodfillPaintImage(image,channel,draw_info,&target,geometry.x,
9664 geometry.y,invert);
9665 draw_info=DestroyDrawInfo(draw_info);
9666 break;
9667 }
9668 case 112: /* Distort */
9669 {
9670 AV
9671 *av;
9672
9673 double
9674 *coordinates;
9675
9676 DistortImageMethod
9677 method;
9678
9679 unsigned long
9680 number_coordinates;
9681
9682 VirtualPixelMethod
9683 virtual_pixel;
9684
9685 if (attribute_flag[0] == 0)
9686 break;
9687 method=UndefinedDistortion;
9688 if (attribute_flag[1] != 0)
9689 method=(DistortImageMethod) argument_list[1].long_reference;
9690 av=(AV *) argument_list[0].array_reference;
9691 number_coordinates=(unsigned long) av_len(av)+1;
9692 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
9693 sizeof(*coordinates));
9694 if (coordinates == (double *) NULL)
9695 {
9696 ThrowPerlException(exception,ResourceLimitFatalError,
9697 "MemoryAllocationFailed",PackageName);
9698 goto PerlException;
9699 }
9700 for (j=0; j < (long) number_coordinates; j++)
9701 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
9702 virtual_pixel=UndefinedVirtualPixelMethod;
9703 if (attribute_flag[2] != 0)
9704 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9705 argument_list[2].long_reference);
9706 image=DistortImage(image,method,number_coordinates,coordinates,
9707 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse,
9708 exception);
9709 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9710 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9711 coordinates=(double *) RelinquishMagickMemory(coordinates);
9712 break;
9713 }
9714 case 113: /* Clut */
9715 {
9716 if (attribute_flag[0] == 0)
9717 {
9718 ThrowPerlException(exception,OptionError,"ClutImageRequired",
9719 PackageName);
9720 goto PerlException;
9721 }
9722 if (attribute_flag[1] != 0)
9723 channel=(ChannelType) argument_list[1].long_reference;
9724 (void) ClutImageChannel(image,channel,
9725 argument_list[0].image_reference);
9726 break;
9727 }
9728 case 114: /* LiquidRescale */
9729 {
9730 if (attribute_flag[0] != 0)
9731 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9732 &geometry,exception);
9733 if (attribute_flag[1] != 0)
9734 geometry.width=argument_list[1].long_reference;
9735 if (attribute_flag[2] != 0)
9736 geometry.height=argument_list[2].long_reference;
9737 if (attribute_flag[3] == 0)
9738 argument_list[3].real_reference=1.0;
9739 if (attribute_flag[4] == 0)
9740 argument_list[4].real_reference=0.0;
9741 image=LiquidRescaleImage(image,geometry.width,geometry.height,
9742 argument_list[3].real_reference,argument_list[4].real_reference,
9743 exception);
9744 break;
9745 }
9746 case 115: /* EncipherImage */
9747 {
9748 (void) EncipherImage(image,argument_list[0].string_reference,
9749 exception);
9750 break;
9751 }
9752 case 116: /* DecipherImage */
9753 {
9754 (void) DecipherImage(image,argument_list[0].string_reference,
9755 exception);
9756 break;
9757 }
9758 case 117: /* Deskew */
9759 {
9760 geometry_info.rho=QuantumRange/2.0;
9761 if (attribute_flag[0] != 0)
9762 flags=ParseGeometry(argument_list[0].string_reference,
9763 &geometry_info);
9764 if (attribute_flag[1] != 0)
9765 geometry_info.rho=StringToDouble(argument_list[1].string_reference,
9766 QuantumRange);
9767 image=DeskewImage(image,geometry_info.rho,exception);
9768 break;
9769 }
9770 case 118: /* Remap */
9771 {
9772 QuantizeInfo
9773 *quantize_info;
9774
9775 if (attribute_flag[0] == 0)
9776 {
9777 ThrowPerlException(exception,OptionError,"RemapImageRequired",
9778 PackageName);
9779 goto PerlException;
9780 }
9781 quantize_info=AcquireQuantizeInfo(info->image_info);
9782 if (attribute_flag[1] == 0)
9783 quantize_info->dither_method=(DitherMethod)
9784 argument_list[1].long_reference;
9785 (void) RemapImages(quantize_info,image,
9786 argument_list[0].image_reference);
9787 quantize_info=DestroyQuantizeInfo(quantize_info);
9788 break;
9789 }
9790 case 119: /* SparseColor */
9791 {
9792 AV
9793 *av;
9794
9795 double
9796 *coordinates;
9797
9798 SparseColorMethod
9799 method;
9800
9801 unsigned long
9802 number_coordinates;
9803
9804 VirtualPixelMethod
9805 virtual_pixel;
9806
9807 if (attribute_flag[0] == 0)
9808 break;
9809 method=UndefinedColorInterpolate;
9810 if (attribute_flag[1] != 0)
9811 method=(SparseColorMethod) argument_list[1].long_reference;
9812 av=(AV *) argument_list[0].array_reference;
9813 number_coordinates=(unsigned long) av_len(av)+1;
9814 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
9815 sizeof(*coordinates));
9816 if (coordinates == (double *) NULL)
9817 {
9818 ThrowPerlException(exception,ResourceLimitFatalError,
9819 "MemoryAllocationFailed",PackageName);
9820 goto PerlException;
9821 }
9822 for (j=0; j < (long) number_coordinates; j++)
9823 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
9824 virtual_pixel=UndefinedVirtualPixelMethod;
9825 if (attribute_flag[2] != 0)
9826 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9827 argument_list[2].long_reference);
9828 if (attribute_flag[3] != 0)
9829 channel=(ChannelType) argument_list[3].long_reference;
9830 image=SparseColorImage(image,channel,method,number_coordinates,
9831 coordinates,exception);
9832 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9833 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9834 coordinates=(double *) RelinquishMagickMemory(coordinates);
9835 break;
9836 }
9837 case 120: /* Function */
9838 {
9839 AV
9840 *av;
9841
9842 double
9843 *parameters;
9844
9845 MagickFunction
9846 function;
9847
9848 unsigned long
9849 number_parameters;
9850
9851 VirtualPixelMethod
9852 virtual_pixel;
9853
9854 if (attribute_flag[0] == 0)
9855 break;
9856 function=UndefinedFunction;
9857 if (attribute_flag[1] != 0)
9858 function=(MagickFunction) argument_list[1].long_reference;
9859 av=(AV *) argument_list[0].array_reference;
9860 number_parameters=(unsigned long) av_len(av)+1;
9861 parameters=(double *) AcquireQuantumMemory(number_parameters,
9862 sizeof(*parameters));
9863 if (parameters == (double *) NULL)
9864 {
9865 ThrowPerlException(exception,ResourceLimitFatalError,
9866 "MemoryAllocationFailed",PackageName);
9867 goto PerlException;
9868 }
9869 for (j=0; j < (long) number_parameters; j++)
9870 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
9871 virtual_pixel=UndefinedVirtualPixelMethod;
9872 if (attribute_flag[2] != 0)
9873 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9874 argument_list[2].long_reference);
9875 (void) FunctionImage(image,function,number_parameters,parameters,
9876 exception);
9877 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9878 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9879 parameters=(double *) RelinquishMagickMemory(parameters);
9880 break;
9881 }
9882 case 121: /* SelectiveBlur */
9883 {
9884 if (attribute_flag[0] != 0)
9885 {
9886 flags=ParseGeometry(argument_list[0].string_reference,
9887 &geometry_info);
9888 if ((flags & SigmaValue) == 0)
9889 geometry_info.sigma=1.0;
9890 if ((flags & PercentValue) != 0)
9891 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9892 }
9893 if (attribute_flag[1] != 0)
9894 geometry_info.rho=argument_list[1].real_reference;
9895 if (attribute_flag[2] != 0)
9896 geometry_info.sigma=argument_list[2].real_reference;
9897 if (attribute_flag[3] != 0)
9898 geometry_info.xi=argument_list[3].long_reference;;
9899 if (attribute_flag[4] != 0)
9900 channel=(ChannelType) argument_list[4].long_reference;
9901 image=SelectiveBlurImageChannel(image,channel,geometry_info.rho,
9902 geometry_info.sigma,geometry_info.xi,exception);
9903 break;
9904 }
9905 case 122: /* HaldClut */
9906 {
9907 if (attribute_flag[0] == 0)
9908 {
9909 ThrowPerlException(exception,OptionError,"ClutImageRequired",
9910 PackageName);
9911 goto PerlException;
9912 }
9913 if (attribute_flag[1] != 0)
9914 channel=(ChannelType) argument_list[1].long_reference;
9915 (void) HaldClutImageChannel(image,channel,
9916 argument_list[0].image_reference);
9917 break;
9918 }
9919 case 123: /* BlueShift */
9920 {
9921 if (attribute_flag[0] != 0)
9922 (void) ParseGeometry(argument_list[0].string_reference,
9923 &geometry_info);
9924 image=BlueShiftImage(image,geometry_info.rho,exception);
9925 break;
9926 }
9927 case 124: /* ForwardFourierTransformImage */
9928 {
9929 image=ForwardFourierTransformImage(image,
9930 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse,
9931 exception);
9932 break;
9933 }
9934 case 125: /* InverseFourierTransformImage */
9935 {
9936 image=InverseFourierTransformImage(image,
9937 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse,
9938 exception);
9939 break;
9940 }
9941 case 126: /* ColorDecisionList */
9942 {
9943 if (attribute_flag[0] == 0)
9944 argument_list[0].string_reference=(char *) NULL;
9945 (void) ColorDecisionListImage(image,
9946 argument_list[0].string_reference);
9947 break;
9948 }
9949 case 127: /* AutoGamma */
9950 {
9951 if (attribute_flag[0] != 0)
9952 channel=(ChannelType) argument_list[0].long_reference;
9953 (void) AutoGammaImageChannel(image,channel);
9954 break;
9955 }
9956 case 128: /* AutoLevel */
9957 {
9958 if (attribute_flag[0] != 0)
9959 channel=(ChannelType) argument_list[0].long_reference;
9960 (void) AutoLevelImageChannel(image,channel);
9961 break;
9962 }
cristyee0f8d72009-09-19 00:58:29 +00009963 case 129: /* LevelColors */
9964 {
9965 MagickPixelPacket
9966 black_point,
9967 white_point;
9968
9969 (void) QueryMagickColor("#000000",&black_point,exception);
9970 (void) QueryMagickColor("#ffffff",&black_point,exception);
9971 if (attribute_flag[1] != 0)
9972 (void) QueryMagickColor(argument_list[1].string_reference,
9973 &black_point,exception);
9974 if (attribute_flag[2] != 0)
9975 (void) QueryMagickColor(argument_list[2].string_reference,
9976 &white_point,exception);
9977 if (attribute_flag[3] != 0)
9978 channel=(ChannelType) argument_list[3].long_reference;
cristy1eb45dd2009-09-25 16:38:06 +00009979 (void) LevelColorsImageChannel(image,channel,&black_point,
9980 &white_point,argument_list[0].long_reference != 0 ? MagickTrue :
9981 MagickFalse);
9982 break;
9983 }
9984 case 130: /* Clamp */
9985 {
9986 if (attribute_flag[0] != 0)
9987 channel=(ChannelType) argument_list[0].long_reference;
9988 (void) ClampImageChannel(image,channel);
cristyee0f8d72009-09-19 00:58:29 +00009989 break;
9990 }
cristy3ed852e2009-09-05 21:47:34 +00009991 }
9992 if (next != (Image *) NULL)
9993 (void) CatchImageException(next);
9994 if (region_image != (Image *) NULL)
9995 {
9996 /*
9997 Composite region.
9998 */
9999 status=CompositeImage(region_image,CopyCompositeOp,image,
10000 region_info.x,region_info.y);
10001 (void) CatchImageException(region_image);
10002 image=DestroyImage(image);
10003 image=region_image;
10004 }
10005 if (image != (Image *) NULL)
10006 {
10007 number_images++;
10008 if (next && (next != image))
10009 {
10010 image->next=next->next;
10011 DeleteImageFromRegistry(*pv,next);
10012 }
10013 sv_setiv(*pv,(IV) image);
10014 next=image;
10015 }
10016 if (*pv)
10017 pv++;
10018 }
10019
10020 PerlException:
10021 if (reference_vector)
10022 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
10023 InheritPerlException(exception,perl_exception);
10024 exception=DestroyExceptionInfo(exception);
10025 sv_setiv(perl_exception,(IV) number_images);
10026 SvPOK_on(perl_exception);
10027 ST(0)=sv_2mortal(perl_exception);
10028 XSRETURN(1);
10029 }
10030
10031#
10032###############################################################################
10033# #
10034# #
10035# #
10036# M o n t a g e #
10037# #
10038# #
10039# #
10040###############################################################################
10041#
10042#
10043void
10044Montage(ref,...)
10045 Image::Magick ref=NO_INIT
10046 ALIAS:
10047 MontageImage = 1
10048 montage = 2
10049 montageimage = 3
10050 PPCODE:
10051 {
10052 AV
10053 *av;
10054
10055 char
10056 *attribute;
10057
10058 ExceptionInfo
10059 *exception;
10060
10061 HV
10062 *hv;
10063
10064 Image
10065 *image,
10066 *next;
10067
10068 long
10069 sp;
10070
10071 MagickPixelPacket
10072 transparent_color;
10073
10074 MontageInfo
10075 *montage_info;
10076
10077 register long
10078 i;
10079
10080 struct PackageInfo
10081 *info;
10082
10083 SV
10084 *av_reference,
10085 *perl_exception,
10086 *reference,
10087 *rv,
10088 *sv;
10089
10090 exception=AcquireExceptionInfo();
10091 perl_exception=newSVpv("",0);
10092 attribute=NULL;
10093 if (sv_isobject(ST(0)) == 0)
10094 {
10095 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10096 PackageName);
10097 goto PerlException;
10098 }
10099 reference=SvRV(ST(0));
10100 hv=SvSTASH(reference);
10101 av=newAV();
10102 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10103 SvREFCNT_dec(av);
10104 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10105 if (image == (Image *) NULL)
10106 {
10107 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10108 PackageName);
10109 goto PerlException;
10110 }
10111 /*
10112 Get options.
10113 */
10114 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10115 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
10116 (void) QueryMagickColor("none",&transparent_color,exception);
10117 for (i=2; i < items; i+=2)
10118 {
10119 attribute=(char *) SvPV(ST(i-1),na);
10120 switch (*attribute)
10121 {
10122 case 'B':
10123 case 'b':
10124 {
10125 if (LocaleCompare(attribute,"background") == 0)
10126 {
10127 (void) QueryColorDatabase(SvPV(ST(i),na),
10128 &montage_info->background_color,exception);
10129 for (next=image; next; next=next->next)
10130 next->background_color=montage_info->background_color;
10131 break;
10132 }
10133 if (LocaleCompare(attribute,"border") == 0)
10134 {
10135 montage_info->border_width=SvIV(ST(i));
10136 break;
10137 }
10138 if (LocaleCompare(attribute,"bordercolor") == 0)
10139 {
10140 (void) QueryColorDatabase(SvPV(ST(i),na),
10141 &montage_info->border_color,exception);
10142 for (next=image; next; next=next->next)
10143 next->border_color=montage_info->border_color;
10144 break;
10145 }
10146 if (LocaleCompare(attribute,"borderwidth") == 0)
10147 {
10148 montage_info->border_width=SvIV(ST(i));
10149 break;
10150 }
10151 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10152 attribute);
10153 break;
10154 }
10155 case 'C':
10156 case 'c':
10157 {
10158 if (LocaleCompare(attribute,"compose") == 0)
10159 {
10160 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10161 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
10162 if (sp < 0)
10163 {
10164 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10165 SvPV(ST(i),na));
10166 break;
10167 }
10168 for (next=image; next; next=next->next)
10169 next->compose=(CompositeOperator) sp;
10170 break;
10171 }
10172 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10173 attribute);
10174 break;
10175 }
10176 case 'F':
10177 case 'f':
10178 {
10179 if (LocaleCompare(attribute,"fill") == 0)
10180 {
10181 (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->fill,
10182 exception);
10183 break;
10184 }
10185 if (LocaleCompare(attribute,"font") == 0)
10186 {
10187 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
10188 break;
10189 }
10190 if (LocaleCompare(attribute,"frame") == 0)
10191 {
10192 char
10193 *p;
10194
10195 p=SvPV(ST(i),na);
10196 if (IsGeometry(p) == MagickFalse)
10197 {
10198 ThrowPerlException(exception,OptionError,"MissingGeometry",
10199 p);
10200 break;
10201 }
10202 (void) CloneString(&montage_info->frame,p);
10203 if (*p == '\0')
10204 montage_info->frame=(char *) NULL;
10205 break;
10206 }
10207 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10208 attribute);
10209 break;
10210 }
10211 case 'G':
10212 case 'g':
10213 {
10214 if (LocaleCompare(attribute,"geometry") == 0)
10215 {
10216 char
10217 *p;
10218
10219 p=SvPV(ST(i),na);
10220 if (IsGeometry(p) == MagickFalse)
10221 {
10222 ThrowPerlException(exception,OptionError,"MissingGeometry",
10223 p);
10224 break;
10225 }
10226 (void) CloneString(&montage_info->geometry,p);
10227 if (*p == '\0')
10228 montage_info->geometry=(char *) NULL;
10229 break;
10230 }
10231 if (LocaleCompare(attribute,"gravity") == 0)
10232 {
10233 long
10234 in;
10235
10236 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10237 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
10238 if (in < 0)
10239 {
10240 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10241 SvPV(ST(i),na));
10242 return;
10243 }
10244 montage_info->gravity=(GravityType) in;
10245 for (next=image; next; next=next->next)
10246 next->gravity=(GravityType) in;
10247 break;
10248 }
10249 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10250 attribute);
10251 break;
10252 }
10253 case 'L':
10254 case 'l':
10255 {
10256 if (LocaleCompare(attribute,"label") == 0)
10257 {
10258 for (next=image; next; next=next->next)
10259 (void) SetImageProperty(next,"label",InterpretImageProperties(
10260 info ? info->image_info : (ImageInfo *) NULL,next,
10261 SvPV(ST(i),na)));
10262 break;
10263 }
10264 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10265 attribute);
10266 break;
10267 }
10268 case 'M':
10269 case 'm':
10270 {
10271 if (LocaleCompare(attribute,"mattecolor") == 0)
10272 {
10273 (void) QueryColorDatabase(SvPV(ST(i),na),
10274 &montage_info->matte_color,exception);
10275 for (next=image; next; next=next->next)
10276 next->matte_color=montage_info->matte_color;
10277 break;
10278 }
10279 if (LocaleCompare(attribute,"mode") == 0)
10280 {
10281 long
10282 in;
10283
10284 in=!SvPOK(ST(i)) ? SvIV(ST(i)) :
10285 ParseMagickOption(MagickModeOptions,MagickFalse,SvPV(ST(i),na));
10286 switch (in)
10287 {
10288 default:
10289 {
10290 ThrowPerlException(exception,OptionError,
10291 "UnrecognizedModeType",SvPV(ST(i),na));
10292 break;
10293 }
10294 case FrameMode:
10295 {
10296 (void) CloneString(&montage_info->frame,"15x15+3+3");
10297 montage_info->shadow=MagickTrue;
10298 break;
10299 }
10300 case UnframeMode:
10301 {
10302 montage_info->frame=(char *) NULL;
10303 montage_info->shadow=MagickFalse;
10304 montage_info->border_width=0;
10305 break;
10306 }
10307 case ConcatenateMode:
10308 {
10309 montage_info->frame=(char *) NULL;
10310 montage_info->shadow=MagickFalse;
10311 (void) CloneString(&montage_info->geometry,"+0+0");
10312 montage_info->border_width=0;
10313 }
10314 }
10315 break;
10316 }
10317 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10318 attribute);
10319 break;
10320 }
10321 case 'P':
10322 case 'p':
10323 {
10324 if (LocaleCompare(attribute,"pointsize") == 0)
10325 {
10326 montage_info->pointsize=SvIV(ST(i));
10327 break;
10328 }
10329 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10330 attribute);
10331 break;
10332 }
10333 case 'S':
10334 case 's':
10335 {
10336 if (LocaleCompare(attribute,"shadow") == 0)
10337 {
10338 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10339 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
10340 if (sp < 0)
10341 {
10342 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10343 SvPV(ST(i),na));
10344 break;
10345 }
10346 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
10347 break;
10348 }
10349 if (LocaleCompare(attribute,"stroke") == 0)
10350 {
10351 (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->stroke,
10352 exception);
10353 break;
10354 }
10355 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10356 attribute);
10357 break;
10358 }
10359 case 'T':
10360 case 't':
10361 {
10362 if (LocaleCompare(attribute,"texture") == 0)
10363 {
10364 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
10365 break;
10366 }
10367 if (LocaleCompare(attribute,"tile") == 0)
10368 {
10369 char *p=SvPV(ST(i),na);
10370 if (IsGeometry(p) == MagickFalse)
10371 {
10372 ThrowPerlException(exception,OptionError,"MissingGeometry",
10373 p);
10374 break;
10375 }
10376 (void) CloneString(&montage_info->tile,p);
10377 if (*p == '\0')
10378 montage_info->tile=(char *) NULL;
10379 break;
10380 }
10381 if (LocaleCompare(attribute,"title") == 0)
10382 {
10383 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
10384 break;
10385 }
10386 if (LocaleCompare(attribute,"transparent") == 0)
10387 {
10388 MagickPixelPacket
10389 transparent_color;
10390
10391 QueryMagickColor(SvPV(ST(i),na),&transparent_color,exception);
10392 for (next=image; next; next=next->next)
10393 (void) TransparentPaintImage(next,&transparent_color,
10394 TransparentOpacity,MagickFalse);
10395 break;
10396 }
10397 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10398 attribute);
10399 break;
10400 }
10401 default:
10402 {
10403 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10404 attribute);
10405 break;
10406 }
10407 }
10408 }
10409 image=MontageImageList(info->image_info,montage_info,image,exception);
10410 montage_info=DestroyMontageInfo(montage_info);
10411 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10412 goto PerlException;
10413 if (transparent_color.opacity != TransparentOpacity)
10414 for (next=image; next; next=next->next)
10415 (void) TransparentPaintImage(next,&transparent_color,
10416 TransparentOpacity,MagickFalse);
10417 for ( ; image; image=image->next)
10418 {
10419 AddImageToRegistry(image);
10420 rv=newRV(sv);
10421 av_push(av,sv_bless(rv,hv));
10422 SvREFCNT_dec(sv);
10423 }
10424 exception=DestroyExceptionInfo(exception);
10425 ST(0)=av_reference;
10426 SvREFCNT_dec(perl_exception);
10427 XSRETURN(1);
10428
10429 PerlException:
10430 InheritPerlException(exception,perl_exception);
10431 exception=DestroyExceptionInfo(exception);
10432 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10433 SvPOK_on(perl_exception);
10434 ST(0)=sv_2mortal(perl_exception);
10435 XSRETURN(1);
10436 }
10437
10438#
10439###############################################################################
10440# #
10441# #
10442# #
10443# M o r p h #
10444# #
10445# #
10446# #
10447###############################################################################
10448#
10449#
10450void
10451Morph(ref,...)
10452 Image::Magick ref=NO_INIT
10453 ALIAS:
10454 MorphImage = 1
10455 morph = 2
10456 morphimage = 3
10457 PPCODE:
10458 {
10459 AV
10460 *av;
10461
10462 char
10463 *attribute;
10464
10465 ExceptionInfo
10466 *exception;
10467
10468 HV
10469 *hv;
10470
10471 Image
10472 *image;
10473
10474 long
10475 number_frames;
10476
10477 register long
10478 i;
10479
10480 struct PackageInfo
10481 *info;
10482
10483 SV
10484 *av_reference,
10485 *perl_exception,
10486 *reference,
10487 *rv,
10488 *sv;
10489
10490 exception=AcquireExceptionInfo();
10491 perl_exception=newSVpv("",0);
10492 av=NULL;
10493 attribute=NULL;
10494 if (sv_isobject(ST(0)) == 0)
10495 {
10496 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10497 PackageName);
10498 goto PerlException;
10499 }
10500 reference=SvRV(ST(0));
10501 hv=SvSTASH(reference);
10502 av=newAV();
10503 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10504 SvREFCNT_dec(av);
10505 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10506 if (image == (Image *) NULL)
10507 {
10508 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10509 PackageName);
10510 goto PerlException;
10511 }
10512 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10513 /*
10514 Get attribute.
10515 */
10516 number_frames=30;
10517 for (i=2; i < items; i+=2)
10518 {
10519 attribute=(char *) SvPV(ST(i-1),na);
10520 switch (*attribute)
10521 {
10522 case 'F':
10523 case 'f':
10524 {
10525 if (LocaleCompare(attribute,"frames") == 0)
10526 {
10527 number_frames=SvIV(ST(i));
10528 break;
10529 }
10530 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10531 attribute);
10532 break;
10533 }
10534 default:
10535 {
10536 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10537 attribute);
10538 break;
10539 }
10540 }
10541 }
10542 image=MorphImages(image,number_frames,exception);
10543 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10544 goto PerlException;
10545 for ( ; image; image=image->next)
10546 {
10547 AddImageToRegistry(image);
10548 rv=newRV(sv);
10549 av_push(av,sv_bless(rv,hv));
10550 SvREFCNT_dec(sv);
10551 }
10552 exception=DestroyExceptionInfo(exception);
10553 ST(0)=av_reference;
10554 SvREFCNT_dec(perl_exception); /* can't return warning messages */
10555 XSRETURN(1);
10556
10557 PerlException:
10558 InheritPerlException(exception,perl_exception);
10559 exception=DestroyExceptionInfo(exception);
10560 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10561 SvPOK_on(perl_exception);
10562 ST(0)=sv_2mortal(perl_exception);
10563 XSRETURN(1);
10564 }
10565
10566#
10567###############################################################################
10568# #
10569# #
10570# #
10571# M o s a i c #
10572# #
10573# #
10574# #
10575###############################################################################
10576#
10577#
10578void
10579Mosaic(ref)
10580 Image::Magick ref=NO_INIT
10581 ALIAS:
10582 MosaicImage = 1
10583 mosaic = 2
10584 mosaicimage = 3
10585 PPCODE:
10586 {
10587 AV
10588 *av;
10589
10590 ExceptionInfo
10591 *exception;
10592
10593 HV
10594 *hv;
10595
10596 Image
10597 *image;
10598
10599 struct PackageInfo
10600 *info;
10601
10602 SV
10603 *perl_exception,
10604 *reference,
10605 *rv,
10606 *sv;
10607
10608 exception=AcquireExceptionInfo();
10609 perl_exception=newSVpv("",0);
10610 if (sv_isobject(ST(0)) == 0)
10611 {
10612 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10613 PackageName);
10614 goto PerlException;
10615 }
10616 reference=SvRV(ST(0));
10617 hv=SvSTASH(reference);
10618 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10619 if (image == (Image *) NULL)
10620 {
10621 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10622 PackageName);
10623 goto PerlException;
10624 }
10625 image=MergeImageLayers(image,MosaicLayer,exception);
10626 /*
10627 Create blessed Perl array for the returned image.
10628 */
10629 av=newAV();
10630 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10631 SvREFCNT_dec(av);
10632 AddImageToRegistry(image);
10633 rv=newRV(sv);
10634 av_push(av,sv_bless(rv,hv));
10635 SvREFCNT_dec(sv);
10636 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10637 (void) CopyMagickString(image->filename,info->image_info->filename,
10638 MaxTextExtent);
10639 SetImageInfo(info->image_info,MagickFalse,&image->exception);
10640 exception=DestroyExceptionInfo(exception);
10641 SvREFCNT_dec(perl_exception);
10642 XSRETURN(1);
10643
10644 PerlException:
10645 InheritPerlException(exception,perl_exception);
10646 exception=DestroyExceptionInfo(exception);
10647 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10648 SvPOK_on(perl_exception); /* return messages in string context */
10649 ST(0)=sv_2mortal(perl_exception);
10650 XSRETURN(1);
10651 }
10652
10653#
10654###############################################################################
10655# #
10656# #
10657# #
10658# P i n g #
10659# #
10660# #
10661# #
10662###############################################################################
10663#
10664#
10665void
10666Ping(ref,...)
10667 Image::Magick ref=NO_INIT
10668 ALIAS:
10669 PingImage = 1
10670 ping = 2
10671 pingimage = 3
10672 PPCODE:
10673 {
10674 AV
10675 *av;
10676
10677 char
10678 **keep,
10679 **list;
10680
10681 ExceptionInfo
10682 *exception;
10683
10684 HV
10685 *hv;
10686
10687 Image
10688 *image,
10689 *next;
10690
10691 int
10692 n;
10693
10694 long
10695 ac;
10696
10697 MagickBooleanType
10698 status;
10699
10700 register char
10701 **p;
10702
10703 register long
10704 i;
10705
10706 STRLEN
10707 *length;
10708
10709 struct PackageInfo
10710 *info,
10711 *package_info;
10712
10713 SV
10714 *perl_exception,
10715 *reference;
10716
10717 unsigned long
10718 count;
10719
10720 exception=AcquireExceptionInfo();
10721 perl_exception=newSVpv("",0);
10722 package_info=(struct PackageInfo *) NULL;
10723 ac=(items < 2) ? 1 : items-1;
10724 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
10725 keep=list;
10726 length=(STRLEN *) NULL;
10727 if (list == (char **) NULL)
10728 {
10729 ThrowPerlException(exception,ResourceLimitError,
10730 "MemoryAllocationFailed",PackageName);
10731 goto PerlException;
10732 }
10733 keep=list;
10734 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
10735 if (length == (STRLEN *) NULL)
10736 {
10737 ThrowPerlException(exception,ResourceLimitError,
10738 "MemoryAllocationFailed",PackageName);
10739 goto PerlException;
10740 }
10741 if (sv_isobject(ST(0)) == 0)
10742 {
10743 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10744 PackageName);
10745 goto PerlException;
10746 }
10747 reference=SvRV(ST(0));
10748 hv=SvSTASH(reference);
10749 if (SvTYPE(reference) != SVt_PVAV)
10750 {
10751 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10752 PackageName);
10753 goto PerlException;
10754 }
10755 av=(AV *) reference;
10756 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
10757 exception);
10758 package_info=ClonePackageInfo(info,exception);
10759 n=1;
10760 if (items <= 1)
10761 *list=(char *) (*package_info->image_info->filename ?
10762 package_info->image_info->filename : "XC:black");
10763 else
10764 for (n=0, i=0; i < ac; i++)
10765 {
10766 list[n]=(char *) SvPV(ST(i+1),length[n]);
10767 if ((items >= 3) && strEQcase(list[n],"blob"))
10768 {
10769 void
10770 *blob;
10771
10772 i++;
10773 blob=(void *) (SvPV(ST(i+1),length[n]));
10774 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
10775 }
10776 if ((items >= 3) && strEQcase(list[n],"filename"))
10777 continue;
10778 if ((items >= 3) && strEQcase(list[n],"file"))
10779 {
10780 FILE
10781 *file;
10782
10783 PerlIO
10784 *io_info;
10785
10786 i++;
10787 io_info=IoIFP(sv_2io(ST(i+1)));
10788 if (io_info == (PerlIO *) NULL)
10789 {
10790 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
10791 PackageName);
10792 continue;
10793 }
10794 file=PerlIO_findFILE(io_info);
10795 if (file == (FILE *) NULL)
10796 {
10797 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
10798 PackageName);
10799 continue;
10800 }
10801 SetImageInfoFile(package_info->image_info,file);
10802 }
10803 if ((items >= 3) && strEQcase(list[n],"magick"))
10804 continue;
10805 n++;
10806 }
10807 list[n]=(char *) NULL;
10808 keep=list;
10809 status=ExpandFilenames(&n,&list);
10810 if (status == MagickFalse)
10811 {
10812 ThrowPerlException(exception,ResourceLimitError,
10813 "MemoryAllocationFailed",PackageName);
10814 goto PerlException;
10815 }
10816 count=0;
10817 for (i=0; i < n; i++)
10818 {
10819 (void) CopyMagickString(package_info->image_info->filename,list[i],
10820 MaxTextExtent);
10821 image=PingImage(package_info->image_info,exception);
10822 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10823 break;
10824 if ((package_info->image_info->file != (FILE *) NULL) ||
10825 (package_info->image_info->blob != (void *) NULL))
10826 DisassociateImageStream(image);
10827 count+=GetImageListLength(image);
10828 EXTEND(sp,4*count);
10829 for (next=image; next; next=next->next)
10830 {
10831 PUSHs(sv_2mortal(newSViv(next->columns)));
10832 PUSHs(sv_2mortal(newSViv(next->rows)));
10833 PUSHs(sv_2mortal(newSViv((unsigned long) GetBlobSize(next))));
10834 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
10835 }
10836 image=DestroyImageList(image);
10837 }
10838 /*
10839 Free resources.
10840 */
10841 for (i=0; i < n; i++)
10842 if (list[i] != (char *) NULL)
10843 for (p=keep; list[i] != *p++; )
10844 if (*p == NULL)
10845 {
10846 list[i]=(char *) RelinquishMagickMemory(list[i]);
10847 break;
10848 }
10849
10850 PerlException:
10851 if (package_info != (struct PackageInfo *) NULL)
10852 DestroyPackageInfo(package_info);
10853 if (list && (list != keep))
10854 list=(char **) RelinquishMagickMemory(list);
10855 if (keep)
10856 keep=(char **) RelinquishMagickMemory(keep);
10857 if (length)
10858 length=(STRLEN *) RelinquishMagickMemory(length);
10859 InheritPerlException(exception,perl_exception);
10860 exception=DestroyExceptionInfo(exception);
10861 SvREFCNT_dec(perl_exception); /* throw away all errors */
10862 }
10863
10864#
10865###############################################################################
10866# #
10867# #
10868# #
10869# P r e v i e w #
10870# #
10871# #
10872# #
10873###############################################################################
10874#
10875#
10876void
10877Preview(ref,...)
10878 Image::Magick ref=NO_INIT
10879 ALIAS:
10880 PreviewImage = 1
10881 preview = 2
10882 previewimage = 3
10883 PPCODE:
10884 {
10885 AV
10886 *av;
10887
10888 ExceptionInfo
10889 *exception;
10890
10891 HV
10892 *hv;
10893
10894 Image
10895 *image,
10896 *preview_image;
10897
10898 PreviewType
10899 preview_type;
10900
10901 struct PackageInfo
10902 *info;
10903
10904 SV
10905 *av_reference,
10906 *perl_exception,
10907 *reference,
10908 *rv,
10909 *sv;
10910
10911 exception=AcquireExceptionInfo();
10912 perl_exception=newSVpv("",0);
10913 av=NULL;
10914 if (sv_isobject(ST(0)) == 0)
10915 {
10916 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10917 PackageName);
10918 goto PerlException;
10919 }
10920 reference=SvRV(ST(0));
10921 hv=SvSTASH(reference);
10922 av=newAV();
10923 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10924 SvREFCNT_dec(av);
10925 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10926 if (image == (Image *) NULL)
10927 {
10928 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10929 PackageName);
10930 goto PerlException;
10931 }
10932 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10933 preview_type=GammaPreview;
10934 if (items > 1)
10935 preview_type=(PreviewType)
10936 ParseMagickOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
10937 for ( ; image; image=image->next)
10938 {
10939 preview_image=PreviewImage(image,preview_type,exception);
10940 if (preview_image == (Image *) NULL)
10941 goto PerlException;
10942 AddImageToRegistry(preview_image);
10943 rv=newRV(sv);
10944 av_push(av,sv_bless(rv,hv));
10945 SvREFCNT_dec(sv);
10946 }
10947 exception=DestroyExceptionInfo(exception);
10948 ST(0)=av_reference;
10949 SvREFCNT_dec(perl_exception); /* can't return warning messages */
10950 XSRETURN(1);
10951
10952 PerlException:
10953 InheritPerlException(exception,perl_exception);
10954 exception=DestroyExceptionInfo(exception);
10955 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10956 SvPOK_on(perl_exception);
10957 ST(0)=sv_2mortal(perl_exception);
10958 XSRETURN(1);
10959 }
10960
10961#
10962###############################################################################
10963# #
10964# #
10965# #
10966# Q u e r y C o l o r #
10967# #
10968# #
10969# #
10970###############################################################################
10971#
10972#
10973void
10974QueryColor(ref,...)
10975 Image::Magick ref=NO_INIT
10976 ALIAS:
10977 querycolor = 1
10978 PPCODE:
10979 {
10980 char
10981 *name;
10982
10983 ExceptionInfo
10984 *exception;
10985
10986 MagickPixelPacket
10987 color;
10988
10989 register long
10990 i;
10991
10992 SV
10993 *perl_exception;
10994
10995 exception=AcquireExceptionInfo();
10996 perl_exception=newSVpv("",0);
10997 if (items == 1)
10998 {
10999 const ColorInfo
11000 **colorlist;
11001
11002 unsigned long
11003 colors;
11004
11005 colorlist=GetColorInfoList("*",&colors,exception);
11006 EXTEND(sp,colors);
11007 for (i=0; i < (long) colors; i++)
11008 {
11009 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
11010 }
11011 colorlist=(const ColorInfo **)
11012 RelinquishMagickMemory((ColorInfo **) colorlist);
11013 goto PerlException;
11014 }
11015 EXTEND(sp,5*items);
11016 for (i=1; i < items; i++)
11017 {
11018 name=(char *) SvPV(ST(i),na);
11019 if (QueryMagickColor(name,&color,exception) == MagickFalse)
11020 {
11021 PUSHs(&sv_undef);
11022 continue;
11023 }
11024 PUSHs(sv_2mortal(newSViv((unsigned long) (color.red+0.5))));
11025 PUSHs(sv_2mortal(newSViv((unsigned long) (color.green+0.5))));
11026 PUSHs(sv_2mortal(newSViv((unsigned long) (color.blue+0.5))));
11027 if (color.matte != MagickFalse)
11028 PUSHs(sv_2mortal(newSViv((unsigned long) (color.opacity+0.5))));
11029 if (color.colorspace == CMYKColorspace)
11030 PUSHs(sv_2mortal(newSViv((unsigned long) (color.index+0.5))));
11031 }
11032
11033 PerlException:
11034 InheritPerlException(exception,perl_exception);
11035 exception=DestroyExceptionInfo(exception);
11036 SvREFCNT_dec(perl_exception);
11037 }
11038
11039#
11040###############################################################################
11041# #
11042# #
11043# #
11044# Q u e r y C o l o r N a m e #
11045# #
11046# #
11047# #
11048###############################################################################
11049#
11050#
11051void
11052QueryColorname(ref,...)
11053 Image::Magick ref=NO_INIT
11054 ALIAS:
11055 querycolorname = 1
11056 PPCODE:
11057 {
11058 AV
11059 *av;
11060
11061 char
11062 message[MaxTextExtent];
11063
11064 ExceptionInfo
11065 *exception;
11066
11067 Image
11068 *image;
11069
11070 PixelPacket
11071 target_color;
11072
11073 register long
11074 i;
11075
11076 struct PackageInfo
11077 *info;
11078
11079 SV
11080 *perl_exception,
11081 *reference; /* reference is the SV* of ref=SvIV(reference) */
11082
11083 exception=AcquireExceptionInfo();
11084 perl_exception=newSVpv("",0);
11085 reference=SvRV(ST(0));
11086 av=(AV *) reference;
11087 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11088 exception);
11089 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11090 if (image == (Image *) NULL)
11091 {
11092 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11093 PackageName);
11094 goto PerlException;
11095 }
11096 EXTEND(sp,items);
11097 for (i=1; i < items; i++)
11098 {
11099 (void) QueryColorDatabase(SvPV(ST(i),na),&target_color,exception);
11100 (void) QueryColorname(image,&target_color,SVGCompliance,message,
11101 exception);
11102 PUSHs(sv_2mortal(newSVpv(message,0)));
11103 }
11104
11105 PerlException:
11106 InheritPerlException(exception,perl_exception);
11107 exception=DestroyExceptionInfo(exception);
11108 SvREFCNT_dec(perl_exception);
11109 }
11110
11111#
11112###############################################################################
11113# #
11114# #
11115# #
11116# Q u e r y F o n t #
11117# #
11118# #
11119# #
11120###############################################################################
11121#
11122#
11123void
11124QueryFont(ref,...)
11125 Image::Magick ref=NO_INIT
11126 ALIAS:
11127 queryfont = 1
11128 PPCODE:
11129 {
11130 char
11131 *name,
11132 message[MaxTextExtent];
11133
11134 ExceptionInfo
11135 *exception;
11136
11137 register long
11138 i;
11139
11140 SV
11141 *perl_exception;
11142
11143 volatile const TypeInfo
11144 *type_info;
11145
11146 exception=AcquireExceptionInfo();
11147 perl_exception=newSVpv("",0);
11148 if (items == 1)
11149 {
11150 const TypeInfo
11151 **typelist;
11152
11153 unsigned long
11154 types;
11155
11156 typelist=GetTypeInfoList("*",&types,exception);
11157 EXTEND(sp,types);
11158 for (i=0; i < (long) types; i++)
11159 {
11160 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
11161 }
11162 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
11163 typelist);
11164 goto PerlException;
11165 }
11166 EXTEND(sp,10*items);
11167 for (i=1; i < items; i++)
11168 {
11169 name=(char *) SvPV(ST(i),na);
11170 type_info=GetTypeInfo(name,exception);
11171 if (type_info == (TypeInfo *) NULL)
11172 {
11173 PUSHs(&sv_undef);
11174 continue;
11175 }
11176 if (type_info->name == (char *) NULL)
11177 PUSHs(&sv_undef);
11178 else
11179 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
11180 if (type_info->description == (char *) NULL)
11181 PUSHs(&sv_undef);
11182 else
11183 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
11184 if (type_info->family == (char *) NULL)
11185 PUSHs(&sv_undef);
11186 else
11187 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
11188 if (type_info->style == UndefinedStyle)
11189 PUSHs(&sv_undef);
11190 else
11191 PUSHs(sv_2mortal(newSVpv(MagickOptionToMnemonic(MagickStyleOptions,
11192 type_info->style),0)));
11193 if (type_info->stretch == UndefinedStretch)
11194 PUSHs(&sv_undef);
11195 else
11196 PUSHs(sv_2mortal(newSVpv(MagickOptionToMnemonic(MagickStretchOptions,
11197 type_info->stretch),0)));
11198 (void) FormatMagickString(message,MaxTextExtent,"%lu",type_info->weight);
11199 PUSHs(sv_2mortal(newSVpv(message,0)));
11200 if (type_info->encoding == (char *) NULL)
11201 PUSHs(&sv_undef);
11202 else
11203 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
11204 if (type_info->foundry == (char *) NULL)
11205 PUSHs(&sv_undef);
11206 else
11207 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
11208 if (type_info->format == (char *) NULL)
11209 PUSHs(&sv_undef);
11210 else
11211 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
11212 if (type_info->metrics == (char *) NULL)
11213 PUSHs(&sv_undef);
11214 else
11215 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
11216 if (type_info->glyphs == (char *) NULL)
11217 PUSHs(&sv_undef);
11218 else
11219 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
11220 }
11221
11222 PerlException:
11223 InheritPerlException(exception,perl_exception);
11224 exception=DestroyExceptionInfo(exception);
11225 SvREFCNT_dec(perl_exception);
11226 }
11227
11228#
11229###############################################################################
11230# #
11231# #
11232# #
11233# Q u e r y F o n t M e t r i c s #
11234# #
11235# #
11236# #
11237###############################################################################
11238#
11239#
11240void
11241QueryFontMetrics(ref,...)
11242 Image::Magick ref=NO_INIT
11243 ALIAS:
11244 queryfontmetrics = 1
11245 PPCODE:
11246 {
11247 AffineMatrix
11248 affine,
11249 current;
11250
11251 AV
11252 *av;
11253
11254 char
11255 *attribute;
11256
11257 double
11258 x,
11259 y;
11260
11261 DrawInfo
11262 *draw_info;
11263
11264 ExceptionInfo
11265 *exception;
11266
11267 GeometryInfo
11268 geometry_info;
11269
11270 Image
11271 *image;
11272
11273 long
11274 type;
11275
11276 MagickBooleanType
11277 status;
11278
11279 MagickStatusType
11280 flags;
11281
11282 register long
11283 i;
11284
11285 struct PackageInfo
11286 *info,
11287 *package_info;
11288
11289 SV
11290 *perl_exception,
11291 *reference; /* reference is the SV* of ref=SvIV(reference) */
11292
11293 TypeMetric
11294 metrics;
11295
11296 exception=AcquireExceptionInfo();
11297 package_info=(struct PackageInfo *) NULL;
11298 perl_exception=newSVpv("",0);
11299 reference=SvRV(ST(0));
11300 av=(AV *) reference;
11301 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11302 exception);
11303 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11304 if (image == (Image *) NULL)
11305 {
11306 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11307 PackageName);
11308 goto PerlException;
11309 }
11310 package_info=ClonePackageInfo(info,exception);
11311 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
11312 CloneString(&draw_info->text,"");
11313 current=draw_info->affine;
11314 GetAffineMatrix(&affine);
11315 x=0.0;
11316 y=0.0;
11317 EXTEND(sp,7*items);
11318 for (i=2; i < items; i+=2)
11319 {
11320 attribute=(char *) SvPV(ST(i-1),na);
11321 switch (*attribute)
11322 {
11323 case 'A':
11324 case 'a':
11325 {
11326 if (LocaleCompare(attribute,"antialias") == 0)
11327 {
11328 type=ParseMagickOption(MagickBooleanOptions,MagickFalse,
11329 SvPV(ST(i),na));
11330 if (type < 0)
11331 {
11332 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11333 SvPV(ST(i),na));
11334 break;
11335 }
11336 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
11337 break;
11338 }
11339 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11340 attribute);
11341 break;
11342 }
11343 case 'd':
11344 case 'D':
11345 {
11346 if (LocaleCompare(attribute,"density") == 0)
11347 {
11348 CloneString(&draw_info->density,SvPV(ST(i),na));
11349 break;
11350 }
11351 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11352 attribute);
11353 break;
11354 }
11355 case 'e':
11356 case 'E':
11357 {
11358 if (LocaleCompare(attribute,"encoding") == 0)
11359 {
11360 CloneString(&draw_info->encoding,SvPV(ST(i),na));
11361 break;
11362 }
11363 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11364 attribute);
11365 break;
11366 }
11367 case 'f':
11368 case 'F':
11369 {
11370 if (LocaleCompare(attribute,"family") == 0)
11371 {
11372 CloneString(&draw_info->family,SvPV(ST(i),na));
11373 break;
11374 }
11375 if (LocaleCompare(attribute,"fill") == 0)
11376 {
11377 if (info)
11378 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->fill,
11379 &image->exception);
11380 break;
11381 }
11382 if (LocaleCompare(attribute,"font") == 0)
11383 {
11384 CloneString(&draw_info->font,SvPV(ST(i),na));
11385 break;
11386 }
11387 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11388 attribute);
11389 break;
11390 }
11391 case 'g':
11392 case 'G':
11393 {
11394 if (LocaleCompare(attribute,"geometry") == 0)
11395 {
11396 CloneString(&draw_info->geometry,SvPV(ST(i),na));
11397 break;
11398 }
11399 if (LocaleCompare(attribute,"gravity") == 0)
11400 {
11401 draw_info->gravity=(GravityType) ParseMagickOption(
11402 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11403 break;
11404 }
11405 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11406 attribute);
11407 break;
11408 }
11409 case 'i':
11410 case 'I':
11411 {
cristyb32b90a2009-09-07 21:45:48 +000011412 if (LocaleCompare(attribute,"interline-spacing") == 0)
11413 {
11414 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11415 draw_info->interline_spacing=geometry_info.rho;
11416 break;
11417 }
cristy3ed852e2009-09-05 21:47:34 +000011418 if (LocaleCompare(attribute,"interword-spacing") == 0)
11419 {
11420 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11421 draw_info->interword_spacing=geometry_info.rho;
11422 break;
11423 }
11424 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11425 attribute);
11426 break;
11427 }
11428 case 'k':
11429 case 'K':
11430 {
11431 if (LocaleCompare(attribute,"kerning") == 0)
11432 {
11433 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11434 draw_info->kerning=geometry_info.rho;
11435 break;
11436 }
11437 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11438 attribute);
11439 break;
11440 }
11441 case 'p':
11442 case 'P':
11443 {
11444 if (LocaleCompare(attribute,"pointsize") == 0)
11445 {
11446 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11447 draw_info->pointsize=geometry_info.rho;
11448 break;
11449 }
11450 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11451 attribute);
11452 break;
11453 }
11454 case 'r':
11455 case 'R':
11456 {
11457 if (LocaleCompare(attribute,"rotate") == 0)
11458 {
11459 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11460 affine.rx=geometry_info.rho;
11461 affine.ry=geometry_info.sigma;
11462 if ((flags & SigmaValue) == 0)
11463 affine.ry=affine.rx;
11464 break;
11465 }
11466 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11467 attribute);
11468 break;
11469 }
11470 case 's':
11471 case 'S':
11472 {
11473 if (LocaleCompare(attribute,"scale") == 0)
11474 {
11475 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11476 affine.sx=geometry_info.rho;
11477 affine.sy=geometry_info.sigma;
11478 if ((flags & SigmaValue) == 0)
11479 affine.sy=affine.sx;
11480 break;
11481 }
11482 if (LocaleCompare(attribute,"skew") == 0)
11483 {
11484 double
11485 x_angle,
11486 y_angle;
11487
11488 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11489 x_angle=geometry_info.rho;
11490 y_angle=geometry_info.sigma;
11491 if ((flags & SigmaValue) == 0)
11492 y_angle=x_angle;
11493 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
11494 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
11495 break;
11496 }
11497 if (LocaleCompare(attribute,"stroke") == 0)
11498 {
11499 if (info)
11500 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->stroke,
11501 &image->exception);
11502 break;
11503 }
11504 if (LocaleCompare(attribute,"style") == 0)
11505 {
11506 type=ParseMagickOption(MagickStyleOptions,MagickFalse,
11507 SvPV(ST(i),na));
11508 if (type < 0)
11509 {
11510 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11511 SvPV(ST(i),na));
11512 break;
11513 }
11514 draw_info->style=(StyleType) type;
11515 break;
11516 }
11517 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11518 attribute);
11519 break;
11520 }
11521 case 't':
11522 case 'T':
11523 {
11524 if (LocaleCompare(attribute,"text") == 0)
11525 {
11526 CloneString(&draw_info->text,SvPV(ST(i),na));
11527 break;
11528 }
11529 if (LocaleCompare(attribute,"translate") == 0)
11530 {
11531 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11532 affine.tx=geometry_info.rho;
11533 affine.ty=geometry_info.sigma;
11534 if ((flags & SigmaValue) == 0)
11535 affine.ty=affine.tx;
11536 break;
11537 }
11538 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11539 attribute);
11540 break;
11541 }
11542 case 'w':
11543 case 'W':
11544 {
11545 if (LocaleCompare(attribute,"weight") == 0)
11546 {
11547 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11548 draw_info->weight=(unsigned long) geometry_info.rho;
11549 break;
11550 }
11551 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11552 attribute);
11553 break;
11554 }
11555 case 'x':
11556 case 'X':
11557 {
11558 if (LocaleCompare(attribute,"x") == 0)
11559 {
11560 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11561 x=geometry_info.rho;
11562 break;
11563 }
11564 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11565 attribute);
11566 break;
11567 }
11568 case 'y':
11569 case 'Y':
11570 {
11571 if (LocaleCompare(attribute,"y") == 0)
11572 {
11573 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11574 y=geometry_info.rho;
11575 break;
11576 }
11577 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11578 attribute);
11579 break;
11580 }
11581 default:
11582 {
11583 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11584 attribute);
11585 break;
11586 }
11587 }
11588 }
11589 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
11590 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
11591 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
11592 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
11593 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
11594 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
11595 if (draw_info->geometry == (char *) NULL)
11596 {
11597 draw_info->geometry=AcquireString((char *) NULL);
11598 (void) FormatMagickString(draw_info->geometry,MaxTextExtent,"%g,%g",
11599 x,y);
11600 }
11601 status=GetTypeMetrics(image,draw_info,&metrics);
11602 (void) CatchImageException(image);
11603 if (status == MagickFalse)
11604 PUSHs(&sv_undef);
11605 else
11606 {
11607 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
11608 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
11609 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
11610 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
11611 PUSHs(sv_2mortal(newSVnv(metrics.width)));
11612 PUSHs(sv_2mortal(newSVnv(metrics.height)));
11613 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
11614 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
11615 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
11616 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
11617 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
11618 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
11619 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
11620 }
11621 draw_info=DestroyDrawInfo(draw_info);
11622
11623 PerlException:
11624 if (package_info != (struct PackageInfo *) NULL)
11625 DestroyPackageInfo(package_info);
11626 InheritPerlException(exception,perl_exception);
11627 exception=DestroyExceptionInfo(exception);
11628 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11629 }
11630
11631#
11632###############################################################################
11633# #
11634# #
11635# #
11636# 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 #
11637# #
11638# #
11639# #
11640###############################################################################
11641#
11642#
11643void
11644QueryMultilineFontMetrics(ref,...)
11645 Image::Magick ref=NO_INIT
11646 ALIAS:
11647 querymultilinefontmetrics = 1
11648 PPCODE:
11649 {
11650 AffineMatrix
11651 affine,
11652 current;
11653
11654 AV
11655 *av;
11656
11657 char
11658 *attribute;
11659
11660 double
11661 x,
11662 y;
11663
11664 DrawInfo
11665 *draw_info;
11666
11667 ExceptionInfo
11668 *exception;
11669
11670 GeometryInfo
11671 geometry_info;
11672
11673 Image
11674 *image;
11675
11676 long
11677 type;
11678
11679 MagickBooleanType
11680 status;
11681
11682 MagickStatusType
11683 flags;
11684
11685 register long
11686 i;
11687
11688 struct PackageInfo
11689 *info,
11690 *package_info;
11691
11692 SV
11693 *perl_exception,
11694 *reference; /* reference is the SV* of ref=SvIV(reference) */
11695
11696 TypeMetric
11697 metrics;
11698
11699 exception=AcquireExceptionInfo();
11700 package_info=(struct PackageInfo *) NULL;
11701 perl_exception=newSVpv("",0);
11702 reference=SvRV(ST(0));
11703 av=(AV *) reference;
11704 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11705 exception);
11706 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11707 if (image == (Image *) NULL)
11708 {
11709 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11710 PackageName);
11711 goto PerlException;
11712 }
11713 package_info=ClonePackageInfo(info,exception);
11714 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
11715 CloneString(&draw_info->text,"");
11716 current=draw_info->affine;
11717 GetAffineMatrix(&affine);
11718 x=0.0;
11719 y=0.0;
11720 EXTEND(sp,7*items);
11721 for (i=2; i < items; i+=2)
11722 {
11723 attribute=(char *) SvPV(ST(i-1),na);
11724 switch (*attribute)
11725 {
11726 case 'A':
11727 case 'a':
11728 {
11729 if (LocaleCompare(attribute,"antialias") == 0)
11730 {
11731 type=ParseMagickOption(MagickBooleanOptions,MagickFalse,
11732 SvPV(ST(i),na));
11733 if (type < 0)
11734 {
11735 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11736 SvPV(ST(i),na));
11737 break;
11738 }
11739 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
11740 break;
11741 }
11742 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11743 attribute);
11744 break;
11745 }
11746 case 'd':
11747 case 'D':
11748 {
11749 if (LocaleCompare(attribute,"density") == 0)
11750 {
11751 CloneString(&draw_info->density,SvPV(ST(i),na));
11752 break;
11753 }
11754 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11755 attribute);
11756 break;
11757 }
11758 case 'e':
11759 case 'E':
11760 {
11761 if (LocaleCompare(attribute,"encoding") == 0)
11762 {
11763 CloneString(&draw_info->encoding,SvPV(ST(i),na));
11764 break;
11765 }
11766 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11767 attribute);
11768 break;
11769 }
11770 case 'f':
11771 case 'F':
11772 {
11773 if (LocaleCompare(attribute,"family") == 0)
11774 {
11775 CloneString(&draw_info->family,SvPV(ST(i),na));
11776 break;
11777 }
11778 if (LocaleCompare(attribute,"fill") == 0)
11779 {
11780 if (info)
11781 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->fill,
11782 &image->exception);
11783 break;
11784 }
11785 if (LocaleCompare(attribute,"font") == 0)
11786 {
11787 CloneString(&draw_info->font,SvPV(ST(i),na));
11788 break;
11789 }
11790 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11791 attribute);
11792 break;
11793 }
11794 case 'g':
11795 case 'G':
11796 {
11797 if (LocaleCompare(attribute,"geometry") == 0)
11798 {
11799 CloneString(&draw_info->geometry,SvPV(ST(i),na));
11800 break;
11801 }
11802 if (LocaleCompare(attribute,"gravity") == 0)
11803 {
11804 draw_info->gravity=(GravityType) ParseMagickOption(
11805 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11806 break;
11807 }
11808 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11809 attribute);
11810 break;
11811 }
11812 case 'p':
11813 case 'P':
11814 {
11815 if (LocaleCompare(attribute,"pointsize") == 0)
11816 {
11817 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11818 draw_info->pointsize=geometry_info.rho;
11819 break;
11820 }
11821 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11822 attribute);
11823 break;
11824 }
11825 case 'r':
11826 case 'R':
11827 {
11828 if (LocaleCompare(attribute,"rotate") == 0)
11829 {
11830 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11831 affine.rx=geometry_info.rho;
11832 affine.ry=geometry_info.sigma;
11833 if ((flags & SigmaValue) == 0)
11834 affine.ry=affine.rx;
11835 break;
11836 }
11837 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11838 attribute);
11839 break;
11840 }
11841 case 's':
11842 case 'S':
11843 {
11844 if (LocaleCompare(attribute,"scale") == 0)
11845 {
11846 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11847 affine.sx=geometry_info.rho;
11848 affine.sy=geometry_info.sigma;
11849 if ((flags & SigmaValue) == 0)
11850 affine.sy=affine.sx;
11851 break;
11852 }
11853 if (LocaleCompare(attribute,"skew") == 0)
11854 {
11855 double
11856 x_angle,
11857 y_angle;
11858
11859 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11860 x_angle=geometry_info.rho;
11861 y_angle=geometry_info.sigma;
11862 if ((flags & SigmaValue) == 0)
11863 y_angle=x_angle;
11864 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
11865 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
11866 break;
11867 }
11868 if (LocaleCompare(attribute,"stroke") == 0)
11869 {
11870 if (info)
11871 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->stroke,
11872 &image->exception);
11873 break;
11874 }
11875 if (LocaleCompare(attribute,"style") == 0)
11876 {
11877 type=ParseMagickOption(MagickStyleOptions,MagickFalse,
11878 SvPV(ST(i),na));
11879 if (type < 0)
11880 {
11881 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11882 SvPV(ST(i),na));
11883 break;
11884 }
11885 draw_info->style=(StyleType) type;
11886 break;
11887 }
11888 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11889 attribute);
11890 break;
11891 }
11892 case 't':
11893 case 'T':
11894 {
11895 if (LocaleCompare(attribute,"text") == 0)
11896 {
11897 CloneString(&draw_info->text,SvPV(ST(i),na));
11898 break;
11899 }
11900 if (LocaleCompare(attribute,"translate") == 0)
11901 {
11902 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11903 affine.tx=geometry_info.rho;
11904 affine.ty=geometry_info.sigma;
11905 if ((flags & SigmaValue) == 0)
11906 affine.ty=affine.tx;
11907 break;
11908 }
11909 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11910 attribute);
11911 break;
11912 }
11913 case 'w':
11914 case 'W':
11915 {
11916 if (LocaleCompare(attribute,"weight") == 0)
11917 {
11918 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11919 draw_info->weight=(unsigned long) geometry_info.rho;
11920 break;
11921 }
11922 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11923 attribute);
11924 break;
11925 }
11926 case 'x':
11927 case 'X':
11928 {
11929 if (LocaleCompare(attribute,"x") == 0)
11930 {
11931 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11932 x=geometry_info.rho;
11933 break;
11934 }
11935 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11936 attribute);
11937 break;
11938 }
11939 case 'y':
11940 case 'Y':
11941 {
11942 if (LocaleCompare(attribute,"y") == 0)
11943 {
11944 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11945 y=geometry_info.rho;
11946 break;
11947 }
11948 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11949 attribute);
11950 break;
11951 }
11952 default:
11953 {
11954 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11955 attribute);
11956 break;
11957 }
11958 }
11959 }
11960 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
11961 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
11962 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
11963 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
11964 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
11965 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
11966 if (draw_info->geometry == (char *) NULL)
11967 {
11968 draw_info->geometry=AcquireString((char *) NULL);
11969 (void) FormatMagickString(draw_info->geometry,MaxTextExtent,"%g,%g",
11970 x,y);
11971 }
11972 status=GetMultilineTypeMetrics(image,draw_info,&metrics);
11973 (void) CatchImageException(image);
11974 if (status == MagickFalse)
11975 PUSHs(&sv_undef);
11976 else
11977 {
11978 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
11979 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
11980 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
11981 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
11982 PUSHs(sv_2mortal(newSVnv(metrics.width)));
11983 PUSHs(sv_2mortal(newSVnv(metrics.height)));
11984 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
11985 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
11986 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
11987 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
11988 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
11989 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
11990 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
11991 }
11992 draw_info=DestroyDrawInfo(draw_info);
11993
11994 PerlException:
11995 if (package_info != (struct PackageInfo *) NULL)
11996 DestroyPackageInfo(package_info);
11997 InheritPerlException(exception,perl_exception);
11998 exception=DestroyExceptionInfo(exception);
11999 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12000 }
12001
12002#
12003###############################################################################
12004# #
12005# #
12006# #
12007# Q u e r y F o r m a t #
12008# #
12009# #
12010# #
12011###############################################################################
12012#
12013#
12014void
12015QueryFormat(ref,...)
12016 Image::Magick ref=NO_INIT
12017 ALIAS:
12018 queryformat = 1
12019 PPCODE:
12020 {
12021 char
12022 *name;
12023
12024 ExceptionInfo
12025 *exception;
12026
12027 register long
12028 i;
12029
12030 SV
12031 *perl_exception;
12032
12033 volatile const MagickInfo
12034 *magick_info;
12035
12036 exception=AcquireExceptionInfo();
12037 perl_exception=newSVpv("",0);
12038 if (items == 1)
12039 {
12040 char
12041 format[MaxTextExtent];
12042
12043 const MagickInfo
12044 **format_list;
12045
12046 unsigned long
12047 types;
12048
12049 format_list=GetMagickInfoList("*",&types,exception);
12050 EXTEND(sp,types);
12051 for (i=0; i < (long) types; i++)
12052 {
12053 (void) CopyMagickString(format,format_list[i]->name,MaxTextExtent);
12054 LocaleLower(format);
12055 PUSHs(sv_2mortal(newSVpv(format,0)));
12056 }
12057 format_list=(const MagickInfo **)
12058 RelinquishMagickMemory((MagickInfo *) format_list);
12059 goto PerlException;
12060 }
12061 EXTEND(sp,8*items);
12062 for (i=1; i < items; i++)
12063 {
12064 name=(char *) SvPV(ST(i),na);
12065 magick_info=GetMagickInfo(name,exception);
12066 if (magick_info == (const MagickInfo *) NULL)
12067 {
12068 PUSHs(&sv_undef);
12069 continue;
12070 }
12071 PUSHs(sv_2mortal(newSViv(magick_info->adjoin)));
12072 PUSHs(sv_2mortal(newSViv(magick_info->blob_support)));
12073 PUSHs(sv_2mortal(newSViv(magick_info->raw)));
12074 PUSHs(sv_2mortal(newSViv((long) magick_info->decoder)));
12075 PUSHs(sv_2mortal(newSViv((long) magick_info->encoder)));
12076 if (magick_info->description == (char *) NULL)
12077 PUSHs(&sv_undef);
12078 else
12079 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
12080 if (magick_info->module == (char *) NULL)
12081 PUSHs(&sv_undef);
12082 else
12083 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
12084 }
12085
12086 PerlException:
12087 InheritPerlException(exception,perl_exception);
12088 exception=DestroyExceptionInfo(exception);
12089 SvREFCNT_dec(perl_exception);
12090 }
12091
12092#
12093###############################################################################
12094# #
12095# #
12096# #
12097# Q u e r y O p t i o n #
12098# #
12099# #
12100# #
12101###############################################################################
12102#
12103#
12104void
12105QueryOption(ref,...)
12106 Image::Magick ref=NO_INIT
12107 ALIAS:
12108 queryoption = 1
12109 PPCODE:
12110 {
12111 char
12112 **options;
12113
12114 ExceptionInfo
12115 *exception;
12116
12117 long
12118 j,
12119 option;
12120
12121 register long
12122 i;
12123
12124 SV
12125 *perl_exception;
12126
12127 exception=AcquireExceptionInfo();
12128 perl_exception=newSVpv("",0);
12129 EXTEND(sp,8*items);
12130 for (i=1; i < items; i++)
12131 {
12132 option=ParseMagickOption(MagickListOptions,MagickFalse,(char *)
12133 SvPV(ST(i),na));
12134 options=GetMagickOptions((MagickOption) option);
12135 if (options == (char **) NULL)
12136 PUSHs(&sv_undef);
12137 else
12138 {
12139 for (j=0; options[j] != (char *) NULL; j++)
12140 PUSHs(sv_2mortal(newSVpv(options[j],0)));
12141 options=DestroyStringList(options);
12142 }
12143 }
12144
12145 PerlException:
12146 InheritPerlException(exception,perl_exception);
12147 exception=DestroyExceptionInfo(exception);
12148 SvREFCNT_dec(perl_exception);
12149 }
12150
12151#
12152###############################################################################
12153# #
12154# #
12155# #
12156# R e a d #
12157# #
12158# #
12159# #
12160###############################################################################
12161#
12162#
12163void
12164Read(ref,...)
12165 Image::Magick ref=NO_INIT
12166 ALIAS:
12167 ReadImage = 1
12168 read = 2
12169 readimage = 3
12170 PPCODE:
12171 {
12172 AV
12173 *av;
12174
12175 char
12176 **keep,
12177 **list;
12178
12179 ExceptionInfo
12180 *exception;
12181
12182 HV
12183 *hv;
12184
12185 Image
12186 *image;
12187
12188 int
12189 n;
12190
12191 long
12192 ac,
12193 number_images;
12194
12195 MagickBooleanType
12196 status;
12197
12198 register char
12199 **p;
12200
12201 register long
12202 i;
12203
12204 STRLEN
12205 *length;
12206
12207 struct PackageInfo
12208 *info,
12209 *package_info;
12210
12211 SV
12212 *perl_exception, /* Perl variable for storing messages */
12213 *reference,
12214 *rv,
12215 *sv;
12216
12217 exception=AcquireExceptionInfo();
12218 perl_exception=newSVpv("",0);
12219 package_info=(struct PackageInfo *) NULL;
12220 number_images=0;
12221 ac=(items < 2) ? 1 : items-1;
12222 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12223 keep=list;
12224 length=(STRLEN *) NULL;
12225 if (list == (char **) NULL)
12226 {
12227 ThrowPerlException(exception,ResourceLimitError,
12228 "MemoryAllocationFailed",PackageName);
12229 goto PerlException;
12230 }
12231 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12232 if (length == (STRLEN *) NULL)
12233 {
12234 ThrowPerlException(exception,ResourceLimitError,
12235 "MemoryAllocationFailed",PackageName);
12236 goto PerlException;
12237 }
12238 if (sv_isobject(ST(0)) == 0)
12239 {
12240 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12241 PackageName);
12242 goto PerlException;
12243 }
12244 reference=SvRV(ST(0));
12245 hv=SvSTASH(reference);
12246 if (SvTYPE(reference) != SVt_PVAV)
12247 {
12248 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12249 PackageName);
12250 goto PerlException;
12251 }
12252 av=(AV *) reference;
12253 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12254 exception);
12255 package_info=ClonePackageInfo(info,exception);
12256 n=1;
12257 if (items <= 1)
12258 *list=(char *) (*package_info->image_info->filename ?
12259 package_info->image_info->filename : "XC:black");
12260 else
12261 for (n=0, i=0; i < ac; i++)
12262 {
12263 list[n]=(char *) SvPV(ST(i+1),length[n]);
12264 if ((items >= 3) && strEQcase(list[n],"blob"))
12265 {
12266 void
12267 *blob;
12268
12269 i++;
12270 blob=(void *) (SvPV(ST(i+1),length[n]));
12271 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12272 }
12273 if ((items >= 3) && strEQcase(list[n],"filename"))
12274 continue;
12275 if ((items >= 3) && strEQcase(list[n],"file"))
12276 {
12277 FILE
12278 *file;
12279
12280 PerlIO
12281 *io_info;
12282
12283 i++;
12284 io_info=IoIFP(sv_2io(ST(i+1)));
12285 if (io_info == (PerlIO *) NULL)
12286 {
12287 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12288 PackageName);
12289 continue;
12290 }
12291 file=PerlIO_findFILE(io_info);
12292 if (file == (FILE *) NULL)
12293 {
12294 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12295 PackageName);
12296 continue;
12297 }
12298 SetImageInfoFile(package_info->image_info,file);
12299 }
12300 if ((items >= 3) && strEQcase(list[n],"magick"))
12301 continue;
12302 n++;
12303 }
12304 list[n]=(char *) NULL;
12305 keep=list;
12306 status=ExpandFilenames(&n,&list);
12307 if (status == MagickFalse)
12308 {
12309 ThrowPerlException(exception,ResourceLimitError,
12310 "MemoryAllocationFailed",PackageName);
12311 goto PerlException;
12312 }
12313 number_images=0;
12314 for (i=0; i < n; i++)
12315 {
12316 if ((package_info->image_info->file != (FILE *) NULL) ||
12317 (package_info->image_info->blob != (void *) NULL))
12318 {
12319 image=ReadImages(package_info->image_info,exception);
12320 if (image != (Image *) NULL)
12321 DisassociateImageStream(image);
12322 }
12323 else
12324 {
12325 (void) CopyMagickString(package_info->image_info->filename,list[i],
12326 MaxTextExtent);
12327 image=ReadImages(package_info->image_info,exception);
12328 }
12329 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
12330 break;
12331 for ( ; image; image=image->next)
12332 {
12333 AddImageToRegistry(image);
12334 rv=newRV(sv);
12335 av_push(av,sv_bless(rv,hv));
12336 SvREFCNT_dec(sv);
12337 number_images++;
12338 }
12339 }
12340 /*
12341 Free resources.
12342 */
12343 for (i=0; i < n; i++)
12344 if (list[i] != (char *) NULL)
12345 for (p=keep; list[i] != *p++; )
12346 if (*p == (char *) NULL)
12347 {
12348 list[i]=(char *) RelinquishMagickMemory(list[i]);
12349 break;
12350 }
12351
12352 PerlException:
12353 if (package_info != (struct PackageInfo *) NULL)
12354 DestroyPackageInfo(package_info);
12355 if (list && (list != keep))
12356 list=(char **) RelinquishMagickMemory(list);
12357 if (keep)
12358 keep=(char **) RelinquishMagickMemory(keep);
12359 if (length)
12360 length=(STRLEN *) RelinquishMagickMemory(length);
12361 InheritPerlException(exception,perl_exception);
12362 exception=DestroyExceptionInfo(exception);
12363 sv_setiv(perl_exception,(IV) number_images);
12364 SvPOK_on(perl_exception);
12365 ST(0)=sv_2mortal(perl_exception);
12366 XSRETURN(1);
12367 }
12368
12369#
12370###############################################################################
12371# #
12372# #
12373# #
12374# R e m o t e #
12375# #
12376# #
12377# #
12378###############################################################################
12379#
12380#
12381void
12382Remote(ref,...)
12383 Image::Magick ref=NO_INIT
12384 ALIAS:
12385 RemoteCommand = 1
12386 remote = 2
12387 remoteCommand = 3
12388 PPCODE:
12389 {
12390 AV
12391 *av;
12392
12393 ExceptionInfo
12394 *exception;
12395
12396 register long
12397 i;
12398
12399 SV
12400 *perl_exception,
12401 *reference;
12402
12403 struct PackageInfo
12404 *info;
12405
12406 exception=AcquireExceptionInfo();
12407 perl_exception=newSVpv("",0);
12408 reference=SvRV(ST(0));
12409 av=(AV *) reference;
12410 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12411 exception);
12412 for (i=1; i < items; i++)
12413 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
12414 SvPV(ST(i),na),exception);
12415 InheritPerlException(exception,perl_exception);
12416 exception=DestroyExceptionInfo(exception);
12417 SvREFCNT_dec(perl_exception); /* throw away all errors */
12418 }
12419
12420#
12421###############################################################################
12422# #
12423# #
12424# #
12425# S e t #
12426# #
12427# #
12428# #
12429###############################################################################
12430#
12431#
12432void
12433Set(ref,...)
12434 Image::Magick ref=NO_INIT
12435 ALIAS:
12436 SetAttributes = 1
12437 SetAttribute = 2
12438 set = 3
12439 setattributes = 4
12440 setattribute = 5
12441 PPCODE:
12442 {
12443 ExceptionInfo
12444 *exception;
12445
12446 Image
12447 *image;
12448
12449 register long
12450 i;
12451
12452 struct PackageInfo
12453 *info;
12454
12455 SV
12456 *perl_exception,
12457 *reference; /* reference is the SV* of ref=SvIV(reference) */
12458
12459 exception=AcquireExceptionInfo();
12460 perl_exception=newSVpv("",0);
12461 if (sv_isobject(ST(0)) == 0)
12462 {
12463 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12464 PackageName);
12465 goto PerlException;
12466 }
12467 reference=SvRV(ST(0));
12468 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12469 if (items == 2)
12470 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
12471 else
12472 for (i=2; i < items; i+=2)
12473 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
12474
12475 PerlException:
12476 InheritPerlException(exception,perl_exception);
12477 exception=DestroyExceptionInfo(exception);
12478 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
12479 SvPOK_on(perl_exception);
12480 ST(0)=sv_2mortal(perl_exception);
12481 XSRETURN(1);
12482 }
12483
12484#
12485###############################################################################
12486# #
12487# #
12488# #
12489# S e t P i x e l #
12490# #
12491# #
12492# #
12493###############################################################################
12494#
12495#
12496void
12497SetPixel(ref,...)
12498 Image::Magick ref=NO_INIT
12499 ALIAS:
12500 setpixel = 1
12501 setPixel = 2
12502 PPCODE:
12503 {
12504 AV
12505 *av;
12506
12507 char
12508 *attribute;
12509
12510 ChannelType
12511 channel;
12512
12513 ExceptionInfo
12514 *exception;
12515
12516 Image
12517 *image;
12518
12519 long
12520 option;
12521
12522 MagickBooleanType
12523 normalize;
12524
12525 RectangleInfo
12526 region;
12527
12528 register IndexPacket
12529 *indexes;
12530
12531 register long
12532 i;
12533
12534 register PixelPacket
12535 *q;
12536
12537 struct PackageInfo
12538 *info;
12539
12540 SV
12541 *perl_exception,
12542 *reference; /* reference is the SV* of ref=SvIV(reference) */
12543
12544 exception=AcquireExceptionInfo();
12545 perl_exception=newSVpv("",0);
12546 reference=SvRV(ST(0));
12547 av=(AV *) reference;
12548 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12549 exception);
12550 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12551 if (image == (Image *) NULL)
12552 {
12553 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12554 PackageName);
12555 goto PerlException;
12556 }
12557 av=(AV *) NULL;
12558 channel=DefaultChannels;
12559 normalize=MagickTrue;
12560 region.x=0;
12561 region.y=0;
12562 region.width=image->columns;
12563 region.height=1;
12564 if (items == 1)
12565 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
12566 for (i=2; i < items; i+=2)
12567 {
12568 attribute=(char *) SvPV(ST(i-1),na);
12569 switch (*attribute)
12570 {
12571 case 'C':
12572 case 'c':
12573 {
12574 if (LocaleCompare(attribute,"channel") == 0)
12575 {
12576 long
12577 option;
12578
12579 option=ParseChannelOption(SvPV(ST(i),na));
12580 if (option < 0)
12581 {
12582 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12583 SvPV(ST(i),na));
12584 return;
12585 }
12586 channel=(ChannelType) option;
12587 break;
12588 }
12589 if (LocaleCompare(attribute,"color") == 0)
12590 {
12591 if (SvTYPE(ST(i)) != SVt_RV)
12592 {
12593 char
12594 message[MaxTextExtent];
12595
12596 (void) FormatMagickString(message,MaxTextExtent,
12597 "invalid %.60s value",attribute);
12598 ThrowPerlException(exception,OptionError,message,
12599 SvPV(ST(i),na));
12600 }
12601 av=(AV *) SvRV(ST(i));
12602 break;
12603 }
12604 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12605 attribute);
12606 break;
12607 }
12608 case 'g':
12609 case 'G':
12610 {
12611 if (LocaleCompare(attribute,"geometry") == 0)
12612 {
12613 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
12614 break;
12615 }
12616 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12617 attribute);
12618 break;
12619 }
12620 case 'N':
12621 case 'n':
12622 {
12623 if (LocaleCompare(attribute,"normalize") == 0)
12624 {
12625 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
12626 SvPV(ST(i),na));
12627 if (option < 0)
12628 {
12629 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12630 SvPV(ST(i),na));
12631 break;
12632 }
12633 normalize=option != 0 ? MagickTrue : MagickFalse;
12634 break;
12635 }
12636 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12637 attribute);
12638 break;
12639 }
12640 case 'x':
12641 case 'X':
12642 {
12643 if (LocaleCompare(attribute,"x") == 0)
12644 {
12645 region.x=SvIV(ST(i));
12646 break;
12647 }
12648 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12649 attribute);
12650 break;
12651 }
12652 case 'y':
12653 case 'Y':
12654 {
12655 if (LocaleCompare(attribute,"y") == 0)
12656 {
12657 region.y=SvIV(ST(i));
12658 break;
12659 }
12660 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12661 attribute);
12662 break;
12663 }
12664 default:
12665 {
12666 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12667 attribute);
12668 break;
12669 }
12670 }
12671 }
12672 (void) SetImageStorageClass(image,DirectClass);
12673 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
12674 if ((q == (PixelPacket *) NULL) || (av == (AV *) NULL))
12675 PUSHs(&sv_undef);
12676 else
12677 {
12678 double
12679 scale;
12680
12681 register long
12682 i;
12683
12684 i=0;
12685 indexes=GetAuthenticIndexQueue(image);
12686 scale=1.0;
12687 if (normalize != MagickFalse)
12688 scale=QuantumRange;
12689 if (((channel & RedChannel) != 0) && (i <= av_len(av)))
12690 {
12691 q->red=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12692 i++;
12693 }
12694 if (((channel & GreenChannel) != 0) && (i <= av_len(av)))
12695 {
12696 q->green=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12697 i++;
12698 }
12699 if (((channel & BlueChannel) != 0) && (i <= av_len(av)))
12700 {
12701 q->blue=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12702 i++;
12703 }
12704 if ((((channel & IndexChannel) != 0) &&
12705 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
12706 {
12707 *indexes=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12708 i++;
12709 }
12710 if (((channel & OpacityChannel) != 0) && (i <= av_len(av)))
12711 {
12712 q->opacity=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12713 i++;
12714 }
12715 (void) SyncAuthenticPixels(image,exception);
12716 }
12717
12718 PerlException:
12719 InheritPerlException(exception,perl_exception);
12720 exception=DestroyExceptionInfo(exception);
12721 SvREFCNT_dec(perl_exception);
12722 }
12723
12724#
12725###############################################################################
12726# #
12727# #
12728# #
12729# S t a t i s t i c s #
12730# #
12731# #
12732# #
12733###############################################################################
12734#
12735#
12736void
12737Statistics(ref,...)
12738 Image::Magick ref=NO_INIT
12739 ALIAS:
12740 StatisticsImage = 1
12741 statistics = 2
12742 statisticsimage = 3
12743 PPCODE:
12744 {
12745 AV
12746 *av;
12747
12748 char
12749 message[MaxTextExtent];
12750
12751 ChannelStatistics
12752 *channel_statistics;
12753
12754 double
12755 scale;
12756
12757 ExceptionInfo
12758 *exception;
12759
12760 HV
12761 *hv;
12762
12763 Image
12764 *image;
12765
12766 ssize_t
12767 count;
12768
12769 struct PackageInfo
12770 *info;
12771
12772 SV
12773 *av_reference,
12774 *perl_exception,
12775 *reference;
12776
12777 exception=AcquireExceptionInfo();
12778 perl_exception=newSVpv("",0);
12779 av=NULL;
12780 if (sv_isobject(ST(0)) == 0)
12781 {
12782 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12783 PackageName);
12784 goto PerlException;
12785 }
12786 reference=SvRV(ST(0));
12787 hv=SvSTASH(reference);
12788 av=newAV();
12789 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12790 SvREFCNT_dec(av);
12791 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12792 if (image == (Image *) NULL)
12793 {
12794 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12795 PackageName);
12796 goto PerlException;
12797 }
12798 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12799 count=0;
12800 for ( ; image; image=image->next)
12801 {
12802 channel_statistics=GetImageChannelStatistics(image,&image->exception);
12803 if (channel_statistics == (ChannelStatistics *) NULL)
12804 continue;
12805 count++;
12806 EXTEND(sp,25*count);
12807 scale=(double) QuantumRange;
12808 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12809 channel_statistics[RedChannel].depth);
12810 PUSHs(sv_2mortal(newSVpv(message,0)));
12811 (void) FormatMagickString(message,MaxTextExtent,"%g",
12812 channel_statistics[RedChannel].minima/scale);
12813 PUSHs(sv_2mortal(newSVpv(message,0)));
12814 (void) FormatMagickString(message,MaxTextExtent,"%g",
12815 channel_statistics[RedChannel].maxima/scale);
12816 PUSHs(sv_2mortal(newSVpv(message,0)));
12817 (void) FormatMagickString(message,MaxTextExtent,"%g",
12818 channel_statistics[RedChannel].mean/scale);
12819 PUSHs(sv_2mortal(newSVpv(message,0)));
12820 (void) FormatMagickString(message,MaxTextExtent,"%g",
12821 channel_statistics[RedChannel].standard_deviation/scale);
12822 PUSHs(sv_2mortal(newSVpv(message,0)));
12823 (void) FormatMagickString(message,MaxTextExtent,"%g",
12824 channel_statistics[RedChannel].kurtosis);
12825 PUSHs(sv_2mortal(newSVpv(message,0)));
12826 (void) FormatMagickString(message,MaxTextExtent,"%g",
12827 channel_statistics[RedChannel].skewness);
12828 PUSHs(sv_2mortal(newSVpv(message,0)));
12829 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12830 channel_statistics[GreenChannel].depth);
12831 PUSHs(sv_2mortal(newSVpv(message,0)));
12832 (void) FormatMagickString(message,MaxTextExtent,"%g",
12833 channel_statistics[GreenChannel].minima/scale);
12834 PUSHs(sv_2mortal(newSVpv(message,0)));
12835 (void) FormatMagickString(message,MaxTextExtent,"%g",
12836 channel_statistics[GreenChannel].maxima/scale);
12837 PUSHs(sv_2mortal(newSVpv(message,0)));
12838 (void) FormatMagickString(message,MaxTextExtent,"%g",
12839 channel_statistics[GreenChannel].mean/scale);
12840 PUSHs(sv_2mortal(newSVpv(message,0)));
12841 (void) FormatMagickString(message,MaxTextExtent,"%g",
12842 channel_statistics[GreenChannel].standard_deviation/scale);
12843 PUSHs(sv_2mortal(newSVpv(message,0)));
12844 (void) FormatMagickString(message,MaxTextExtent,"%g",
12845 channel_statistics[GreenChannel].kurtosis);
12846 PUSHs(sv_2mortal(newSVpv(message,0)));
12847 (void) FormatMagickString(message,MaxTextExtent,"%g",
12848 channel_statistics[GreenChannel].skewness);
12849 PUSHs(sv_2mortal(newSVpv(message,0)));
12850 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12851 channel_statistics[BlueChannel].depth);
12852 PUSHs(sv_2mortal(newSVpv(message,0)));
12853 (void) FormatMagickString(message,MaxTextExtent,"%g",
12854 channel_statistics[BlueChannel].minima/scale);
12855 PUSHs(sv_2mortal(newSVpv(message,0)));
12856 (void) FormatMagickString(message,MaxTextExtent,"%g",
12857 channel_statistics[BlueChannel].maxima/scale);
12858 PUSHs(sv_2mortal(newSVpv(message,0)));
12859 (void) FormatMagickString(message,MaxTextExtent,"%g",
12860 channel_statistics[BlueChannel].mean/scale);
12861 PUSHs(sv_2mortal(newSVpv(message,0)));
12862 (void) FormatMagickString(message,MaxTextExtent,"%g",
12863 channel_statistics[BlueChannel].standard_deviation/scale);
12864 PUSHs(sv_2mortal(newSVpv(message,0)));
12865 (void) FormatMagickString(message,MaxTextExtent,"%g",
12866 channel_statistics[BlueChannel].kurtosis);
12867 PUSHs(sv_2mortal(newSVpv(message,0)));
12868 (void) FormatMagickString(message,MaxTextExtent,"%g",
12869 channel_statistics[BlueChannel].skewness);
12870 PUSHs(sv_2mortal(newSVpv(message,0)));
12871 if (image->colorspace == CMYKColorspace)
12872 {
12873 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12874 channel_statistics[BlackChannel].depth);
12875 PUSHs(sv_2mortal(newSVpv(message,0)));
12876 (void) FormatMagickString(message,MaxTextExtent,"%g",
12877 channel_statistics[BlackChannel].minima/scale);
12878 PUSHs(sv_2mortal(newSVpv(message,0)));
12879 (void) FormatMagickString(message,MaxTextExtent,"%g",
12880 channel_statistics[BlackChannel].maxima/scale);
12881 PUSHs(sv_2mortal(newSVpv(message,0)));
12882 (void) FormatMagickString(message,MaxTextExtent,"%g",
12883 channel_statistics[BlackChannel].mean/scale);
12884 PUSHs(sv_2mortal(newSVpv(message,0)));
12885 (void) FormatMagickString(message,MaxTextExtent,"%g",
12886 channel_statistics[BlackChannel].standard_deviation/scale);
12887 PUSHs(sv_2mortal(newSVpv(message,0)));
12888 (void) FormatMagickString(message,MaxTextExtent,"%g",
12889 channel_statistics[BlackChannel].kurtosis);
12890 PUSHs(sv_2mortal(newSVpv(message,0)));
12891 (void) FormatMagickString(message,MaxTextExtent,"%g",
12892 channel_statistics[BlackChannel].skewness);
12893 PUSHs(sv_2mortal(newSVpv(message,0)));
12894 }
12895 if (image->matte != MagickFalse)
12896 {
12897 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12898 channel_statistics[OpacityChannel].depth);
12899 PUSHs(sv_2mortal(newSVpv(message,0)));
12900 (void) FormatMagickString(message,MaxTextExtent,"%g",
12901 channel_statistics[OpacityChannel].minima/scale);
12902 PUSHs(sv_2mortal(newSVpv(message,0)));
12903 (void) FormatMagickString(message,MaxTextExtent,"%g",
12904 channel_statistics[OpacityChannel].maxima/scale);
12905 PUSHs(sv_2mortal(newSVpv(message,0)));
12906 (void) FormatMagickString(message,MaxTextExtent,"%g",
12907 channel_statistics[OpacityChannel].mean/scale);
12908 PUSHs(sv_2mortal(newSVpv(message,0)));
12909 (void) FormatMagickString(message,MaxTextExtent,"%g",
12910 channel_statistics[OpacityChannel].standard_deviation/scale);
12911 PUSHs(sv_2mortal(newSVpv(message,0)));
12912 (void) FormatMagickString(message,MaxTextExtent,"%g",
12913 channel_statistics[OpacityChannel].kurtosis);
12914 PUSHs(sv_2mortal(newSVpv(message,0)));
12915 (void) FormatMagickString(message,MaxTextExtent,"%g",
12916 channel_statistics[OpacityChannel].skewness);
12917 PUSHs(sv_2mortal(newSVpv(message,0)));
12918 }
12919 channel_statistics=(ChannelStatistics *)
12920 RelinquishMagickMemory(channel_statistics);
12921 }
12922
12923 PerlException:
12924 InheritPerlException(exception,perl_exception);
12925 exception=DestroyExceptionInfo(exception);
12926 SvREFCNT_dec(perl_exception);
12927 }
12928
12929#
12930###############################################################################
12931# #
12932# #
12933# #
12934# S y n c A u t h e n t i c P i x e l s #
12935# #
12936# #
12937# #
12938###############################################################################
12939#
12940#
12941void
12942SyncAuthenticPixels(ref,...)
12943 Image::Magick ref = NO_INIT
12944 ALIAS:
12945 Syncauthenticpixels = 1
12946 SyncImagePixels = 2
12947 syncimagepixels = 3
12948 CODE:
12949 {
12950 ExceptionInfo
12951 *exception;
12952
12953 Image
12954 *image;
12955
12956 MagickBooleanType
12957 status;
12958
12959 struct PackageInfo
12960 *info;
12961
12962 SV
12963 *perl_exception,
12964 *reference;
12965
12966 exception=AcquireExceptionInfo();
12967 perl_exception=newSVpv("",0);
12968
12969 if (sv_isobject(ST(0)) == 0)
12970 {
12971 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12972 PackageName);
12973 goto PerlException;
12974 }
12975
12976 reference=SvRV(ST(0));
12977 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12978 if (image == (Image *) NULL)
12979 {
12980 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12981 PackageName);
12982 goto PerlException;
12983 }
12984
12985 status=SyncAuthenticPixels(image,exception);
12986 if (status != MagickFalse)
12987 return;
12988 InheritException(exception,&image->exception);
12989
12990 PerlException:
12991 InheritPerlException(exception,perl_exception);
12992 exception=DestroyExceptionInfo(exception);
12993 SvREFCNT_dec(perl_exception); /* throw away all errors */
12994 }
12995
12996#
12997###############################################################################
12998# #
12999# #
13000# #
13001# T r a n s f o r m #
13002# #
13003# #
13004# #
13005###############################################################################
13006#
13007#
13008void
13009Transform(ref,...)
13010 Image::Magick ref=NO_INIT
13011 ALIAS:
13012 TransformImage = 1
13013 transform = 2
13014 transformimage = 3
13015 PPCODE:
13016 {
13017 AV
13018 *av;
13019
13020 char
13021 *attribute,
13022 *crop_geometry,
13023 *geometry;
13024
13025 ExceptionInfo
13026 *exception;
13027
13028 HV
13029 *hv;
13030
13031 Image
13032 *clone,
13033 *image;
13034
13035 register long
13036 i;
13037
13038 struct PackageInfo
13039 *info;
13040
13041 SV
13042 *av_reference,
13043 *perl_exception,
13044 *reference,
13045 *rv,
13046 *sv;
13047
13048 exception=AcquireExceptionInfo();
13049 perl_exception=newSVpv("",0);
13050 av=NULL;
13051 attribute=NULL;
13052 if (sv_isobject(ST(0)) == 0)
13053 {
13054 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13055 PackageName);
13056 goto PerlException;
13057 }
13058 reference=SvRV(ST(0));
13059 hv=SvSTASH(reference);
13060 av=newAV();
13061 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
13062 SvREFCNT_dec(av);
13063 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13064 if (image == (Image *) NULL)
13065 {
13066 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13067 PackageName);
13068 goto PerlException;
13069 }
13070 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
13071 /*
13072 Get attribute.
13073 */
13074 crop_geometry=(char *) NULL;
13075 geometry=(char *) NULL;
13076 for (i=2; i < items; i+=2)
13077 {
13078 attribute=(char *) SvPV(ST(i-1),na);
13079 switch (*attribute)
13080 {
13081 case 'c':
13082 case 'C':
13083 {
13084 if (LocaleCompare(attribute,"crop") == 0)
13085 {
13086 crop_geometry=SvPV(ST(i),na);
13087 break;
13088 }
13089 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13090 attribute);
13091 break;
13092 }
13093 case 'g':
13094 case 'G':
13095 {
13096 if (LocaleCompare(attribute,"geometry") == 0)
13097 {
13098 geometry=SvPV(ST(i),na);
13099 break;
13100 }
13101 if (LocaleCompare(attribute,"gravity") == 0)
13102 {
13103 Image
13104 *next;
13105
13106 long
13107 in;
13108
13109 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
13110 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13111 if (in < 0)
13112 {
13113 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13114 SvPV(ST(i),na));
13115 return;
13116 }
13117 for (next=image; next; next=next->next)
13118 next->gravity=(GravityType) in;
13119 break;
13120 }
13121 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13122 attribute);
13123 break;
13124 }
13125 default:
13126 {
13127 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13128 attribute);
13129 break;
13130 }
13131 }
13132 }
13133 for ( ; image; image=image->next)
13134 {
13135 clone=CloneImage(image,0,0,MagickTrue,exception);
13136 if ((clone == (Image *) NULL) || (exception->severity >= ErrorException))
13137 goto PerlException;
13138 TransformImage(&clone,crop_geometry,geometry);
13139 for ( ; clone; clone=clone->next)
13140 {
13141 AddImageToRegistry(clone);
13142 rv=newRV(sv);
13143 av_push(av,sv_bless(rv,hv));
13144 SvREFCNT_dec(sv);
13145 }
13146 }
13147 exception=DestroyExceptionInfo(exception);
13148 ST(0)=av_reference;
13149 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13150 XSRETURN(1);
13151
13152 PerlException:
13153 InheritPerlException(exception,perl_exception);
13154 exception=DestroyExceptionInfo(exception);
13155 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
13156 SvPOK_on(perl_exception);
13157 ST(0)=sv_2mortal(perl_exception);
13158 XSRETURN(1);
13159 }
13160
13161#
13162###############################################################################
13163# #
13164# #
13165# #
13166# W r i t e #
13167# #
13168# #
13169# #
13170###############################################################################
13171#
13172#
13173void
13174Write(ref,...)
13175 Image::Magick ref=NO_INIT
13176 ALIAS:
13177 WriteImage = 1
13178 write = 2
13179 writeimage = 3
13180 PPCODE:
13181 {
13182 char
13183 filename[MaxTextExtent];
13184
13185 ExceptionInfo
13186 *exception;
13187
13188 Image
13189 *image,
13190 *next;
13191
13192 long
13193 number_images,
13194 scene;
13195
13196 register long
13197 i;
13198
13199 struct PackageInfo
13200 *info,
13201 *package_info;
13202
13203 SV
13204 *perl_exception,
13205 *reference;
13206
13207 exception=AcquireExceptionInfo();
13208 perl_exception=newSVpv("",0);
13209 number_images=0;
13210 package_info=(struct PackageInfo *) NULL;
13211 if (sv_isobject(ST(0)) == 0)
13212 {
13213 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13214 PackageName);
13215 goto PerlException;
13216 }
13217 reference=SvRV(ST(0));
13218 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13219 if (image == (Image *) NULL)
13220 {
13221 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13222 PackageName);
13223 goto PerlException;
13224 }
13225 package_info=ClonePackageInfo(info,exception);
13226 if (items == 2)
13227 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
13228 else
13229 if (items > 2)
13230 for (i=2; i < items; i+=2)
13231 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
13232 exception);
13233 (void) CopyMagickString(filename,package_info->image_info->filename,
13234 MaxTextExtent);
13235 scene=0;
13236 for (next=image; next; next=next->next)
13237 {
13238 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
13239 next->scene=scene++;
13240 }
13241 SetImageInfo(package_info->image_info,MagickTrue,&image->exception);
13242 for (next=image; next; next=next->next)
13243 {
13244 (void) WriteImage(package_info->image_info,next);
13245 if (next->exception.severity >= ErrorException)
13246 InheritException(exception,&next->exception);
13247 GetImageException(next,exception);
13248 number_images++;
13249 if (package_info->image_info->adjoin)
13250 break;
13251 }
13252
13253 PerlException:
13254 if (package_info != (struct PackageInfo *) NULL)
13255 DestroyPackageInfo(package_info);
13256 InheritPerlException(exception,perl_exception);
13257 exception=DestroyExceptionInfo(exception);
13258 sv_setiv(perl_exception,(IV) number_images);
13259 SvPOK_on(perl_exception);
13260 ST(0)=sv_2mortal(perl_exception);
13261 XSRETURN(1);
13262 }