blob: 272b1d5b20cefdbfd777e2faddb78c600542d138 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% PPPP EEEEE RRRR L %
6% P P E R R L %
7% PPPP EEE RRRR L %
8% P E R R L %
9% P EEEEE R R LLLLL %
10% %
11% M M AAA GGGG IIIII CCCC K K %
12% MM MM A A G I C K K %
13% M M M AAAAA G GGG I C KKK %
14% M M A A G G I C K K %
15% M M A A GGGG IIIII CCCC K K %
16% %
17% %
18% Object-oriented Perl interface to ImageMagick %
19% %
20% Software Design %
21% Kyle Shorter %
22% John Cristy %
23% February 1997 %
24% %
25% %
26% Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
27% dedicated to making software imaging solutions freely available. %
28% %
29% You may not use this file except in compliance with the License. You may %
30% obtain a copy of the License at %
31% %
32% http://www.imagemagick.org/script/license.php %
33% %
34% Unless required by applicable law or agreed to in writing, software %
35% distributed under the License is distributed on an "AS IS" BASIS, %
36% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37% See the License for the specific language governing permissions and %
38% limitations under the License. %
39% %
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41%
42% PerlMagick is an objected-oriented Perl interface to ImageMagick. Use
43% the module to read, manipulate, or write an image or image sequence from
44% within a Perl script. This makes PerlMagick suitable for Web CGI scripts.
45%
46*/
47
48/*
49 Include declarations.
50*/
51#if !defined(WIN32)
52#define MagickExport
53#endif
54
55#if defined(__cplusplus) || defined(c_plusplus)
56extern "C" {
57#endif
58
59#define PERL_NO_GET_CONTEXT
60#include "EXTERN.h"
61#include "perl.h"
62#include "XSUB.h"
63#include <math.h>
64#include <magick/MagickCore.h>
65#undef tainted
66
67#if defined(__cplusplus) || defined(c_plusplus)
68}
69#endif
70
71/*
72 Define declarations.
73*/
74#ifndef aTHX_
75#define aTHX_
76#define pTHX_
77#define dTHX
78#endif
79#define DegreesToRadians(x) (MagickPI*(x)/180.0)
80#define EndOf(array) (&array[NumberOf(array)])
81#define MagickPI 3.14159265358979323846264338327950288419716939937510
82#define MaxArguments 31
83#ifndef na
84#define na PL_na
85#endif
86#define NumberOf(array) (sizeof(array)/sizeof(*array))
87#define PackageName "Image::Magick"
88#if PERL_VERSION <= 6
89#define PerlIO FILE
90#define PerlIO_importFILE(f, fl) (f)
91#define PerlIO_findFILE(f) NULL
92#endif
93#define RoundToQuantum(value) ((Quantum) ((value) < 0.0 ? 0.0 : \
94 ((value) > (MagickRealType) QuantumRange) ? (MagickRealType) \
95 QuantumRange : (value)+0.5))
96#ifndef sv_undef
97#define sv_undef PL_sv_undef
98#endif
99
100#define AddImageToRegistry(image) \
101{ \
102 if (magick_registry != (SplayTreeInfo *) NULL) \
103 { \
104 (void) AddValueToSplayTree(magick_registry,image,image); \
105 sv=newSViv((IV) image); \
106 } \
107}
108
109#define DeleteImageFromRegistry(reference,image) \
110{ \
111 if (magick_registry != (SplayTreeInfo *) NULL) \
112 { \
113 if (GetImageReferenceCount(image) == 1) \
114 (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
115 image=DestroyImage(image); \
116 sv_setiv(reference,0); \
117 } \
118}
119
120#define InheritPerlException(exception,perl_exception) \
121{ \
122 char \
123 message[MaxTextExtent]; \
124 \
125 if ((exception)->severity != UndefinedException) \
126 { \
127 (void) FormatMagickString(message,MaxTextExtent,"Exception %d: %s%s%s%s",\
128 (exception)->severity, (exception)->reason ? \
129 GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
130 "Unknown", (exception)->description ? " (" : "", \
131 (exception)->description ? GetLocaleExceptionMessage( \
132 (exception)->severity,(exception)->description) : "", \
133 (exception)->description ? ")" : ""); \
134 if ((perl_exception) != (SV *) NULL) \
135 { \
136 if (SvCUR(perl_exception)) \
137 sv_catpv(perl_exception,"\n"); \
138 sv_catpv(perl_exception,message); \
139 } \
140 } \
141}
142
143#define ThrowPerlException(exception,severity,tag,reason) \
144 (void) ThrowMagickException(exception,GetMagickModule(),severity, \
145 tag,"`%s'",reason); \
146
147/*
148 Typedef and structure declarations.
149*/
150typedef enum
151{
152 ArrayReference = (~0),
153 RealReference = (~0)-1,
154 FileReference = (~0)-2,
155 ImageReference = (~0)-3,
156 IntegerReference = (~0)-4,
157 StringReference = (~0)-5
158} MagickReference;
159
160typedef struct _Arguments
161{
162 const char
163 *method;
164
165 long
166 type;
167} Arguments;
168
169struct ArgumentList
170{
171 long
172 long_reference;
173
174 MagickRealType
175 real_reference;
176
177 const char
178 *string_reference;
179
180 Image
181 *image_reference;
182
183 SV
184 *array_reference;
185
186 FILE
187 *file_reference;
188
189 size_t
190 length;
191};
192
193struct PackageInfo
194{
195 ImageInfo
196 *image_info;
197};
198
199typedef void
200 *Image__Magick; /* data type for the Image::Magick package */
201
202/*
203 Static declarations.
204*/
205static struct
206 Methods
207 {
208 const char
209 *name;
210
211 Arguments
212 arguments[MaxArguments];
213 } Methods[] =
214 {
215 { "Comment", { {"comment", StringReference} } },
216 { "Label", { {"label", StringReference} } },
217 { "AddNoise", { {"noise", MagickNoiseOptions},
218 {"channel", MagickChannelOptions} } },
219 { "Colorize", { {"fill", StringReference}, {"opacity", StringReference} } },
220 { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
221 {"height", IntegerReference}, {"fill", StringReference},
222 {"bordercolor", StringReference}, {"color", StringReference},
223 {"compose", MagickComposeOptions} } },
224 { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
225 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
226 { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
227 {"height", IntegerReference}, {"x", IntegerReference},
228 {"y", IntegerReference} } },
229 { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
230 {"height", IntegerReference}, {"x", IntegerReference},
231 {"y", IntegerReference}, {"fuzz", StringReference} } },
232 { "Despeckle", },
233 { "Edge", { {"radius", RealReference} } },
234 { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
235 {"sigma", RealReference} } },
236 { "Enhance", },
237 { "Flip", },
238 { "Flop", },
239 { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
240 {"height", IntegerReference}, {"inner", IntegerReference},
241 {"outer", IntegerReference}, {"fill", StringReference},
242 {"color", StringReference}, {"compose", MagickComposeOptions} } },
243 { "Implode", { {"amount", RealReference},
244 {"interpolate", MagickInterpolateOptions} } },
245 { "Magnify", },
246 { "MedianFilter", { {"radius", RealReference} } },
247 { "Minify", },
248 { "OilPaint", { {"radius", RealReference} } },
249 { "ReduceNoise", { {"radius", RealReference} } },
250 { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
251 {"y", IntegerReference} } },
252 { "Rotate", { {"degrees", RealReference}, {"fill", StringReference},
253 {"color", StringReference}, {"background", StringReference} } },
254 { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
255 {"height", IntegerReference} } },
256 { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
257 {"height", IntegerReference} } },
258 { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
259 {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
260 { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
261 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
262 { "Shear", { {"geometry", StringReference}, {"x", RealReference},
263 {"y", RealReference}, { "fill", StringReference},
264 {"color", StringReference} } },
265 { "Spread", { {"radius", RealReference} } },
266 { "Swirl", { {"degrees", RealReference},
267 {"interpolate", MagickInterpolateOptions} } },
268 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
269 {"height", IntegerReference}, {"filter", MagickFilterOptions},
270 {"support", StringReference }, {"blur", RealReference } } },
271 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
272 {"height", IntegerReference}, {"filter", MagickFilterOptions},
273 {"support", RealReference }, {"blur", RealReference } } },
274 { "Annotate", { {"text", StringReference}, {"font", StringReference},
275 {"pointsize", RealReference}, {"density", StringReference},
276 {"undercolor", StringReference}, {"stroke", StringReference},
277 {"fill", StringReference}, {"geometry", StringReference},
278 {"pen", StringReference}, {"x", RealReference},
279 {"y", RealReference}, {"gravity", MagickGravityOptions},
280 {"translate", StringReference}, {"scale", StringReference},
281 {"rotate", RealReference}, {"skewX", RealReference},
282 {"skewY", RealReference}, {"strokewidth", RealReference},
283 {"antialias", MagickBooleanOptions}, {"family", StringReference},
284 {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
285 {"weight", IntegerReference}, {"align", MagickAlignOptions},
286 {"encoding", StringReference}, {"affine", ArrayReference},
287 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
288 {"tile", ImageReference}, {"kerning", RealReference},
289 {"interword-spacing", RealReference} } },
290 { "ColorFloodfill", { {"geometry", StringReference},
291 {"x", IntegerReference}, {"y", IntegerReference},
292 {"fill", StringReference}, {"bordercolor", StringReference},
293 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
294 { "Composite", { {"image", ImageReference},
295 {"compose", MagickComposeOptions}, {"geometry", StringReference},
296 {"x", IntegerReference}, {"y", IntegerReference},
297 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
298 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
299 {"color", StringReference}, {"mask", ImageReference},
300 {"channel", MagickChannelOptions},
301 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
302 {"blend", StringReference} } },
303 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
304 { "CycleColormap", { {"display", IntegerReference} } },
305 { "Draw", { {"primitive", MagickPrimitiveOptions},
306 {"points", StringReference}, {"method", MagickMethodOptions},
307 {"stroke", StringReference}, {"fill", StringReference},
308 {"strokewidth", RealReference}, {"font", StringReference},
309 {"bordercolor", StringReference}, {"x", RealReference},
310 {"y", RealReference}, {"translate", StringReference},
311 {"scale", StringReference}, {"rotate", RealReference},
312 {"skewX", RealReference}, {"skewY", RealReference},
313 {"tile", ImageReference}, {"pointsize", RealReference},
314 {"antialias", MagickBooleanOptions}, {"density", StringReference},
315 {"linewidth", RealReference}, {"affine", ArrayReference},
316 {"stroke-dashoffset", RealReference},
317 {"stroke-dasharray", ArrayReference},
318 {"interpolate", MagickInterpolateOptions},
319 {"origin", StringReference}, {"text", StringReference},
320 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
321 {"vector-graphics", StringReference}, {"kerning", RealReference},
322 {"interword-spacing", RealReference} } },
323 { "Equalize", { {"channel", MagickChannelOptions} } },
324 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
325 {"red", RealReference}, {"green", RealReference},
326 {"blue", RealReference} } },
327 { "Map", { {"image", ImageReference}, {"dither", MagickBooleanOptions} } },
328 { "MatteFloodfill", { {"geometry", StringReference},
329 {"x", IntegerReference}, {"y", IntegerReference},
330 {"opacity", StringReference}, {"bordercolor", StringReference},
331 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
332 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
333 {"saturation", RealReference}, {"whiteness", RealReference},
334 {"brightness", RealReference}, {"luminosity", RealReference},
335 {"blackness", RealReference} } },
336 { "Negate", { {"gray", MagickBooleanOptions},
337 {"channel", MagickChannelOptions} } },
338 { "Normalize", { {"channel", MagickChannelOptions} } },
339 { "NumberColors", },
340 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
341 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
342 {"invert", MagickBooleanOptions} } },
343 { "Quantize", { {"colors", IntegerReference},
344 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
345 {"dither", MagickBooleanOptions}, {"measure", MagickBooleanOptions},
346 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
347 {"dither-method", MagickDitherOptions} } },
348 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
349 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
350 { "Segment", { {"geometry", StringReference},
351 {"cluster-threshold", RealReference},
352 {"smoothing-threshold", RealReference},
353 {"colorspace", MagickColorspaceOptions},
354 {"verbose", MagickBooleanOptions} } },
355 { "Signature", },
356 { "Solarize", { {"geometry", StringReference},
357 {"threshold", StringReference} } },
358 { "Sync", },
359 { "Texture", { {"texture", ImageReference} } },
360 { "Evaluate", { {"value", RealReference},
361 {"operator", MagickEvaluateOptions},
362 {"channel", MagickChannelOptions} } },
363 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
364 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
365 { "Threshold", { {"threshold", StringReference},
366 {"channel", MagickChannelOptions} } },
367 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
368 {"sigma", RealReference} } },
369 { "Trim", { {"fuzz", StringReference} } },
370 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
371 {"wavelength", RealReference},
372 {"interpolate", MagickInterpolateOptions} } },
373 { "Separate", { {"channel", MagickChannelOptions} } },
374 { "Condense", },
375 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
376 {"y", IntegerReference} } },
377 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
378 { "Deconstruct", },
379 { "GaussianBlur", { {"geometry", StringReference},
380 {"radius", RealReference}, {"sigma", RealReference},
381 {"channel", MagickChannelOptions} } },
382 { "Convolve", { {"coefficients", ArrayReference},
383 {"channel", MagickChannelOptions}, {"bias", StringReference} } },
384 { "Profile", { {"name", StringReference}, {"profile", StringReference},
385 { "rendering-intent", MagickIntentOptions},
386 { "black-point-compensation", MagickBooleanOptions} } },
387 { "UnsharpMask", { {"geometry", StringReference},
388 {"radius", RealReference}, {"sigma", RealReference},
389 {"amount", RealReference}, {"threshold", RealReference},
390 {"channel", MagickChannelOptions} } },
391 { "MotionBlur", { {"geometry", StringReference},
392 {"radius", RealReference}, {"sigma", RealReference},
393 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
394 { "OrderedDither", { {"threshold", StringReference},
395 {"channel", MagickChannelOptions} } },
396 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
397 {"height", IntegerReference} } },
398 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
399 {"white-point", RealReference}, {"gamma", RealReference},
400 {"channel", MagickChannelOptions}, {"level", StringReference} } },
401 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
402 { "AffineTransform", { {"affine", ArrayReference},
403 {"translate", StringReference}, {"scale", StringReference},
404 {"rotate", RealReference}, {"skewX", RealReference},
405 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
406 {"background", StringReference} } },
407 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
408 { "AdaptiveThreshold", { {"geometry", StringReference},
409 {"width", IntegerReference}, {"height", IntegerReference},
410 {"offset", IntegerReference} } },
411 { "Resample", { {"density", StringReference}, {"x", RealReference},
412 {"y", RealReference}, {"filter", MagickFilterOptions},
413 {"support", RealReference }, {"blur", RealReference } } },
414 { "Describe", { {"file", FileReference} } },
415 { "BlackThreshold", { {"threshold", StringReference},
416 {"channel", MagickChannelOptions} } },
417 { "WhiteThreshold", { {"threshold", StringReference},
418 {"channel", MagickChannelOptions} } },
419 { "RadialBlur", { {"geometry", StringReference}, {"angle", RealReference},
420 {"channel", MagickChannelOptions} } },
421 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
422 {"height", IntegerReference} } },
423 { "Strip", },
424 { "Tint", { {"fill", StringReference}, {"opacity", StringReference} } },
425 { "Channel", { {"channel", MagickChannelOptions} } },
426 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
427 {"height", IntegerReference}, {"x", IntegerReference},
428 {"y", IntegerReference}, {"fuzz", StringReference},
429 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
430 { "Posterize", { {"levels", IntegerReference},
431 {"dither", MagickBooleanOptions} } },
432 { "Shadow", { {"geometry", StringReference}, {"opacity", RealReference},
433 {"sigma", RealReference}, {"x", IntegerReference},
434 {"y", IntegerReference} } },
435 { "Identify", { {"file", FileReference} } },
436 { "SepiaTone", { {"threshold", RealReference} } },
437 { "SigmoidalContrast", { {"geometry", StringReference},
438 {"contrast", RealReference}, {"mid-point", RealReference},
439 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
440 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
441 {"height", IntegerReference}, {"x", IntegerReference},
442 {"y", IntegerReference}, {"fuzz", StringReference},
443 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
444 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
445 {"sigma", RealReference}, {"x", IntegerReference},
446 {"y", IntegerReference}, {"background", StringReference} } },
447 { "ContrastStretch", { {"levels", StringReference},
448 {"black-point", RealReference},{"white-point", RealReference},
449 {"channel", MagickChannelOptions} } },
450 { "Sans0", },
451 { "Sans1", },
452 { "AdaptiveSharpen", { {"geometry", StringReference},
453 {"radius", RealReference}, {"sigma", RealReference},
454 {"channel", MagickChannelOptions} } },
455 { "Transpose", },
456 { "Transverse", },
457 { "AutoOrient", },
458 { "AdaptiveBlur", { {"geometry", StringReference},
459 {"radius", RealReference}, {"sigma", RealReference},
460 {"channel", MagickChannelOptions} } },
461 { "Sketch", { {"geometry", StringReference},
462 {"radius", RealReference}, {"sigma", RealReference},
463 {"angle", RealReference} } },
464 { "UniqueColors", },
465 { "AdaptiveResize", { {"geometry", StringReference},
466 {"width", IntegerReference}, {"height", IntegerReference},
467 {"filter", MagickFilterOptions}, {"support", StringReference },
468 {"blur", RealReference } } },
469 { "ClipMask", { {"mask", ImageReference} } },
470 { "LinearStretch", { {"levels", StringReference},
471 {"black-point", RealReference},{"white-point", RealReference} } },
472 { "Recolor", { {"matrix", ArrayReference} } },
473 { "Mask", { {"mask", ImageReference} } },
474 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
475 {"font", StringReference}, {"stroke", StringReference},
476 {"fill", StringReference}, {"strokewidth", RealReference},
477 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
478 {"background", StringReference} } },
479 { "FloodfillPaint", { {"geometry", StringReference},
480 {"x", IntegerReference}, {"y", IntegerReference},
481 {"fill", StringReference}, {"bordercolor", StringReference},
482 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
483 {"invert", MagickBooleanOptions} } },
484 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
485 {"virtual-pixel", MagickVirtualPixelOptions},
486 {"best-fit", MagickBooleanOptions} } },
487 { "Clut", { {"image", ImageReference},
488 {"channel", MagickChannelOptions} } },
489 { "LiquidRescale", { {"geometry", StringReference},
490 {"width", IntegerReference}, {"height", IntegerReference},
491 {"delta-x", RealReference}, {"rigidity", RealReference } } },
492 { "Encipher", { {"passphrase", StringReference} } },
493 { "Decipher", { {"passphrase", StringReference} } },
494 { "Deskew", { {"geometry", StringReference},
495 {"threshold", StringReference} } },
496 { "Remap", { {"image", ImageReference},
497 {"dither-method", MagickDitherOptions} } },
498 { "SparseColor", { {"points", ArrayReference},
499 {"method", MagickSparseColorOptions},
500 {"virtual-pixel", MagickVirtualPixelOptions},
501 {"channel", MagickChannelOptions} } },
502 { "Function", { {"parameters", ArrayReference},
503 {"function", MagickFunctionOptions},
504 {"virtual-pixel", MagickVirtualPixelOptions} } },
505 { "SelectiveBlur", { {"geometry", StringReference},
506 {"radius", RealReference}, {"sigma", RealReference},
507 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
508 { "HaldClut", { {"image", ImageReference},
509 {"channel", MagickChannelOptions} } },
510 { "BlueShift", {"factor", StringReference} },
511 { "ForwardFourierTransform", {"magnitude", MagickBooleanOptions} },
512 { "InverseFourierTransform", {"magnitude", MagickBooleanOptions} },
513 { "ColorDecisionList", {
514 {"color-correction-collection", StringReference} } },
515 { "AutoGamma", { {"channel", MagickChannelOptions} } },
516 { "AutoLevel", { {"channel", MagickChannelOptions} } },
517 };
518
519static SplayTreeInfo
520 *magick_registry = (SplayTreeInfo *) NULL;
521
522/*
523 Forward declarations.
524*/
525static Image
526 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
527
528static long
529 strEQcase(const char *,const char *);
530
531/*
532%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
533% %
534% %
535% %
536% C l o n e P a c k a g e I n f o %
537% %
538% %
539% %
540%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
541%
542% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
543% a new one.
544%
545% The format of the ClonePackageInfo routine is:
546%
547% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
548% exception)
549%
550% A description of each parameter follows:
551%
552% o info: a structure of type info.
553%
554% o exception: Return any errors or warnings in this structure.
555%
556*/
557static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
558 ExceptionInfo *exception)
559{
560 struct PackageInfo
561 *clone_info;
562
563 clone_info=(struct PackageInfo *) AcquireMagickMemory(sizeof(*clone_info));
564 if (clone_info == (struct PackageInfo *) NULL)
565 {
566 ThrowPerlException(exception,ResourceLimitError,
567 "UnableToClonePackageInfo",PackageName);
568 return((struct PackageInfo *) NULL);
569 }
570 if (info == (struct PackageInfo *) NULL)
571 {
572 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
573 return(clone_info);
574 }
575 *clone_info=(*info);
576 clone_info->image_info=CloneImageInfo(info->image_info);
577 return(clone_info);
578}
579
580/*
581%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582% %
583% %
584% %
585% c o n s t a n t %
586% %
587% %
588% %
589%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
590%
591% constant() returns a double value for the specified name.
592%
593% The format of the constant routine is:
594%
595% double constant(char *name,long sans)
596%
597% A description of each parameter follows:
598%
599% o value: Method constant returns a double value for the specified name.
600%
601% o name: The name of the constant.
602%
603% o sans: This integer value is not used.
604%
605*/
606static double constant(char *name,long sans)
607{
608 (void) sans;
609 errno=0;
610 switch (*name)
611 {
612 case 'B':
613 {
614 if (strEQ(name,"BlobError"))
615 return(BlobError);
616 if (strEQ(name,"BlobWarning"))
617 return(BlobWarning);
618 break;
619 }
620 case 'C':
621 {
622 if (strEQ(name,"CacheError"))
623 return(CacheError);
624 if (strEQ(name,"CacheWarning"))
625 return(CacheWarning);
626 if (strEQ(name,"CoderError"))
627 return(CoderError);
628 if (strEQ(name,"CoderWarning"))
629 return(CoderWarning);
630 if (strEQ(name,"ConfigureError"))
631 return(ConfigureError);
632 if (strEQ(name,"ConfigureWarning"))
633 return(ConfigureWarning);
634 if (strEQ(name,"CorruptImageError"))
635 return(CorruptImageError);
636 if (strEQ(name,"CorruptImageWarning"))
637 return(CorruptImageWarning);
638 break;
639 }
640 case 'D':
641 {
642 if (strEQ(name,"DelegateError"))
643 return(DelegateError);
644 if (strEQ(name,"DelegateWarning"))
645 return(DelegateWarning);
646 if (strEQ(name,"DrawError"))
647 return(DrawError);
648 if (strEQ(name,"DrawWarning"))
649 return(DrawWarning);
650 break;
651 }
652 case 'E':
653 {
654 if (strEQ(name,"ErrorException"))
655 return(ErrorException);
656 if (strEQ(name,"ExceptionError"))
657 return(CoderError);
658 if (strEQ(name,"ExceptionWarning"))
659 return(CoderWarning);
660 break;
661 }
662 case 'F':
663 {
664 if (strEQ(name,"FatalErrorException"))
665 return(FatalErrorException);
666 if (strEQ(name,"FileOpenError"))
667 return(FileOpenError);
668 if (strEQ(name,"FileOpenWarning"))
669 return(FileOpenWarning);
670 break;
671 }
672 case 'I':
673 {
674 if (strEQ(name,"ImageError"))
675 return(ImageError);
676 if (strEQ(name,"ImageWarning"))
677 return(ImageWarning);
678 break;
679 }
680 case 'M':
681 {
682 if (strEQ(name,"MaxRGB"))
683 return(QuantumRange);
684 if (strEQ(name,"MissingDelegateError"))
685 return(MissingDelegateError);
686 if (strEQ(name,"MissingDelegateWarning"))
687 return(MissingDelegateWarning);
688 if (strEQ(name,"ModuleError"))
689 return(ModuleError);
690 if (strEQ(name,"ModuleWarning"))
691 return(ModuleWarning);
692 break;
693 }
694 case 'O':
695 {
696 if (strEQ(name,"Opaque"))
697 return(OpaqueOpacity);
698 if (strEQ(name,"OptionError"))
699 return(OptionError);
700 if (strEQ(name,"OptionWarning"))
701 return(OptionWarning);
702 break;
703 }
704 case 'Q':
705 {
706 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
707 return(MAGICKCORE_QUANTUM_DEPTH);
708 if (strEQ(name,"QuantumDepth"))
709 return(QuantumDepth);
710 if (strEQ(name,"QuantumRange"))
711 return(QuantumRange);
712 break;
713 }
714 case 'R':
715 {
716 if (strEQ(name,"ResourceLimitError"))
717 return(ResourceLimitError);
718 if (strEQ(name,"ResourceLimitWarning"))
719 return(ResourceLimitWarning);
720 if (strEQ(name,"RegistryError"))
721 return(RegistryError);
722 if (strEQ(name,"RegistryWarning"))
723 return(RegistryWarning);
724 break;
725 }
726 case 'S':
727 {
728 if (strEQ(name,"StreamError"))
729 return(StreamError);
730 if (strEQ(name,"StreamWarning"))
731 return(StreamWarning);
732 if (strEQ(name,"Success"))
733 return(0);
734 break;
735 }
736 case 'T':
737 {
738 if (strEQ(name,"Transparent"))
739 return(TransparentOpacity);
740 if (strEQ(name,"TypeError"))
741 return(TypeError);
742 if (strEQ(name,"TypeWarning"))
743 return(TypeWarning);
744 break;
745 }
746 case 'W':
747 {
748 if (strEQ(name,"WarningException"))
749 return(WarningException);
750 break;
751 }
752 case 'X':
753 {
754 if (strEQ(name,"XServerError"))
755 return(XServerError);
756 if (strEQ(name,"XServerWarning"))
757 return(XServerWarning);
758 break;
759 }
760 }
761 errno=EINVAL;
762 return(0);
763}
764
765/*
766%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
767% %
768% %
769% %
770% D e s t r o y P a c k a g e I n f o %
771% %
772% %
773% %
774%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
775%
776% Method DestroyPackageInfo frees a previously created info structure.
777%
778% The format of the DestroyPackageInfo routine is:
779%
780% DestroyPackageInfo(struct PackageInfo *info)
781%
782% A description of each parameter follows:
783%
784% o info: a structure of type info.
785%
786*/
787static void DestroyPackageInfo(struct PackageInfo *info)
788{
789 info->image_info=DestroyImageInfo(info->image_info);
790 info=(struct PackageInfo *) RelinquishMagickMemory(info);
791}
792
793/*
794%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795% %
796% %
797% %
798% G e t L i s t %
799% %
800% %
801% %
802%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
803%
804% Method GetList is recursively called by SetupList to traverse the
805% Image__Magick reference. If building an reference_vector (see SetupList),
806% *current is the current position in *reference_vector and *last is the final
807% entry in *reference_vector.
808%
809% The format of the GetList routine is:
810%
811% GetList(info)
812%
813% A description of each parameter follows:
814%
815% o info: a structure of type info.
816%
817*/
818static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,long *current,
819 long *last,ExceptionInfo *exception)
820{
821 Image
822 *image;
823
824 if (reference == (SV *) NULL)
825 return(NULL);
826 switch (SvTYPE(reference))
827 {
828 case SVt_PVAV:
829 {
830 AV
831 *av;
832
833 Image
834 *head,
835 *previous;
836
837 long
838 n;
839
840 register long
841 i;
842
843 /*
844 Array of images.
845 */
846 previous=(Image *) NULL;
847 head=(Image *) NULL;
848 av=(AV *) reference;
849 n=av_len(av);
850 for (i=0; i <= n; i++)
851 {
852 SV
853 **rv;
854
855 rv=av_fetch(av,i,0);
856 if (rv && *rv && sv_isobject(*rv))
857 {
858 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
859 exception);
860 if (image == (Image *) NULL)
861 continue;
862 if (image == previous)
863 {
864 image=CloneImage(image,0,0,MagickTrue,exception);
865 if (image == (Image *) NULL)
866 return(NULL);
867 }
868 image->previous=previous;
869 *(previous ? &previous->next : &head)=image;
870 for (previous=image; previous->next; previous=previous->next) ;
871 }
872 }
873 return(head);
874 }
875 case SVt_PVMG:
876 {
877 /*
878 Blessed scalar, one image.
879 */
880 image=(Image *) SvIV(reference);
881 if (image == (Image *) NULL)
882 return(NULL);
883 image->previous=(Image *) NULL;
884 image->next=(Image *) NULL;
885 if (reference_vector)
886 {
887 if (*current == *last)
888 {
889 *last+=256;
890 if (*reference_vector == (SV **) NULL)
891 *reference_vector=(SV **) AcquireQuantumMemory(*last,
892 sizeof(*reference_vector));
893 else
894 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
895 *last,sizeof(*reference_vector));
896 }
897 if (*reference_vector == (SV **) NULL)
898 {
899 ThrowPerlException(exception,ResourceLimitError,
900 "MemoryAllocationFailed",PackageName);
901 return((Image *) NULL);
902 }
903 (*reference_vector)[*current]=reference;
904 (*reference_vector)[++(*current)]=NULL;
905 }
906 return(image);
907 }
908 default:
909 break;
910 }
911 (void) fprintf(stderr,"GetList: UnrecognizedType %ld\n",
912 (long) SvTYPE(reference));
913 return((Image *) NULL);
914}
915
916/*
917%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
918% %
919% %
920% %
921% G e t P a c k a g e I n f o %
922% %
923% %
924% %
925%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
926%
927% Method GetPackageInfo looks up or creates an info structure for the given
928% Image__Magick reference. If it does create a new one, the information in
929% package_info is used to initialize it.
930%
931% The format of the GetPackageInfo routine is:
932%
933% struct PackageInfo *GetPackageInfo(void *reference,
934% struct PackageInfo *package_info,ExceptionInfo *exception)
935%
936% A description of each parameter follows:
937%
938% o info: a structure of type info.
939%
940% o exception: Return any errors or warnings in this structure.
941%
942*/
943static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
944 struct PackageInfo *package_info,ExceptionInfo *exception)
945{
946 char
947 message[MaxTextExtent];
948
949 struct PackageInfo
950 *clone_info;
951
952 SV
953 *sv;
954
955 (void) FormatMagickString(message,MaxTextExtent,"%s::package%s%lx",
956 PackageName,XS_VERSION,(long) reference);
957 sv=perl_get_sv(message,(TRUE | 0x02));
958 if (sv == (SV *) NULL)
959 {
960 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
961 message);
962 return(package_info);
963 }
964 if (SvREFCNT(sv) == 0)
965 (void) SvREFCNT_inc(sv);
966 if (SvIOKp(sv) && (clone_info=(struct PackageInfo *) SvIV(sv)))
967 return(clone_info);
968 clone_info=ClonePackageInfo(package_info,exception);
969 sv_setiv(sv,(IV) clone_info);
970 return(clone_info);
971}
972
973/*
974%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
975% %
976% %
977% %
978% S e t A t t r i b u t e %
979% %
980% %
981% %
982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983%
984% SetAttribute() sets the attribute to the value in sval. This can change
985% either or both of image or info.
986%
987% The format of the SetAttribute routine is:
988%
989% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
990% SV *sval,ExceptionInfo *exception)
991%
992% A description of each parameter follows:
993%
994% o list: a list of strings.
995%
996% o string: a character string.
997%
998*/
999static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1000 const char *attribute,SV *sval,ExceptionInfo *exception)
1001{
1002 GeometryInfo
1003 geometry_info;
1004
1005 long
1006 sp;
1007
1008 long
1009 x,
1010 y;
1011
1012 MagickPixelPacket
1013 pixel;
1014
1015 MagickStatusType
1016 flags;
1017
1018 PixelPacket
1019 *color,
1020 target_color;
1021
1022 switch (*attribute)
1023 {
1024 case 'A':
1025 case 'a':
1026 {
1027 if (LocaleCompare(attribute,"adjoin") == 0)
1028 {
1029 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1030 SvPV(sval,na)) : SvIV(sval);
1031 if (sp < 0)
1032 {
1033 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1034 SvPV(sval,na));
1035 break;
1036 }
1037 if (info)
1038 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1039 break;
1040 }
1041 if (LocaleCompare(attribute,"alpha") == 0)
1042 {
1043 sp=SvPOK(sval) ? ParseMagickOption(MagickAlphaOptions,MagickFalse,
1044 SvPV(sval,na)) : SvIV(sval);
1045 if (sp < 0)
1046 {
1047 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1048 SvPV(sval,na));
1049 break;
1050 }
1051 for ( ; image; image=image->next)
1052 (void) SetImageAlphaChannel(image,(AlphaChannelType) sp);
1053 break;
1054 }
1055 if (LocaleCompare(attribute,"antialias") == 0)
1056 {
1057 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1058 SvPV(sval,na)) : SvIV(sval);
1059 if (sp < 0)
1060 {
1061 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1062 SvPV(sval,na));
1063 break;
1064 }
1065 if (info)
1066 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1067 break;
1068 }
1069 if (LocaleCompare(attribute,"area-limit") == 0)
1070 {
1071 MagickSizeType
1072 limit;
1073
1074 limit=MagickResourceInfinity;
1075 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1076 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1077 (void) SetMagickResourceLimit(AreaResource,limit);
1078 break;
1079 }
1080 if (LocaleCompare(attribute,"attenuate") == 0)
1081 {
1082 if (info)
1083 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1084 break;
1085 }
1086 if (LocaleCompare(attribute,"authenticate") == 0)
1087 {
1088 if (info)
1089 (void) CloneString(&info->image_info->authenticate,SvPV(sval,na));
1090 break;
1091 }
1092 if (info)
1093 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1094 for ( ; image; image=image->next)
1095 SetImageProperty(image,attribute,SvPV(sval,na));
1096 break;
1097 }
1098 case 'B':
1099 case 'b':
1100 {
1101 if (LocaleCompare(attribute,"background") == 0)
1102 {
1103 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
1104 if (info)
1105 info->image_info->background_color=target_color;
1106 for ( ; image; image=image->next)
1107 image->background_color=target_color;
1108 break;
1109 }
1110 if (LocaleCompare(attribute,"bias") == 0)
1111 {
1112 for ( ; image; image=image->next)
1113 image->bias=StringToDouble(SvPV(sval,na),QuantumRange);
1114 break;
1115 }
1116 if (LocaleCompare(attribute,"blue-primary") == 0)
1117 {
1118 for ( ; image; image=image->next)
1119 {
1120 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1121 image->chromaticity.blue_primary.x=geometry_info.rho;
1122 image->chromaticity.blue_primary.y=geometry_info.sigma;
1123 if ((flags & SigmaValue) == 0)
1124 image->chromaticity.blue_primary.y=
1125 image->chromaticity.blue_primary.x;
1126 }
1127 break;
1128 }
1129 if (LocaleCompare(attribute,"bordercolor") == 0)
1130 {
1131 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
1132 if (info)
1133 info->image_info->border_color=target_color;
1134 for ( ; image; image=image->next)
1135 image->border_color=target_color;
1136 break;
1137 }
1138 if (info)
1139 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1140 for ( ; image; image=image->next)
1141 SetImageProperty(image,attribute,SvPV(sval,na));
1142 break;
1143 }
1144 case 'C':
1145 case 'c':
1146 {
1147 if (LocaleCompare(attribute,"cache-threshold") == 0)
1148 {
1149 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1150 StringToDouble(SvPV(sval,na),100.0));
1151 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1152 (2*StringToDouble(SvPV(sval,na),100.0)));
1153 break;
1154 }
1155 if (LocaleCompare(attribute,"clip-mask") == 0)
1156 {
1157 Image
1158 *clip_mask;
1159
1160 clip_mask=(Image *) NULL;
1161 if (SvPOK(sval))
1162 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1163 for ( ; image; image=image->next)
1164 SetImageClipMask(image,clip_mask);
1165 break;
1166 }
1167 if (LocaleNCompare(attribute,"colormap",8) == 0)
1168 {
1169 for ( ; image; image=image->next)
1170 {
1171 int
1172 items;
1173
1174 long
1175 i;
1176
1177 if (image->storage_class == DirectClass)
1178 continue;
1179 i=0;
1180 items=sscanf(attribute,"%*[^[][%ld",&i);
1181 if (i > (long) image->colors)
1182 i%=image->colors;
1183 if ((strchr(SvPV(sval,na),',') == 0) ||
1184 (strchr(SvPV(sval,na),')') != 0))
1185 QueryColorDatabase(SvPV(sval,na),image->colormap+i,exception);
1186 else
1187 {
1188 color=image->colormap+i;
1189 pixel.red=color->red;
1190 pixel.green=color->green;
1191 pixel.blue=color->blue;
1192 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1193 pixel.red=geometry_info.rho;
1194 pixel.green=geometry_info.sigma;
1195 pixel.blue=geometry_info.xi;
1196 color->red=RoundToQuantum(pixel.red);
1197 color->green=RoundToQuantum(pixel.green);
1198 color->blue=RoundToQuantum(pixel.blue);
1199 }
1200 }
1201 break;
1202 }
1203 if (LocaleCompare(attribute,"colorspace") == 0)
1204 {
1205 sp=SvPOK(sval) ? ParseMagickOption(MagickColorspaceOptions,
1206 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1207 if (sp < 0)
1208 {
1209 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1210 SvPV(sval,na));
1211 break;
1212 }
1213 for ( ; image; image=image->next)
1214 (void) TransformImageColorspace(image,(ColorspaceType) sp);
1215 break;
1216 }
1217 if (LocaleCompare(attribute,"comment") == 0)
1218 {
1219 for ( ; image; image=image->next)
1220 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1221 info ? info->image_info : (ImageInfo *) NULL,image,
1222 SvPV(sval,na)));
1223 break;
1224 }
1225 if (LocaleCompare(attribute,"compression") == 0)
1226 {
1227 sp=SvPOK(sval) ? ParseMagickOption(MagickCompressOptions,
1228 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1229 if (sp < 0)
1230 {
1231 ThrowPerlException(exception,OptionError,
1232 "UnrecognizedImageCompression",SvPV(sval,na));
1233 break;
1234 }
1235 if (info)
1236 info->image_info->compression=(CompressionType) sp;
1237 for ( ; image; image=image->next)
1238 image->compression=(CompressionType) sp;
1239 break;
1240 }
1241 if (info)
1242 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1243 for ( ; image; image=image->next)
1244 SetImageProperty(image,attribute,SvPV(sval,na));
1245 break;
1246 }
1247 case 'D':
1248 case 'd':
1249 {
1250 if (LocaleCompare(attribute,"debug") == 0)
1251 {
1252 SetLogEventMask(SvPV(sval,na));
1253 break;
1254 }
1255 if (LocaleCompare(attribute,"delay") == 0)
1256 {
1257 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1258 for ( ; image; image=image->next)
1259 {
1260 image->delay=(unsigned long) (geometry_info.rho+0.5);
1261 if ((flags & SigmaValue) != 0)
1262 image->ticks_per_second=(unsigned long) (geometry_info.sigma+0.5);
1263 }
1264 break;
1265 }
1266 if (LocaleCompare(attribute,"disk-limit") == 0)
1267 {
1268 MagickSizeType
1269 limit;
1270
1271 limit=MagickResourceInfinity;
1272 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1273 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1274 (void) SetMagickResourceLimit(DiskResource,limit);
1275 break;
1276 }
1277 if (LocaleCompare(attribute,"density") == 0)
1278 {
1279 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1280 {
1281 ThrowPerlException(exception,OptionError,"MissingGeometry",
1282 SvPV(sval,na));
1283 break;
1284 }
1285 if (info)
1286 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1287 for ( ; image; image=image->next)
1288 {
1289 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1290 image->x_resolution=geometry_info.rho;
1291 image->y_resolution=geometry_info.sigma;
1292 if ((flags & SigmaValue) == 0)
1293 image->y_resolution=image->x_resolution;
1294 }
1295 break;
1296 }
1297 if (LocaleCompare(attribute,"depth") == 0)
1298 {
1299 if (info)
1300 info->image_info->depth=SvIV(sval);
1301 for ( ; image; image=image->next)
1302 (void) SetImageDepth(image,SvIV(sval));
1303 break;
1304 }
1305 if (LocaleCompare(attribute,"dispose") == 0)
1306 {
1307 sp=SvPOK(sval) ? ParseMagickOption(MagickDisposeOptions,MagickFalse,
1308 SvPV(sval,na)) : SvIV(sval);
1309 if (sp < 0)
1310 {
1311 ThrowPerlException(exception,OptionError,
1312 "UnrecognizedDisposeMethod",SvPV(sval,na));
1313 break;
1314 }
1315 for ( ; image; image=image->next)
1316 image->dispose=(DisposeType) sp;
1317 break;
1318 }
1319 if (LocaleCompare(attribute,"dither") == 0)
1320 {
1321 if (info)
1322 {
1323 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,
1324 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1325 if (sp < 0)
1326 {
1327 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1328 SvPV(sval,na));
1329 break;
1330 }
1331 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1332 }
1333 break;
1334 }
1335 if (LocaleCompare(attribute,"display") == 0)
1336 {
1337 display:
1338 if (info)
1339 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1340 break;
1341 }
1342 if (info)
1343 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1344 for ( ; image; image=image->next)
1345 SetImageProperty(image,attribute,SvPV(sval,na));
1346 break;
1347 }
1348 case 'E':
1349 case 'e':
1350 {
1351 if (LocaleCompare(attribute,"endian") == 0)
1352 {
1353 sp=SvPOK(sval) ? ParseMagickOption(MagickEndianOptions,MagickFalse,
1354 SvPV(sval,na)) : SvIV(sval);
1355 if (sp < 0)
1356 {
1357 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1358 SvPV(sval,na));
1359 break;
1360 }
1361 if (info)
1362 info->image_info->endian=(EndianType) sp;
1363 for ( ; image; image=image->next)
1364 image->endian=(EndianType) sp;
1365 break;
1366 }
1367 if (LocaleCompare(attribute,"extract") == 0)
1368 {
1369 /*
1370 Set image extract geometry.
1371 */
1372 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1373 break;
1374 }
1375 if (info)
1376 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1377 for ( ; image; image=image->next)
1378 SetImageProperty(image,attribute,SvPV(sval,na));
1379 break;
1380 }
1381 case 'F':
1382 case 'f':
1383 {
1384 if (LocaleCompare(attribute,"filename") == 0)
1385 {
1386 if (info)
1387 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
1388 MaxTextExtent);
1389 for ( ; image; image=image->next)
1390 (void) CopyMagickString(image->filename,SvPV(sval,na),
1391 MaxTextExtent);
1392 break;
1393 }
1394 if (LocaleCompare(attribute,"file") == 0)
1395 {
1396 FILE
1397 *file;
1398
1399 PerlIO
1400 *io_info;
1401
1402 if (info == (struct PackageInfo *) NULL)
1403 break;
1404 io_info=IoIFP(sv_2io(sval));
1405 if (io_info == (PerlIO *) NULL)
1406 {
1407 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1408 PackageName);
1409 break;
1410 }
1411 file=PerlIO_findFILE(io_info);
1412 if (file == (FILE *) NULL)
1413 {
1414 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1415 PackageName);
1416 break;
1417 }
1418 SetImageInfoFile(info->image_info,file);
1419 break;
1420 }
1421 if (LocaleCompare(attribute,"fill") == 0)
1422 {
1423 if (info)
1424 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1425 break;
1426 }
1427 if (LocaleCompare(attribute,"font") == 0)
1428 {
1429 if (info)
1430 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1431 break;
1432 }
1433 if (LocaleCompare(attribute,"foreground") == 0)
1434 break;
1435 if (LocaleCompare(attribute,"fuzz") == 0)
1436 {
1437 if (info)
1438 info->image_info->fuzz=StringToDouble(SvPV(sval,na),QuantumRange);
1439 for ( ; image; image=image->next)
1440 image->fuzz=StringToDouble(SvPV(sval,na),QuantumRange);
1441 break;
1442 }
1443 if (info)
1444 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1445 for ( ; image; image=image->next)
1446 SetImageProperty(image,attribute,SvPV(sval,na));
1447 break;
1448 }
1449 case 'G':
1450 case 'g':
1451 {
1452 if (LocaleCompare(attribute,"gamma") == 0)
1453 {
1454 for ( ; image; image=image->next)
1455 image->gamma=SvNV(sval);
1456 break;
1457 }
1458 if (LocaleCompare(attribute,"gravity") == 0)
1459 {
1460 sp=SvPOK(sval) ? ParseMagickOption(MagickGravityOptions,MagickFalse,
1461 SvPV(sval,na)) : SvIV(sval);
1462 if (sp < 0)
1463 {
1464 ThrowPerlException(exception,OptionError,
1465 "UnrecognizedGravityType",SvPV(sval,na));
1466 break;
1467 }
1468 for ( ; image; image=image->next)
1469 image->gravity=(GravityType) sp;
1470 break;
1471 }
1472 if (LocaleCompare(attribute,"green-primary") == 0)
1473 {
1474 for ( ; image; image=image->next)
1475 {
1476 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1477 image->chromaticity.green_primary.x=geometry_info.rho;
1478 image->chromaticity.green_primary.y=geometry_info.sigma;
1479 if ((flags & SigmaValue) == 0)
1480 image->chromaticity.green_primary.y=
1481 image->chromaticity.green_primary.x;
1482 }
1483 break;
1484 }
1485 if (info)
1486 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1487 for ( ; image; image=image->next)
1488 SetImageProperty(image,attribute,SvPV(sval,na));
1489 break;
1490 }
1491 case 'I':
1492 case 'i':
1493 {
1494 if (LocaleNCompare(attribute,"index",5) == 0)
1495 {
1496 IndexPacket
1497 *indexes;
1498
1499 int
1500 items;
1501
1502 long
1503 index;
1504
1505 register PixelPacket
1506 *p;
1507
1508 CacheView
1509 *image_view;
1510
1511 for ( ; image; image=image->next)
1512 {
1513 if (image->storage_class != PseudoClass)
1514 continue;
1515 x=0;
1516 y=0;
1517 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1518 image_view=OpenCacheView(image);
1519 p=GetCacheViewPixels(image_view,x,y,1,1);
1520 if (p != (PixelPacket *) NULL)
1521 {
1522 indexes=GetCacheViewIndexes(image_view);
1523 items=sscanf(SvPV(sval,na),"%ld",&index);
1524 if ((index >= 0) && (index < (long) image->colors))
1525 *indexes=(IndexPacket) index;
1526 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1527 }
1528 image_view=CloseCacheView(image_view);
1529 }
1530 break;
1531 }
1532 if (LocaleCompare(attribute,"iterations") == 0)
1533 {
1534 iterations:
1535 for ( ; image; image=image->next)
1536 image->iterations=SvIV(sval);
1537 break;
1538 }
1539 if (LocaleCompare(attribute,"interlace") == 0)
1540 {
1541 sp=SvPOK(sval) ? ParseMagickOption(MagickInterlaceOptions,MagickFalse,
1542 SvPV(sval,na)) : SvIV(sval);
1543 if (sp < 0)
1544 {
1545 ThrowPerlException(exception,OptionError,
1546 "UnrecognizedInterlaceType",SvPV(sval,na));
1547 break;
1548 }
1549 if (info)
1550 info->image_info->interlace=(InterlaceType) sp;
1551 for ( ; image; image=image->next)
1552 image->interlace=(InterlaceType) sp;
1553 break;
1554 }
1555 if (info)
1556 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1557 for ( ; image; image=image->next)
1558 SetImageProperty(image,attribute,SvPV(sval,na));
1559 break;
1560 }
1561 case 'L':
1562 case 'l':
1563 {
1564 if (LocaleCompare(attribute,"label") == 0)
1565 {
1566 for ( ; image; image=image->next)
1567 (void) SetImageProperty(image,"label",InterpretImageProperties(
1568 info ? info->image_info : (ImageInfo *) NULL,image,
1569 SvPV(sval,na)));
1570 break;
1571 }
1572 if (LocaleCompare(attribute,"loop") == 0)
1573 goto iterations;
1574 if (info)
1575 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1576 for ( ; image; image=image->next)
1577 SetImageProperty(image,attribute,SvPV(sval,na));
1578 break;
1579 }
1580 case 'M':
1581 case 'm':
1582 {
1583 if (LocaleCompare(attribute,"magick") == 0)
1584 {
1585 if (info)
1586 (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
1587 "%.1024s:",SvPV(sval,na));
1588 for ( ; image; image=image->next)
1589 (void) CopyMagickString(image->magick,SvPV(sval,na),MaxTextExtent);
1590 break;
1591 }
1592 if (LocaleCompare(attribute,"map-limit") == 0)
1593 {
1594 MagickSizeType
1595 limit;
1596
1597 limit=MagickResourceInfinity;
1598 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1599 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1600 (void) SetMagickResourceLimit(MapResource,limit);
1601 break;
1602 }
1603 if (LocaleCompare(attribute,"mask") == 0)
1604 {
1605 Image
1606 *mask;
1607
1608 mask=(Image *) NULL;
1609 if (SvPOK(sval))
1610 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1611 for ( ; image; image=image->next)
1612 SetImageMask(image,mask);
1613 break;
1614 }
1615 if (LocaleCompare(attribute,"mattecolor") == 0)
1616 {
1617 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
1618 if (info)
1619 info->image_info->matte_color=target_color;
1620 for ( ; image; image=image->next)
1621 image->matte_color=target_color;
1622 break;
1623 }
1624 if (LocaleCompare(attribute,"matte") == 0)
1625 {
1626 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1627 SvPV(sval,na)) : SvIV(sval);
1628 if (sp < 0)
1629 {
1630 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1631 SvPV(sval,na));
1632 break;
1633 }
1634 for ( ; image; image=image->next)
1635 image->matte=sp != 0 ? MagickTrue : MagickFalse;
1636 break;
1637 }
1638 if (LocaleCompare(attribute,"memory-limit") == 0)
1639 {
1640 MagickSizeType
1641 limit;
1642
1643 limit=MagickResourceInfinity;
1644 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1645 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
1646 (void) SetMagickResourceLimit(MemoryResource,limit);
1647 break;
1648 }
1649 if (LocaleCompare(attribute,"monochrome") == 0)
1650 {
1651 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
1652 SvPV(sval,na)) : SvIV(sval);
1653 if (sp < 0)
1654 {
1655 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1656 SvPV(sval,na));
1657 break;
1658 }
1659 if (info)
1660 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1661 for ( ; image; image=image->next)
1662 (void) SetImageType(image,BilevelType);
1663 break;
1664 }
1665 if (info)
1666 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1667 for ( ; image; image=image->next)
1668 SetImageProperty(image,attribute,SvPV(sval,na));
1669 break;
1670 }
1671 case 'O':
1672 case 'o':
1673 {
1674 if (LocaleCompare(attribute,"option") == 0)
1675 {
1676 if (info)
1677 DefineImageOption(info->image_info,SvPV(sval,na));
1678 break;
1679 }
1680 if (LocaleCompare(attribute,"orientation") == 0)
1681 {
1682 sp=SvPOK(sval) ? ParseMagickOption(MagickOrientationOptions,
1683 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1684 if (sp < 0)
1685 {
1686 ThrowPerlException(exception,OptionError,
1687 "UnrecognizedOrientationType",SvPV(sval,na));
1688 break;
1689 }
1690 if (info)
1691 info->image_info->orientation=(OrientationType) sp;
1692 for ( ; image; image=image->next)
1693 image->orientation=(OrientationType) sp;
1694 break;
1695 }
1696 if (info)
1697 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1698 for ( ; image; image=image->next)
1699 SetImageProperty(image,attribute,SvPV(sval,na));
1700 break;
1701 }
1702 case 'P':
1703 case 'p':
1704 {
1705 if (LocaleCompare(attribute,"page") == 0)
1706 {
1707 char
1708 *geometry;
1709
1710 geometry=GetPageGeometry(SvPV(sval,na));
1711 if (info)
1712 (void) CloneString(&info->image_info->page,geometry);
1713 for ( ; image; image=image->next)
1714 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1715 geometry=(char *) RelinquishMagickMemory(geometry);
1716 break;
1717 }
1718 if (LocaleCompare(attribute,"pen") == 0)
1719 {
1720 if (info)
1721 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1722 break;
1723 }
1724 if (LocaleNCompare(attribute,"pixel",5) == 0)
1725 {
1726 int
1727 items;
1728
1729 MagickPixelPacket
1730 pixel;
1731
1732 register IndexPacket
1733 *indexes;
1734
1735 register PixelPacket
1736 *p;
1737
1738 CacheView
1739 *image_view;
1740
1741 for ( ; image; image=image->next)
1742 {
1743 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1744 break;
1745 x=0;
1746 y=0;
1747 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1748 image_view=OpenCacheView(image);
1749 p=GetCacheViewPixels(image_view,x,y,1,1);
1750 indexes=GetCacheViewIndexes(image_view);
1751 if (p != (PixelPacket *) NULL)
1752 {
1753 if ((strchr(SvPV(sval,na),',') == 0) ||
1754 (strchr(SvPV(sval,na),')') != 0))
1755 QueryMagickColor(SvPV(sval,na),&pixel,exception);
1756 else
1757 {
1758 GetMagickPixelPacket(image,&pixel);
1759 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1760 pixel.red=geometry_info.rho;
1761 if ((flags & SigmaValue) != 0)
1762 pixel.green=geometry_info.sigma;
1763 if ((flags & XiValue) != 0)
1764 pixel.blue=geometry_info.xi;
1765 if ((flags & PsiValue) != 0)
1766 pixel.opacity=geometry_info.psi;
1767 if ((flags & ChiValue) != 0)
1768 pixel.index=geometry_info.chi;
1769 }
1770 p->red=RoundToQuantum(pixel.red);
1771 p->green=RoundToQuantum(pixel.green);
1772 p->blue=RoundToQuantum(pixel.blue);
1773 p->opacity=RoundToQuantum(pixel.opacity);
1774 if (((image->colorspace == CMYKColorspace) ||
1775 (image->storage_class == PseudoClass)) &&
1776 (indexes != (IndexPacket *) NULL))
1777 *indexes=RoundToQuantum(pixel.index);
1778 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1779 }
1780 image_view=CloseCacheView(image_view);
1781 }
1782 break;
1783 }
1784 if (LocaleCompare(attribute,"pointsize") == 0)
1785 {
1786 if (info)
1787 {
1788 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1789 info->image_info->pointsize=geometry_info.rho;
1790 }
1791 break;
1792 }
1793 if (LocaleCompare(attribute,"preview") == 0)
1794 {
1795 sp=SvPOK(sval) ? ParseMagickOption(MagickPreviewOptions,MagickFalse,
1796 SvPV(sval,na)) : SvIV(sval);
1797 if (sp < 0)
1798 {
1799 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1800 SvPV(sval,na));
1801 break;
1802 }
1803 if (info)
1804 info->image_info->preview_type=(PreviewType) sp;
1805 break;
1806 }
1807 if (info)
1808 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1809 for ( ; image; image=image->next)
1810 SetImageProperty(image,attribute,SvPV(sval,na));
1811 break;
1812 }
1813 case 'Q':
1814 case 'q':
1815 {
1816 if (LocaleCompare(attribute,"quality") == 0)
1817 {
1818 if (info)
1819 info->image_info->quality=SvIV(sval);
1820 for ( ; image; image=image->next)
1821 image->quality=SvIV(sval);
1822 break;
1823 }
1824 if (info)
1825 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1826 for ( ; image; image=image->next)
1827 SetImageProperty(image,attribute,SvPV(sval,na));
1828 break;
1829 }
1830 case 'R':
1831 case 'r':
1832 {
1833 if (LocaleCompare(attribute,"red-primary") == 0)
1834 {
1835 for ( ; image; image=image->next)
1836 {
1837 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1838 image->chromaticity.red_primary.x=geometry_info.rho;
1839 image->chromaticity.red_primary.y=geometry_info.sigma;
1840 if ((flags & SigmaValue) == 0)
1841 image->chromaticity.red_primary.y=
1842 image->chromaticity.red_primary.x;
1843 }
1844 break;
1845 }
1846 if (LocaleCompare(attribute,"render") == 0)
1847 {
1848 sp=SvPOK(sval) ? ParseMagickOption(MagickIntentOptions,MagickFalse,
1849 SvPV(sval,na)) : SvIV(sval);
1850 if (sp < 0)
1851 {
1852 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1853 SvPV(sval,na));
1854 break;
1855 }
1856 for ( ; image; image=image->next)
1857 image->rendering_intent=(RenderingIntent) sp;
1858 break;
1859 }
1860 if (LocaleCompare(attribute,"repage") == 0)
1861 {
1862 RectangleInfo
1863 geometry;
1864
1865 for ( ; image; image=image->next)
1866 {
1867 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1868 if ((flags & WidthValue) != 0)
1869 {
1870 if ((flags & HeightValue) == 0)
1871 geometry.height=geometry.width;
1872 image->page.width=geometry.width;
1873 image->page.height=geometry.height;
1874 }
1875 if ((flags & AspectValue) != 0)
1876 {
1877 if ((flags & XValue) != 0)
1878 image->page.x+=geometry.x;
1879 if ((flags & YValue) != 0)
1880 image->page.y+=geometry.y;
1881 }
1882 else
1883 {
1884 if ((flags & XValue) != 0)
1885 {
1886 image->page.x=geometry.x;
1887 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1888 image->page.width=image->columns+geometry.x;
1889 }
1890 if ((flags & YValue) != 0)
1891 {
1892 image->page.y=geometry.y;
1893 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1894 image->page.height=image->rows+geometry.y;
1895 }
1896 }
1897 }
1898 break;
1899 }
1900 if (info)
1901 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1902 for ( ; image; image=image->next)
1903 SetImageProperty(image,attribute,SvPV(sval,na));
1904 break;
1905 }
1906 case 'S':
1907 case 's':
1908 {
1909 if (LocaleCompare(attribute,"sampling-factor") == 0)
1910 {
1911 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1912 {
1913 ThrowPerlException(exception,OptionError,"MissingGeometry",
1914 SvPV(sval,na));
1915 break;
1916 }
1917 if (info)
1918 (void) CloneString(&info->image_info->sampling_factor,
1919 SvPV(sval,na));
1920 break;
1921 }
1922 if (LocaleCompare(attribute,"scene") == 0)
1923 {
1924 for ( ; image; image=image->next)
1925 image->scene=SvIV(sval);
1926 break;
1927 }
1928 if (LocaleCompare(attribute,"subimage") == 0)
1929 {
1930 if (info)
1931 info->image_info->subimage=SvIV(sval);
1932 break;
1933 }
1934 if (LocaleCompare(attribute,"subrange") == 0)
1935 {
1936 if (info)
1937 info->image_info->subrange=SvIV(sval);
1938 break;
1939 }
1940 if (LocaleCompare(attribute,"server") == 0)
1941 goto display;
1942 if (LocaleCompare(attribute,"size") == 0)
1943 {
1944 if (info)
1945 {
1946 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1947 {
1948 ThrowPerlException(exception,OptionError,"MissingGeometry",
1949 SvPV(sval,na));
1950 break;
1951 }
1952 (void) CloneString(&info->image_info->size,SvPV(sval,na));
1953 }
1954 break;
1955 }
1956 if (LocaleCompare(attribute,"stroke") == 0)
1957 {
1958 if (info)
1959 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
1960 break;
1961 }
1962 if (info)
1963 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1964 for ( ; image; image=image->next)
1965 SetImageProperty(image,attribute,SvPV(sval,na));
1966 break;
1967 }
1968 case 'T':
1969 case 't':
1970 {
1971 if (LocaleCompare(attribute,"tile") == 0)
1972 {
1973 if (info)
1974 (void) CloneString(&info->image_info->tile,SvPV(sval,na));
1975 break;
1976 }
1977 if (LocaleCompare(attribute,"texture") == 0)
1978 {
1979 if (info)
1980 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
1981 break;
1982 }
1983 if (LocaleCompare(attribute,"tile-offset") == 0)
1984 {
1985 char
1986 *geometry;
1987
1988 geometry=GetPageGeometry(SvPV(sval,na));
1989 if (info)
1990 (void) CloneString(&info->image_info->page,geometry);
1991 for ( ; image; image=image->next)
1992 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
1993 exception);
1994 geometry=(char *) RelinquishMagickMemory(geometry);
1995 break;
1996 }
1997 if (LocaleCompare(attribute,"time-limit") == 0)
1998 {
1999 MagickSizeType
2000 limit;
2001
2002 limit=MagickResourceInfinity;
2003 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2004 limit=(MagickSizeType) StringToDouble(SvPV(sval,na),100.0);
2005 (void) SetMagickResourceLimit(TimeResource,limit);
2006 break;
2007 }
2008 if (LocaleCompare(attribute,"transparent-color") == 0)
2009 {
2010 (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception);
2011 if (info)
2012 info->image_info->transparent_color=target_color;
2013 for ( ; image; image=image->next)
2014 image->transparent_color=target_color;
2015 break;
2016 }
2017 if (LocaleCompare(attribute,"type") == 0)
2018 {
2019 sp=SvPOK(sval) ? ParseMagickOption(MagickTypeOptions,MagickFalse,
2020 SvPV(sval,na)) : SvIV(sval);
2021 if (sp < 0)
2022 {
2023 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2024 SvPV(sval,na));
2025 break;
2026 }
2027 if (info)
2028 info->image_info->type=(ImageType) sp;
2029 for ( ; image; image=image->next)
2030 SetImageType(image,(ImageType) sp);
2031 break;
2032 }
2033 if (info)
2034 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2035 for ( ; image; image=image->next)
2036 SetImageProperty(image,attribute,SvPV(sval,na));
2037 break;
2038 }
2039 case 'U':
2040 case 'u':
2041 {
2042 if (LocaleCompare(attribute,"units") == 0)
2043 {
2044 sp=SvPOK(sval) ? ParseMagickOption(MagickResolutionOptions,
2045 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2046 if (sp < 0)
2047 {
2048 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2049 SvPV(sval,na));
2050 break;
2051 }
2052 if (info)
2053 info->image_info->units=(ResolutionType) sp;
2054 for ( ; image; image=image->next)
2055 {
2056 ResolutionType
2057 units;
2058
2059 units=(ResolutionType) sp;
2060 if (image->units != units)
2061 switch (image->units)
2062 {
2063 case UndefinedResolution:
2064 case PixelsPerInchResolution:
2065 {
2066 if (units == PixelsPerCentimeterResolution)
2067 {
2068 image->x_resolution*=2.54;
2069 image->y_resolution*=2.54;
2070 }
2071 break;
2072 }
2073 case PixelsPerCentimeterResolution:
2074 {
2075 if (units == PixelsPerInchResolution)
2076 {
2077 image->x_resolution/=2.54;
2078 image->y_resolution/=2.54;
2079 }
2080 break;
2081 }
2082 }
2083 image->units=units;
2084 }
2085 break;
2086 }
2087 if (info)
2088 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2089 for ( ; image; image=image->next)
2090 SetImageProperty(image,attribute,SvPV(sval,na));
2091 break;
2092 }
2093 case 'V':
2094 case 'v':
2095 {
2096 if (LocaleCompare(attribute,"verbose") == 0)
2097 {
2098 sp=SvPOK(sval) ? ParseMagickOption(MagickBooleanOptions,MagickFalse,
2099 SvPV(sval,na)) : SvIV(sval);
2100 if (sp < 0)
2101 {
2102 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2103 SvPV(sval,na));
2104 break;
2105 }
2106 if (info)
2107 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2108 break;
2109 }
2110 if (LocaleCompare(attribute,"view") == 0)
2111 {
2112 if (info)
2113 (void) CloneString(&info->image_info->view,SvPV(sval,na));
2114 break;
2115 }
2116 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2117 {
2118 sp=SvPOK(sval) ? ParseMagickOption(MagickVirtualPixelOptions,
2119 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2120 if (sp < 0)
2121 {
2122 ThrowPerlException(exception,OptionError,
2123 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2124 break;
2125 }
2126 if (info)
2127 info->image_info->virtual_pixel_method=(VirtualPixelMethod) sp;
2128 for ( ; image; image=image->next)
2129 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp);
2130 break;
2131 }
2132 if (info)
2133 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2134 for ( ; image; image=image->next)
2135 SetImageProperty(image,attribute,SvPV(sval,na));
2136 break;
2137 }
2138 case 'W':
2139 case 'w':
2140 {
2141 if (LocaleCompare(attribute,"white-point") == 0)
2142 {
2143 for ( ; image; image=image->next)
2144 {
2145 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2146 image->chromaticity.white_point.x=geometry_info.rho;
2147 image->chromaticity.white_point.y=geometry_info.sigma;
2148 if ((flags & SigmaValue) == 0)
2149 image->chromaticity.white_point.y=
2150 image->chromaticity.white_point.x;
2151 }
2152 break;
2153 }
2154 if (info)
2155 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2156 for ( ; image; image=image->next)
2157 SetImageProperty(image,attribute,SvPV(sval,na));
2158 break;
2159 }
2160 default:
2161 {
2162 if (info)
2163 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2164 for ( ; image; image=image->next)
2165 SetImageProperty(image,attribute,SvPV(sval,na));
2166 break;
2167 }
2168 }
2169}
2170
2171/*
2172%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2173% %
2174% %
2175% %
2176% S e t u p L i s t %
2177% %
2178% %
2179% %
2180%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2181%
2182% Method SetupList returns the list of all the images linked by their
2183% image->next and image->previous link lists for use with ImageMagick. If
2184% info is non-NULL, an info structure is returned in *info. If
2185% reference_vector is non-NULL,an array of SV* are returned in
2186% *reference_vector. Reference_vector is used when the images are going to be
2187% replaced with new Image*'s.
2188%
2189% The format of the SetupList routine is:
2190%
2191% Image *SetupList(SV *reference,struct PackageInfo **info,
2192% SV ***reference_vector,ExceptionInfo *exception)
2193%
2194% A description of each parameter follows:
2195%
2196% o list: a list of strings.
2197%
2198% o string: a character string.
2199%
2200% o exception: Return any errors or warnings in this structure.
2201%
2202*/
2203static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2204 SV ***reference_vector,ExceptionInfo *exception)
2205{
2206 Image
2207 *image;
2208
2209 long
2210 current,
2211 last;
2212
2213 if (reference_vector)
2214 *reference_vector=NULL;
2215 if (info)
2216 *info=NULL;
2217 current=0;
2218 last=0;
2219 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2220 if (info && (SvTYPE(reference) == SVt_PVAV))
2221 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2222 exception);
2223 return(image);
2224}
2225
2226/*
2227%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2228% %
2229% %
2230% %
2231% s t r E Q c a s e %
2232% %
2233% %
2234% %
2235%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2236%
2237% strEQcase() compares two strings and returns 0 if they are the
2238% same or if the second string runs out first. The comparison is case
2239% insensitive.
2240%
2241% The format of the strEQcase routine is:
2242%
2243% long strEQcase(const char *p,const char *q)
2244%
2245% A description of each parameter follows:
2246%
2247% o p: a character string.
2248%
2249% o q: a character string.
2250%
2251%
2252*/
2253static long strEQcase(const char *p,const char *q)
2254{
2255 char
2256 c;
2257
2258 register long
2259 i;
2260
2261 for (i=0 ; (c=(*q)) != 0; i++)
2262 {
2263 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2264 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2265 return(0);
2266 p++;
2267 q++;
2268 }
2269 return(((*q == 0) && (*p == 0)) ? i : 0);
2270}
2271
2272/*
2273%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2274% %
2275% %
2276% %
2277% I m a g e : : M a g i c k %
2278% %
2279% %
2280% %
2281%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2282%
2283%
2284*/
2285MODULE = Image::Magick PACKAGE = Image::Magick
2286
2287PROTOTYPES: ENABLE
2288
2289BOOT:
2290 MagickCoreGenesis("PerlMagick",MagickFalse);
2291 SetWarningHandler(NULL);
2292 SetErrorHandler(NULL);
2293 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2294 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2295
2296void
2297UNLOAD()
2298 PPCODE:
2299 {
2300 if (magick_registry != (SplayTreeInfo *) NULL)
2301 magick_registry=DestroySplayTree(magick_registry);
2302 MagickCoreTerminus();
2303 }
2304
2305double
2306constant(name,argument)
2307 char *name
2308 long argument
2309
2310#
2311###############################################################################
2312# #
2313# #
2314# #
2315# A n i m a t e #
2316# #
2317# #
2318# #
2319###############################################################################
2320#
2321#
2322void
2323Animate(ref,...)
2324 Image::Magick ref=NO_INIT
2325 ALIAS:
2326 AnimateImage = 1
2327 animate = 2
2328 animateimage = 3
2329 PPCODE:
2330 {
2331 ExceptionInfo
2332 *exception;
2333
2334 Image
2335 *image;
2336
2337 register long
2338 i;
2339
2340 struct PackageInfo
2341 *info,
2342 *package_info;
2343
2344 SV
2345 *perl_exception,
2346 *reference;
2347
2348 exception=AcquireExceptionInfo();
2349 perl_exception=newSVpv("",0);
2350 package_info=(struct PackageInfo *) NULL;
2351 if (sv_isobject(ST(0)) == 0)
2352 {
2353 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2354 PackageName);
2355 goto PerlException;
2356 }
2357 reference=SvRV(ST(0));
2358 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2359 if (image == (Image *) NULL)
2360 {
2361 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2362 PackageName);
2363 goto PerlException;
2364 }
2365 package_info=ClonePackageInfo(info,exception);
2366 if (items == 2)
2367 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2368 else
2369 if (items > 2)
2370 for (i=2; i < items; i+=2)
2371 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2372 exception);
2373 (void) AnimateImages(package_info->image_info,image);
2374 (void) CatchImageException(image);
2375 InheritException(exception,&image->exception);
2376
2377 PerlException:
2378 if (package_info != (struct PackageInfo *) NULL)
2379 DestroyPackageInfo(package_info);
2380 InheritPerlException(exception,perl_exception);
2381 exception=DestroyExceptionInfo(exception);
2382 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2383 SvPOK_on(perl_exception);
2384 ST(0)=sv_2mortal(perl_exception);
2385 XSRETURN(1);
2386 }
2387
2388#
2389###############################################################################
2390# #
2391# #
2392# #
2393# A p p e n d #
2394# #
2395# #
2396# #
2397###############################################################################
2398#
2399#
2400void
2401Append(ref,...)
2402 Image::Magick ref=NO_INIT
2403 ALIAS:
2404 AppendImage = 1
2405 append = 2
2406 appendimage = 3
2407 PPCODE:
2408 {
2409 AV
2410 *av;
2411
2412 char
2413 *attribute;
2414
2415 ExceptionInfo
2416 *exception;
2417
2418 HV
2419 *hv;
2420
2421 Image
2422 *image;
2423
2424 long
2425 stack;
2426
2427 register long
2428 i;
2429
2430 struct PackageInfo
2431 *info;
2432
2433 SV
2434 *av_reference,
2435 *perl_exception,
2436 *reference,
2437 *rv,
2438 *sv;
2439
2440 exception=AcquireExceptionInfo();
2441 perl_exception=newSVpv("",0);
2442 attribute=NULL;
2443 av=NULL;
2444 if (sv_isobject(ST(0)) == 0)
2445 {
2446 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2447 PackageName);
2448 goto PerlException;
2449 }
2450 reference=SvRV(ST(0));
2451 hv=SvSTASH(reference);
2452 av=newAV();
2453 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2454 SvREFCNT_dec(av);
2455 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2456 if (image == (Image *) NULL)
2457 {
2458 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2459 PackageName);
2460 goto PerlException;
2461 }
2462 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2463 /*
2464 Get options.
2465 */
2466 stack=MagickTrue;
2467 for (i=2; i < items; i+=2)
2468 {
2469 attribute=(char *) SvPV(ST(i-1),na);
2470 switch (*attribute)
2471 {
2472 case 'S':
2473 case 's':
2474 {
2475 if (LocaleCompare(attribute,"stack") == 0)
2476 {
2477 stack=ParseMagickOption(MagickBooleanOptions,MagickFalse,
2478 SvPV(ST(i),na));
2479 if (stack < 0)
2480 {
2481 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2482 SvPV(ST(i),na));
2483 return;
2484 }
2485 break;
2486 }
2487 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2488 attribute);
2489 break;
2490 }
2491 default:
2492 {
2493 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2494 attribute);
2495 break;
2496 }
2497 }
2498 }
2499 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2500 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2501 goto PerlException;
2502 for ( ; image; image=image->next)
2503 {
2504 AddImageToRegistry(image);
2505 rv=newRV(sv);
2506 av_push(av,sv_bless(rv,hv));
2507 SvREFCNT_dec(sv);
2508 }
2509 exception=DestroyExceptionInfo(exception);
2510 ST(0)=av_reference;
2511 SvREFCNT_dec(perl_exception);
2512 XSRETURN(1);
2513
2514 PerlException:
2515 InheritPerlException(exception,perl_exception);
2516 exception=DestroyExceptionInfo(exception);
2517 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2518 SvPOK_on(perl_exception);
2519 ST(0)=sv_2mortal(perl_exception);
2520 XSRETURN(1);
2521 }
2522
2523#
2524###############################################################################
2525# #
2526# #
2527# #
2528# A v e r a g e #
2529# #
2530# #
2531# #
2532###############################################################################
2533#
2534#
2535void
2536Average(ref)
2537 Image::Magick ref=NO_INIT
2538 ALIAS:
2539 AverageImage = 1
2540 average = 2
2541 averageimage = 3
2542 PPCODE:
2543 {
2544 AV
2545 *av;
2546
2547 char
2548 *p;
2549
2550 ExceptionInfo
2551 *exception;
2552
2553 HV
2554 *hv;
2555
2556 Image
2557 *image;
2558
2559 struct PackageInfo
2560 *info;
2561
2562 SV
2563 *perl_exception,
2564 *reference,
2565 *rv,
2566 *sv;
2567
2568 exception=AcquireExceptionInfo();
2569 perl_exception=newSVpv("",0);
2570 if (sv_isobject(ST(0)) == 0)
2571 {
2572 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2573 PackageName);
2574 goto PerlException;
2575 }
2576 reference=SvRV(ST(0));
2577 hv=SvSTASH(reference);
2578 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2579 if (image == (Image *) NULL)
2580 {
2581 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2582 PackageName);
2583 goto PerlException;
2584 }
2585 image=AverageImages(image,exception);
2586 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2587 goto PerlException;
2588 /*
2589 Create blessed Perl array for the returned image.
2590 */
2591 av=newAV();
2592 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2593 SvREFCNT_dec(av);
2594 AddImageToRegistry(image);
2595 rv=newRV(sv);
2596 av_push(av,sv_bless(rv,hv));
2597 SvREFCNT_dec(sv);
2598 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2599 (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
2600 "average-%.*s",(int) (MaxTextExtent-9),
2601 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2602 (void) CopyMagickString(image->filename,info->image_info->filename,
2603 MaxTextExtent);
2604 SetImageInfo(info->image_info,MagickFalse,exception);
2605 exception=DestroyExceptionInfo(exception);
2606 SvREFCNT_dec(perl_exception);
2607 XSRETURN(1);
2608
2609 PerlException:
2610 InheritPerlException(exception,perl_exception);
2611 exception=DestroyExceptionInfo(exception);
2612 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2613 SvPOK_on(perl_exception);
2614 ST(0)=sv_2mortal(perl_exception);
2615 XSRETURN(1);
2616 }
2617
2618#
2619###############################################################################
2620# #
2621# #
2622# #
2623# B l o b T o I m a g e #
2624# #
2625# #
2626# #
2627###############################################################################
2628#
2629#
2630void
2631BlobToImage(ref,...)
2632 Image::Magick ref=NO_INIT
2633 ALIAS:
2634 BlobToImage = 1
2635 blobtoimage = 2
2636 blobto = 3
2637 PPCODE:
2638 {
2639 AV
2640 *av;
2641
2642 char
2643 **keep,
2644 **list;
2645
2646 ExceptionInfo
2647 *exception;
2648
2649 HV
2650 *hv;
2651
2652 Image
2653 *image;
2654
2655 long
2656 ac,
2657 n,
2658 number_images;
2659
2660 register char
2661 **p;
2662
2663 register long
2664 i;
2665
2666 STRLEN
2667 *length;
2668
2669 struct PackageInfo
2670 *info;
2671
2672 SV
2673 *perl_exception,
2674 *reference,
2675 *rv,
2676 *sv;
2677
2678 exception=AcquireExceptionInfo();
2679 perl_exception=newSVpv("",0);
2680 number_images=0;
2681 ac=(items < 2) ? 1 : items-1;
2682 length=(STRLEN *) NULL;
2683 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2684 if (list == (char **) NULL)
2685 {
2686 ThrowPerlException(exception,ResourceLimitError,
2687 "MemoryAllocationFailed",PackageName);
2688 goto PerlException;
2689 }
2690 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2691 if (length == (STRLEN *) NULL)
2692 {
2693 ThrowPerlException(exception,ResourceLimitError,
2694 "MemoryAllocationFailed",PackageName);
2695 goto PerlException;
2696 }
2697 if (sv_isobject(ST(0)) == 0)
2698 {
2699 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2700 PackageName);
2701 goto PerlException;
2702 }
2703 reference=SvRV(ST(0));
2704 hv=SvSTASH(reference);
2705 if (SvTYPE(reference) != SVt_PVAV)
2706 {
2707 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2708 PackageName);
2709 goto PerlException;
2710 }
2711 av=(AV *) reference;
2712 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2713 exception);
2714 n=1;
2715 if (items <= 1)
2716 {
2717 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2718 goto PerlException;
2719 }
2720 for (n=0, i=0; i < ac; i++)
2721 {
2722 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2723 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2724 {
2725 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2726 continue;
2727 }
2728 n++;
2729 }
2730 list[n]=(char *) NULL;
2731 keep=list;
2732 for (i=number_images=0; i < n; i++)
2733 {
2734 image=BlobToImage(info->image_info,list[i],length[i],exception);
2735 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2736 break;
2737 for ( ; image; image=image->next)
2738 {
2739 AddImageToRegistry(image);
2740 rv=newRV(sv);
2741 av_push(av,sv_bless(rv,hv));
2742 SvREFCNT_dec(sv);
2743 number_images++;
2744 }
2745 }
2746 /*
2747 Free resources.
2748 */
2749 for (i=0; i < n; i++)
2750 if (list[i] != (char *) NULL)
2751 for (p=keep; list[i] != *p++; )
2752 if (*p == (char *) NULL)
2753 {
2754 list[i]=(char *) RelinquishMagickMemory(list[i]);
2755 break;
2756 }
2757
2758 PerlException:
2759 if (list)
2760 list=(char **) RelinquishMagickMemory(list);
2761 if (length)
2762 length=(STRLEN *) RelinquishMagickMemory(length);
2763 InheritPerlException(exception,perl_exception);
2764 exception=DestroyExceptionInfo(exception);
2765 sv_setiv(perl_exception,(IV) number_images);
2766 SvPOK_on(perl_exception);
2767 ST(0)=sv_2mortal(perl_exception);
2768 XSRETURN(1);
2769 }
2770
2771#
2772###############################################################################
2773# #
2774# #
2775# #
2776# C l o n e #
2777# #
2778# #
2779# #
2780###############################################################################
2781#
2782#
2783void
2784Clone(ref)
2785 Image::Magick ref=NO_INIT
2786 ALIAS:
2787 CopyImage = 1
2788 copy = 2
2789 copyimage = 3
2790 CloneImage = 4
2791 clone = 5
2792 cloneimage = 6
2793 Clone = 7
2794 PPCODE:
2795 {
2796 AV
2797 *av;
2798
2799 ExceptionInfo
2800 *exception;
2801
2802 HV
2803 *hv;
2804
2805 Image
2806 *clone,
2807 *image;
2808
2809 struct PackageInfo
2810 *info;
2811
2812 SV
2813 *perl_exception,
2814 *reference,
2815 *rv,
2816 *sv;
2817
2818 exception=AcquireExceptionInfo();
2819 perl_exception=newSVpv("",0);
2820 if (sv_isobject(ST(0)) == 0)
2821 {
2822 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2823 PackageName);
2824 goto PerlException;
2825 }
2826 reference=SvRV(ST(0));
2827 hv=SvSTASH(reference);
2828 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2829 if (image == (Image *) NULL)
2830 {
2831 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2832 PackageName);
2833 goto PerlException;
2834 }
2835 /*
2836 Create blessed Perl array for the returned image.
2837 */
2838 av=newAV();
2839 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2840 SvREFCNT_dec(av);
2841 for ( ; image; image=image->next)
2842 {
2843 clone=CloneImage(image,0,0,MagickTrue,exception);
2844 if ((clone == (Image *) NULL) || (exception->severity >= ErrorException))
2845 break;
2846 AddImageToRegistry(clone);
2847 rv=newRV(sv);
2848 av_push(av,sv_bless(rv,hv));
2849 SvREFCNT_dec(sv);
2850 }
2851 exception=DestroyExceptionInfo(exception);
2852 SvREFCNT_dec(perl_exception);
2853 XSRETURN(1);
2854
2855 PerlException:
2856 InheritPerlException(exception,perl_exception);
2857 exception=DestroyExceptionInfo(exception);
2858 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2859 SvPOK_on(perl_exception);
2860 ST(0)=sv_2mortal(perl_exception);
2861 XSRETURN(1);
2862 }
2863
2864#
2865###############################################################################
2866# #
2867# #
2868# #
2869# C L O N E #
2870# #
2871# #
2872# #
2873###############################################################################
2874#
2875#
2876void
2877CLONE(ref,...)
2878 SV *ref;
2879 CODE:
2880 {
2881 if (magick_registry != (SplayTreeInfo *) NULL)
2882 {
2883 register Image
2884 *p;
2885
2886 ResetSplayTreeIterator(magick_registry);
2887 p=(Image *) GetNextKeyInSplayTree(magick_registry);
2888 while (p != (Image *) NULL)
2889 {
2890 ReferenceImage(p);
2891 p=(Image *) GetNextKeyInSplayTree(magick_registry);
2892 }
2893 }
2894 }
2895
2896#
2897###############################################################################
2898# #
2899# #
2900# #
2901# C o a l e s c e #
2902# #
2903# #
2904# #
2905###############################################################################
2906#
2907#
2908void
2909Coalesce(ref)
2910 Image::Magick ref=NO_INIT
2911 ALIAS:
2912 CoalesceImage = 1
2913 coalesce = 2
2914 coalesceimage = 3
2915 PPCODE:
2916 {
2917 AV
2918 *av;
2919
2920 ExceptionInfo
2921 *exception;
2922
2923 HV
2924 *hv;
2925
2926 Image
2927 *image;
2928
2929 struct PackageInfo
2930 *info;
2931
2932 SV
2933 *av_reference,
2934 *perl_exception,
2935 *reference,
2936 *rv,
2937 *sv;
2938
2939 exception=AcquireExceptionInfo();
2940 perl_exception=newSVpv("",0);
2941 if (sv_isobject(ST(0)) == 0)
2942 {
2943 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2944 PackageName);
2945 goto PerlException;
2946 }
2947 reference=SvRV(ST(0));
2948 hv=SvSTASH(reference);
2949 av=newAV();
2950 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2951 SvREFCNT_dec(av);
2952 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2953 if (image == (Image *) NULL)
2954 {
2955 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2956 PackageName);
2957 goto PerlException;
2958 }
2959 image=CoalesceImages(image,exception);
2960 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
2961 goto PerlException;
2962 for ( ; image; image=image->next)
2963 {
2964 AddImageToRegistry(image);
2965 rv=newRV(sv);
2966 av_push(av,sv_bless(rv,hv));
2967 SvREFCNT_dec(sv);
2968 }
2969 exception=DestroyExceptionInfo(exception);
2970 ST(0)=av_reference;
2971 SvREFCNT_dec(perl_exception);
2972 XSRETURN(1);
2973
2974 PerlException:
2975 InheritPerlException(exception,perl_exception);
2976 exception=DestroyExceptionInfo(exception);
2977 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2978 SvPOK_on(perl_exception);
2979 ST(0)=sv_2mortal(perl_exception);
2980 XSRETURN(1);
2981 }
2982
2983#
2984###############################################################################
2985# #
2986# #
2987# #
2988# C o m p a r e #
2989# #
2990# #
2991# #
2992###############################################################################
2993#
2994#
2995void
2996Compare(ref,...)
2997 Image::Magick ref=NO_INIT
2998 ALIAS:
2999 CompareImage = 1
3000 compare = 2
3001 compareimage = 3
3002 PPCODE:
3003 {
3004 AV
3005 *av;
3006
3007 char
3008 *attribute;
3009
3010 ChannelType
3011 channel;
3012
3013 double
3014 distortion;
3015
3016 ExceptionInfo
3017 *exception;
3018
3019 HV
3020 *hv;
3021
3022 Image
3023 *difference_image,
3024 *image,
3025 *reconstruct_image;
3026
3027 long
3028 option;
3029
3030 MetricType
3031 metric;
3032
3033 register long
3034 i;
3035
3036 struct PackageInfo
3037 *info;
3038
3039 SV
3040 *av_reference,
3041 *perl_exception,
3042 *reference,
3043 *rv,
3044 *sv;
3045
3046 exception=AcquireExceptionInfo();
3047 perl_exception=newSVpv("",0);
3048 av=NULL;
3049 attribute=NULL;
3050 if (sv_isobject(ST(0)) == 0)
3051 {
3052 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3053 PackageName);
3054 goto PerlException;
3055 }
3056 reference=SvRV(ST(0));
3057 hv=SvSTASH(reference);
3058 av=newAV();
3059 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3060 SvREFCNT_dec(av);
3061 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3062 if (image == (Image *) NULL)
3063 {
3064 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3065 PackageName);
3066 goto PerlException;
3067 }
3068 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3069 /*
3070 Get attribute.
3071 */
3072 channel=DefaultChannels;
3073 reconstruct_image=image;
3074 metric=RootMeanSquaredErrorMetric;
3075 for (i=2; i < items; i+=2)
3076 {
3077 attribute=(char *) SvPV(ST(i-1),na);
3078 switch (*attribute)
3079 {
3080 case 'C':
3081 case 'c':
3082 {
3083 if (LocaleCompare(attribute,"channel") == 0)
3084 {
3085 long
3086 option;
3087
3088 option=ParseChannelOption(SvPV(ST(i),na));
3089 if (option < 0)
3090 {
3091 ThrowPerlException(exception,OptionError,
3092 "UnrecognizedType",SvPV(ST(i),na));
3093 return;
3094 }
3095 channel=(ChannelType) option;
3096 break;
3097 }
3098 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3099 attribute);
3100 break;
3101 }
3102 case 'F':
3103 case 'f':
3104 {
3105 if (LocaleCompare(attribute,"fuzz") == 0)
3106 {
3107 image->fuzz=StringToDouble(SvPV(ST(i),na),100.0);
3108 break;
3109 }
3110 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3111 attribute);
3112 break;
3113 }
3114 case 'I':
3115 case 'i':
3116 {
3117 if (LocaleCompare(attribute,"image") == 0)
3118 {
3119 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3120 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3121 }
3122 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3123 attribute);
3124 break;
3125 }
3126 case 'M':
3127 case 'm':
3128 {
3129 if (LocaleCompare(attribute,"metric") == 0)
3130 {
3131 option=ParseMagickOption(MagickMetricOptions,MagickFalse,
3132 SvPV(ST(i),na));
3133 if (option < 0)
3134 {
3135 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3136 SvPV(ST(i),na));
3137 break;
3138 }
3139 metric=(MetricType) option;
3140 break;
3141 }
3142 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3143 attribute);
3144 break;
3145 }
3146 default:
3147 {
3148 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3149 attribute);
3150 break;
3151 }
3152 }
3153 }
3154 difference_image=CompareImageChannels(image,reconstruct_image,channel,
3155 metric,&distortion,exception);
3156 if (difference_image != (Image *) NULL)
3157 {
3158 difference_image->error.mean_error_per_pixel=distortion;
3159 AddImageToRegistry(difference_image);
3160 rv=newRV(sv);
3161 av_push(av,sv_bless(rv,hv));
3162 SvREFCNT_dec(sv);
3163 }
3164 exception=DestroyExceptionInfo(exception);
3165 ST(0)=av_reference;
3166 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3167 XSRETURN(1);
3168
3169 PerlException:
3170 InheritPerlException(exception,perl_exception);
3171 exception=DestroyExceptionInfo(exception);
3172 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3173 SvPOK_on(perl_exception);
3174 ST(0)=sv_2mortal(perl_exception);
3175 XSRETURN(1);
3176 }
3177
3178#
3179###############################################################################
3180# #
3181# #
3182# #
3183# C o m p a r e L a y e r s #
3184# #
3185# #
3186# #
3187###############################################################################
3188#
3189#
3190void
3191CompareLayers(ref)
3192 Image::Magick ref=NO_INIT
3193 ALIAS:
3194 CompareImageLayers = 1
3195 comparelayers = 2
3196 compareimagelayers = 3
3197 PPCODE:
3198 {
3199 AV
3200 *av;
3201
3202 char
3203 *attribute;
3204
3205 ExceptionInfo
3206 *exception;
3207
3208 HV
3209 *hv;
3210
3211 Image
3212 *image;
3213
3214 long
3215 option;
3216
3217 ImageLayerMethod
3218 method;
3219
3220 register long
3221 i;
3222
3223 struct PackageInfo
3224 *info;
3225
3226 SV
3227 *av_reference,
3228 *perl_exception,
3229 *reference,
3230 *rv,
3231 *sv;
3232
3233 exception=AcquireExceptionInfo();
3234 perl_exception=newSVpv("",0);
3235 if (sv_isobject(ST(0)) == 0)
3236 {
3237 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3238 PackageName);
3239 goto PerlException;
3240 }
3241 reference=SvRV(ST(0));
3242 hv=SvSTASH(reference);
3243 av=newAV();
3244 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3245 SvREFCNT_dec(av);
3246 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3247 if (image == (Image *) NULL)
3248 {
3249 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3250 PackageName);
3251 goto PerlException;
3252 }
3253 method=CompareAnyLayer;
3254 for (i=2; i < items; i+=2)
3255 {
3256 attribute=(char *) SvPV(ST(i-1),na);
3257 switch (*attribute)
3258 {
3259 case 'M':
3260 case 'm':
3261 {
3262 if (LocaleCompare(attribute,"method") == 0)
3263 {
3264 option=ParseMagickOption(MagickLayerOptions,MagickFalse,
3265 SvPV(ST(i),na));
3266 if (option < 0)
3267 {
3268 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3269 SvPV(ST(i),na));
3270 break;
3271 }
3272 method=(ImageLayerMethod) option;
3273 break;
3274 }
3275 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3276 attribute);
3277 break;
3278 }
3279 default:
3280 {
3281 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3282 attribute);
3283 break;
3284 }
3285 }
3286 }
3287 image=CompareImageLayers(image,method,exception);
3288 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
3289 goto PerlException;
3290 for ( ; image; image=image->next)
3291 {
3292 AddImageToRegistry(image);
3293 rv=newRV(sv);
3294 av_push(av,sv_bless(rv,hv));
3295 SvREFCNT_dec(sv);
3296 }
3297 exception=DestroyExceptionInfo(exception);
3298 ST(0)=av_reference;
3299 SvREFCNT_dec(perl_exception);
3300 XSRETURN(1);
3301
3302 PerlException:
3303 InheritPerlException(exception,perl_exception);
3304 exception=DestroyExceptionInfo(exception);
3305 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3306 SvPOK_on(perl_exception);
3307 ST(0)=sv_2mortal(perl_exception);
3308 XSRETURN(1);
3309 }
3310
3311#
3312###############################################################################
3313# #
3314# #
3315# #
3316# D e s t r o y #
3317# #
3318# #
3319# #
3320###############################################################################
3321#
3322#
3323void
3324DESTROY(ref)
3325 Image::Magick ref=NO_INIT
3326 PPCODE:
3327 {
3328 SV
3329 *reference;
3330
3331 if (sv_isobject(ST(0)) == 0)
3332 croak("ReferenceIsNotMyType");
3333 reference=SvRV(ST(0));
3334 switch (SvTYPE(reference))
3335 {
3336 case SVt_PVAV:
3337 {
3338 char
3339 message[MaxTextExtent];
3340
3341 struct PackageInfo
3342 *info;
3343
3344 HV
3345 *hv;
3346
3347 GV
3348 **gvp;
3349
3350 SV
3351 *sv;
3352
3353 /*
3354 Array (AV *) reference
3355 */
3356 (void) FormatMagickString(message,MaxTextExtent,"package%s%lx",
3357 XS_VERSION,(long) reference);
3358 hv=gv_stashpv(PackageName, FALSE);
3359 if (!hv)
3360 break;
3361 gvp=(GV **) hv_fetch(hv,message,strlen(message),FALSE);
3362 if (!gvp)
3363 break;
3364 sv=GvSV(*gvp);
3365 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3366 {
3367 info=(struct PackageInfo *) SvIV(sv);
3368 DestroyPackageInfo(info);
3369 }
3370 hv_delete(hv,message,strlen(message),G_DISCARD);
3371 break;
3372 }
3373 case SVt_PVMG:
3374 {
3375 Image
3376 *image;
3377
3378 /*
3379 Blessed scalar = (Image *) SvIV(reference)
3380 */
3381 image=(Image *) SvIV(reference);
3382 if (image != (Image *) NULL)
3383 DeleteImageFromRegistry(reference,image);
3384 break;
3385 }
3386 default:
3387 break;
3388 }
3389 }
3390
3391#
3392###############################################################################
3393# #
3394# #
3395# #
3396# D i s p l a y #
3397# #
3398# #
3399# #
3400###############################################################################
3401#
3402#
3403void
3404Display(ref,...)
3405 Image::Magick ref=NO_INIT
3406 ALIAS:
3407 DisplayImage = 1
3408 display = 2
3409 displayimage = 3
3410 PPCODE:
3411 {
3412 ExceptionInfo
3413 *exception;
3414
3415 Image
3416 *image;
3417
3418 register long
3419 i;
3420
3421 struct PackageInfo
3422 *info,
3423 *package_info;
3424
3425 SV
3426 *perl_exception,
3427 *reference;
3428
3429 exception=AcquireExceptionInfo();
3430 perl_exception=newSVpv("",0);
3431 package_info=(struct PackageInfo *) NULL;
3432 if (sv_isobject(ST(0)) == 0)
3433 {
3434 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3435 PackageName);
3436 goto PerlException;
3437 }
3438 reference=SvRV(ST(0));
3439 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3440 if (image == (Image *) NULL)
3441 {
3442 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3443 PackageName);
3444 goto PerlException;
3445 }
3446 package_info=ClonePackageInfo(info,exception);
3447 if (items == 2)
3448 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3449 else
3450 if (items > 2)
3451 for (i=2; i < items; i+=2)
3452 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3453 exception);
3454 (void) DisplayImages(package_info->image_info,image);
3455 (void) CatchImageException(image);
3456 InheritException(exception,&image->exception);
3457
3458 PerlException:
3459 if (package_info != (struct PackageInfo *) NULL)
3460 DestroyPackageInfo(package_info);
3461 InheritPerlException(exception,perl_exception);
3462 exception=DestroyExceptionInfo(exception);
3463 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3464 SvPOK_on(perl_exception);
3465 ST(0)=sv_2mortal(perl_exception);
3466 XSRETURN(1);
3467 }
3468
3469#
3470###############################################################################
3471# #
3472# #
3473# #
3474# F l a t t e n #
3475# #
3476# #
3477# #
3478###############################################################################
3479#
3480#
3481void
3482Flatten(ref)
3483 Image::Magick ref=NO_INIT
3484 ALIAS:
3485 FlattenImage = 1
3486 flatten = 2
3487 flattenimage = 3
3488 PPCODE:
3489 {
3490 AV
3491 *av;
3492
3493 char
3494 *attribute,
3495 *p;
3496
3497 ExceptionInfo
3498 *exception;
3499
3500 HV
3501 *hv;
3502
3503 Image
3504 *image;
3505
3506 PixelPacket
3507 background_color;
3508
3509 register long
3510 i;
3511
3512 struct PackageInfo
3513 *info;
3514
3515 SV
3516 *perl_exception,
3517 *reference,
3518 *rv,
3519 *sv;
3520
3521 exception=AcquireExceptionInfo();
3522 perl_exception=newSVpv("",0);
3523 if (sv_isobject(ST(0)) == 0)
3524 {
3525 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3526 PackageName);
3527 goto PerlException;
3528 }
3529 reference=SvRV(ST(0));
3530 hv=SvSTASH(reference);
3531 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3532 if (image == (Image *) NULL)
3533 {
3534 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3535 PackageName);
3536 goto PerlException;
3537 }
3538 background_color=image->background_color;
3539 if (items == 2)
3540 (void) QueryColorDatabase((char *) SvPV(ST(1),na),&background_color,
3541 exception);
3542 else
3543 for (i=2; i < items; i+=2)
3544 {
3545 attribute=(char *) SvPV(ST(i-1),na);
3546 switch (*attribute)
3547 {
3548 case 'B':
3549 case 'b':
3550 {
3551 if (LocaleCompare(attribute,"background") == 0)
3552 {
3553 (void) QueryColorDatabase((char *) SvPV(ST(1),na),
3554 &background_color,exception);
3555 break;
3556 }
3557 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3558 attribute);
3559 break;
3560 }
3561 default:
3562 {
3563 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3564 attribute);
3565 break;
3566 }
3567 }
3568 }
3569 image->background_color=background_color;
3570 image=MergeImageLayers(image,FlattenLayer,exception);
3571 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
3572 goto PerlException;
3573 /*
3574 Create blessed Perl array for the returned image.
3575 */
3576 av=newAV();
3577 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3578 SvREFCNT_dec(av);
3579 AddImageToRegistry(image);
3580 rv=newRV(sv);
3581 av_push(av,sv_bless(rv,hv));
3582 SvREFCNT_dec(sv);
3583 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3584 (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
3585 "flatten-%.*s",(int) (MaxTextExtent-9),
3586 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3587 (void) CopyMagickString(image->filename,info->image_info->filename,
3588 MaxTextExtent);
3589 SetImageInfo(info->image_info,MagickFalse,exception);
3590 exception=DestroyExceptionInfo(exception);
3591 SvREFCNT_dec(perl_exception);
3592 XSRETURN(1);
3593
3594 PerlException:
3595 InheritPerlException(exception,perl_exception);
3596 exception=DestroyExceptionInfo(exception);
3597 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3598 SvPOK_on(perl_exception); /* return messages in string context */
3599 ST(0)=sv_2mortal(perl_exception);
3600 XSRETURN(1);
3601 }
3602
3603#
3604###############################################################################
3605# #
3606# #
3607# #
3608# F x #
3609# #
3610# #
3611# #
3612###############################################################################
3613#
3614#
3615void
3616Fx(ref,...)
3617 Image::Magick ref=NO_INIT
3618 ALIAS:
3619 FxImage = 1
3620 fx = 2
3621 fximage = 3
3622 PPCODE:
3623 {
3624 AV
3625 *av;
3626
3627 char
3628 *attribute,
3629 expression[MaxTextExtent];
3630
3631 ChannelType
3632 channel;
3633
3634 ExceptionInfo
3635 *exception;
3636
3637 HV
3638 *hv;
3639
3640 Image
3641 *image;
3642
3643 register long
3644 i;
3645
3646 struct PackageInfo
3647 *info;
3648
3649 SV
3650 *av_reference,
3651 *perl_exception,
3652 *reference,
3653 *rv,
3654 *sv;
3655
3656 exception=AcquireExceptionInfo();
3657 perl_exception=newSVpv("",0);
3658 attribute=NULL;
3659 av=NULL;
3660 if (sv_isobject(ST(0)) == 0)
3661 {
3662 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3663 PackageName);
3664 goto PerlException;
3665 }
3666 reference=SvRV(ST(0));
3667 hv=SvSTASH(reference);
3668 av=newAV();
3669 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3670 SvREFCNT_dec(av);
3671 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3672 if (image == (Image *) NULL)
3673 {
3674 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3675 PackageName);
3676 goto PerlException;
3677 }
3678 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3679 /*
3680 Get options.
3681 */
3682 channel=DefaultChannels;
3683 (void) CopyMagickString(expression,"u",MaxTextExtent);
3684 if (items == 2)
3685 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MaxTextExtent);
3686 else
3687 for (i=2; i < items; i+=2)
3688 {
3689 attribute=(char *) SvPV(ST(i-1),na);
3690 switch (*attribute)
3691 {
3692 case 'C':
3693 case 'c':
3694 {
3695 if (LocaleCompare(attribute,"channel") == 0)
3696 {
3697 long
3698 option;
3699
3700 option=ParseChannelOption(SvPV(ST(i),na));
3701 if (option < 0)
3702 {
3703 ThrowPerlException(exception,OptionError,
3704 "UnrecognizedType",SvPV(ST(i),na));
3705 return;
3706 }
3707 channel=(ChannelType) option;
3708 break;
3709 }
3710 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3711 attribute);
3712 break;
3713 }
3714 case 'E':
3715 case 'e':
3716 {
3717 if (LocaleCompare(attribute,"expression") == 0)
3718 {
3719 (void) CopyMagickString(expression,SvPV(ST(i),na),
3720 MaxTextExtent);
3721 break;
3722 }
3723 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3724 attribute);
3725 break;
3726 }
3727 default:
3728 {
3729 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3730 attribute);
3731 break;
3732 }
3733 }
3734 }
3735 image=FxImageChannel(image,channel,expression,exception);
3736 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
3737 goto PerlException;
3738 for ( ; image; image=image->next)
3739 {
3740 AddImageToRegistry(image);
3741 rv=newRV(sv);
3742 av_push(av,sv_bless(rv,hv));
3743 SvREFCNT_dec(sv);
3744 }
3745 exception=DestroyExceptionInfo(exception);
3746 ST(0)=av_reference;
3747 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3748 XSRETURN(1);
3749
3750 PerlException:
3751 InheritPerlException(exception,perl_exception);
3752 exception=DestroyExceptionInfo(exception);
3753 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3754 SvPOK_on(perl_exception);
3755 ST(0)=sv_2mortal(perl_exception);
3756 XSRETURN(1);
3757 }
3758
3759#
3760###############################################################################
3761# #
3762# #
3763# #
3764# G e t #
3765# #
3766# #
3767# #
3768###############################################################################
3769#
3770#
3771void
3772Get(ref,...)
3773 Image::Magick ref=NO_INIT
3774 ALIAS:
3775 GetAttributes = 1
3776 GetAttribute = 2
3777 get = 3
3778 getattributes = 4
3779 getattribute = 5
3780 PPCODE:
3781 {
3782 char
3783 *attribute,
3784 color[MaxTextExtent];
3785
3786 const char
3787 *value;
3788
3789 ExceptionInfo
3790 *exception;
3791
3792 Image
3793 *image;
3794
3795 long
3796 j;
3797
3798 register long
3799 i;
3800
3801 struct PackageInfo
3802 *info;
3803
3804 SV
3805 *perl_exception,
3806 *reference,
3807 *s;
3808
3809 exception=AcquireExceptionInfo();
3810 perl_exception=newSVpv("",0);
3811 if (sv_isobject(ST(0)) == 0)
3812 {
3813 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3814 PackageName);
3815 XSRETURN_EMPTY;
3816 }
3817 reference=SvRV(ST(0));
3818 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3819 if (image == (Image *) NULL && !info)
3820 XSRETURN_EMPTY;
3821 EXTEND(sp,items);
3822 for (i=1; i < items; i++)
3823 {
3824 attribute=(char *) SvPV(ST(i),na);
3825 s=NULL;
3826 switch (*attribute)
3827 {
3828 case 'A':
3829 case 'a':
3830 {
3831 if (LocaleCompare(attribute,"adjoin") == 0)
3832 {
3833 if (info)
3834 s=newSViv((long) info->image_info->adjoin);
3835 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3836 continue;
3837 }
3838 if (LocaleCompare(attribute,"antialias") == 0)
3839 {
3840 if (info)
3841 s=newSViv((long) info->image_info->antialias);
3842 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3843 continue;
3844 }
3845 if (LocaleCompare(attribute,"area") == 0)
3846 {
3847 s=newSViv(GetMagickResource(AreaResource));
3848 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3849 continue;
3850 }
3851 if (LocaleCompare(attribute,"attenuate") == 0)
3852 {
3853 const char
3854 *value;
3855
3856 value=GetImageProperty(image,attribute);
3857 if (value != (const char *) NULL)
3858 s=newSVpv(value,0);
3859 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3860 continue;
3861 }
3862 if (LocaleCompare(attribute,"authenticate") == 0)
3863 {
3864 if (info)
3865 s=newSVpv(info->image_info->authenticate,0);
3866 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3867 continue;
3868 }
3869 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3870 attribute);
3871 break;
3872 }
3873 case 'B':
3874 case 'b':
3875 {
3876 if (LocaleCompare(attribute,"background") == 0)
3877 {
3878 if (image == (Image *) NULL)
3879 break;
3880 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
3881 QuantumFormat "," QuantumFormat "," QuantumFormat,
3882 image->background_color.red,image->background_color.green,
3883 image->background_color.blue,image->background_color.opacity);
3884 s=newSVpv(color,0);
3885 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3886 continue;
3887 }
3888 if (LocaleCompare(attribute,"base-columns") == 0)
3889 {
3890 if (image != (Image *) NULL)
3891 s=newSViv((long) image->magick_columns);
3892 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3893 continue;
3894 }
3895 if (LocaleCompare(attribute,"base-filename") == 0)
3896 {
3897 if (image != (Image *) NULL)
3898 s=newSVpv(image->magick_filename,0);
3899 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3900 continue;
3901 }
3902 if (LocaleCompare(attribute,"base-height") == 0)
3903 {
3904 if (image != (Image *) NULL)
3905 s=newSViv((long) image->magick_rows);
3906 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3907 continue;
3908 }
3909 if (LocaleCompare(attribute,"base-rows") == 0)
3910 {
3911 if (image != (Image *) NULL)
3912 s=newSViv((long) image->magick_rows);
3913 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3914 continue;
3915 }
3916 if (LocaleCompare(attribute,"base-width") == 0)
3917 {
3918 if (image != (Image *) NULL)
3919 s=newSViv((long) image->magick_columns);
3920 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3921 continue;
3922 }
3923 if (LocaleCompare(attribute,"bias") == 0)
3924 {
3925 if (image != (Image *) NULL)
3926 s=newSVnv(image->bias);
3927 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3928 continue;
3929 }
3930 if (LocaleCompare(attribute,"blue-primary") == 0)
3931 {
3932 if (image == (Image *) NULL)
3933 break;
3934 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
3935 image->chromaticity.blue_primary.x,
3936 image->chromaticity.blue_primary.y);
3937 s=newSVpv(color,0);
3938 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3939 continue;
3940 }
3941 if (LocaleCompare(attribute,"bordercolor") == 0)
3942 {
3943 if (image == (Image *) NULL)
3944 break;
3945 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
3946 QuantumFormat "," QuantumFormat "," QuantumFormat,
3947 image->border_color.red,image->border_color.green,
3948 image->border_color.blue,image->border_color.opacity);
3949 s=newSVpv(color,0);
3950 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3951 continue;
3952 }
3953 if (LocaleCompare(attribute,"bounding-box") == 0)
3954 {
3955 char
3956 geometry[MaxTextExtent];
3957
3958 RectangleInfo
3959 page;
3960
3961 if (image == (Image *) NULL)
3962 break;
3963 page=GetImageBoundingBox(image,&image->exception);
3964 (void) FormatMagickString(geometry,MaxTextExtent,
3965 "%lux%lu%+ld%+ld",page.width,page.height,page.x,page.y);
3966 s=newSVpv(geometry,0);
3967 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3968 continue;
3969 }
3970 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3971 attribute);
3972 break;
3973 }
3974 case 'C':
3975 case 'c':
3976 {
3977 if (LocaleCompare(attribute,"class") == 0)
3978 {
3979 if (image == (Image *) NULL)
3980 break;
3981 s=newSViv(image->storage_class);
3982 (void) sv_setpv(s,MagickOptionToMnemonic(MagickClassOptions,
3983 image->storage_class));
3984 SvIOK_on(s);
3985 PUSHs(s ? sv_2mortal(s) : &sv_undef);
3986 continue;
3987 }
3988 if (LocaleCompare(attribute,"clip-mask") == 0)
3989 {
3990 if (image != (Image *) NULL)
3991 {
3992 SV
3993 *sv;
3994
3995 if (image->mask == (Image *) NULL)
3996 ClipImage(image);
3997 if (image->mask != (Image *) NULL)
3998 {
3999 AddImageToRegistry(image->mask);
4000 s=sv_bless(newRV(sv),SvSTASH(reference));
4001 }
4002 }
4003 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4004 continue;
4005 }
4006 if (LocaleCompare(attribute,"clip-path") == 0)
4007 {
4008 if (image != (Image *) NULL)
4009 {
4010 SV
4011 *sv;
4012
4013 if (image->clip_mask == (Image *) NULL)
4014 ClipImage(image);
4015 if (image->clip_mask != (Image *) NULL)
4016 {
4017 AddImageToRegistry(image->clip_mask);
4018 s=sv_bless(newRV(sv),SvSTASH(reference));
4019 }
4020 }
4021 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4022 continue;
4023 }
4024 if (LocaleCompare(attribute,"compression") == 0)
4025 {
4026 j=info ? info->image_info->compression : image->compression;
4027 if (info)
4028 if (info->image_info->compression == UndefinedCompression)
4029 j=image->compression;
4030 s=newSViv(j);
4031 (void) sv_setpv(s,MagickOptionToMnemonic(MagickCompressOptions,
4032 j));
4033 SvIOK_on(s);
4034 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4035 continue;
4036 }
4037 if (LocaleCompare(attribute,"colorspace") == 0)
4038 {
4039 j=image ? image->colorspace : RGBColorspace;
4040 s=newSViv(j);
4041 (void) sv_setpv(s,MagickOptionToMnemonic(MagickColorspaceOptions,
4042 j));
4043 SvIOK_on(s);
4044 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4045 continue;
4046 }
4047 if (LocaleCompare(attribute,"colors") == 0)
4048 {
4049 if (image != (Image *) NULL)
4050 s=newSViv((long) GetNumberColors(image,(FILE *) NULL,
4051 &image->exception));
4052 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4053 continue;
4054 }
4055 if (LocaleNCompare(attribute,"colormap",8) == 0)
4056 {
4057 int
4058 items;
4059
4060 if (image == (Image *) NULL || !image->colormap)
4061 break;
4062 j=0;
4063 items=sscanf(attribute,"%*[^[][%ld",&j);
4064 if (j > (long) image->colors)
4065 j%=image->colors;
4066 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
4067 QuantumFormat "," QuantumFormat "," QuantumFormat,
4068 image->colormap[j].red,image->colormap[j].green,
4069 image->colormap[j].blue,image->colormap[j].opacity);
4070 s=newSVpv(color,0);
4071 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4072 continue;
4073 }
4074 if (LocaleCompare(attribute,"columns") == 0)
4075 {
4076 if (image != (Image *) NULL)
4077 s=newSViv((long) image->columns);
4078 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4079 continue;
4080 }
4081 if (LocaleCompare(attribute,"comment") == 0)
4082 {
4083 const char
4084 *value;
4085
4086 value=GetImageProperty(image,attribute);
4087 if (value != (const char *) NULL)
4088 s=newSVpv(value,0);
4089 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4090 continue;
4091 }
4092 if (LocaleCompare(attribute,"copyright") == 0)
4093 {
4094 s=newSVpv(GetMagickCopyright(),0);
4095 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4096 continue;
4097 }
4098 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4099 attribute);
4100 break;
4101 }
4102 case 'D':
4103 case 'd':
4104 {
4105 if (LocaleCompare(attribute,"density") == 0)
4106 {
4107 char
4108 geometry[MaxTextExtent];
4109
4110 if (image == (Image *) NULL)
4111 break;
4112 (void) FormatMagickString(geometry,MaxTextExtent,"%gx%g",
4113 image->x_resolution,image->y_resolution);
4114 s=newSVpv(geometry,0);
4115 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4116 continue;
4117 }
4118 if (LocaleCompare(attribute,"dispose") == 0)
4119 {
4120 if (image == (Image *) NULL)
4121 break;
4122
4123 s=newSViv(image->dispose);
4124 (void) sv_setpv(s,
4125 MagickOptionToMnemonic(MagickDisposeOptions,image->dispose));
4126 SvIOK_on(s);
4127 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4128 continue;
4129 }
4130 if (LocaleCompare(attribute,"delay") == 0)
4131 {
4132 if (image != (Image *) NULL)
4133 s=newSViv((long) image->delay);
4134 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4135 continue;
4136 }
4137 if (LocaleCompare(attribute,"depth") == 0)
4138 {
4139 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4140 if (image != (Image *) NULL)
4141 s=newSViv((long) GetImageDepth(image,&image->exception));
4142 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4143 continue;
4144 }
4145 if (LocaleCompare(attribute,"disk") == 0)
4146 {
4147 s=newSViv(GetMagickResource(DiskResource));
4148 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4149 continue;
4150 }
4151 if (LocaleCompare(attribute,"dither") == 0)
4152 {
4153 if (info)
4154 s=newSViv((long) info->image_info->dither);
4155 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4156 continue;
4157 }
4158 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4159 {
4160 if (info && info->image_info->server_name)
4161 s=newSVpv(info->image_info->server_name,0);
4162 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4163 continue;
4164 }
4165 if (LocaleCompare(attribute,"directory") == 0)
4166 {
4167 if (image && image->directory)
4168 s=newSVpv(image->directory,0);
4169 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4170 continue;
4171 }
4172 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4173 attribute);
4174 break;
4175 }
4176 case 'E':
4177 case 'e':
4178 {
4179 if (LocaleCompare(attribute,"elapsed-time") == 0)
4180 {
4181 if (image != (Image *) NULL)
4182 s=newSVnv(GetElapsedTime(&image->timer));
4183 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4184 continue;
4185 }
4186 if (LocaleCompare(attribute,"endian") == 0)
4187 {
4188 j=info ? info->image_info->endian : image->endian;
4189 s=newSViv(j);
4190 (void) sv_setpv(s,MagickOptionToMnemonic(MagickEndianOptions,j));
4191 SvIOK_on(s);
4192 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4193 continue;
4194 }
4195 if (LocaleCompare(attribute,"error") == 0)
4196 {
4197 if (image != (Image *) NULL)
4198 s=newSVnv(image->error.mean_error_per_pixel);
4199 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4200 continue;
4201 }
4202 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4203 attribute);
4204 break;
4205 }
4206 case 'F':
4207 case 'f':
4208 {
4209 if (LocaleCompare(attribute,"filesize") == 0)
4210 {
4211 if (image != (Image *) NULL)
4212 s=newSViv((long) GetBlobSize(image));
4213 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4214 continue;
4215 }
4216 if (LocaleCompare(attribute,"filename") == 0)
4217 {
4218 if (info && info->image_info->filename &&
4219 *info->image_info->filename)
4220 s=newSVpv(info->image_info->filename,0);
4221 if (image != (Image *) NULL)
4222 s=newSVpv(image->filename,0);
4223 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4224 continue;
4225 }
4226 if (LocaleCompare(attribute,"filter") == 0)
4227 {
4228 s=newSViv(image->filter);
4229 (void) sv_setpv(s,MagickOptionToMnemonic(MagickFilterOptions,
4230 image->filter));
4231 SvIOK_on(s);
4232 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4233 continue;
4234 }
4235 if (LocaleCompare(attribute,"font") == 0)
4236 {
4237 if (info && info->image_info->font)
4238 s=newSVpv(info->image_info->font,0);
4239 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4240 continue;
4241 }
4242 if (LocaleCompare(attribute,"foreground") == 0)
4243 continue;
4244 if (LocaleCompare(attribute,"format") == 0)
4245 {
4246 const MagickInfo
4247 *magick_info;
4248
4249 magick_info=(const MagickInfo *) NULL;
4250 if (info && (*info->image_info->magick != '\0'))
4251 magick_info=GetMagickInfo(info->image_info->magick,exception);
4252 if (image != (Image *) NULL)
4253 magick_info=GetMagickInfo(image->magick,&image->exception);
4254 if ((magick_info != (const MagickInfo *) NULL) &&
4255 (*magick_info->description != '\0'))
4256 s=newSVpv((char *) magick_info->description,0);
4257 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4258 continue;
4259 }
4260 if (LocaleCompare(attribute,"fuzz") == 0)
4261 {
4262 if (info)
4263 s=newSVnv(info->image_info->fuzz);
4264 if (image != (Image *) NULL)
4265 s=newSVnv(image->fuzz);
4266 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4267 continue;
4268 }
4269 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4270 attribute);
4271 break;
4272 }
4273 case 'G':
4274 case 'g':
4275 {
4276 if (LocaleCompare(attribute,"gamma") == 0)
4277 {
4278 if (image != (Image *) NULL)
4279 s=newSVnv(image->gamma);
4280 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4281 continue;
4282 }
4283 if (LocaleCompare(attribute,"geometry") == 0)
4284 {
4285 if (image && image->geometry)
4286 s=newSVpv(image->geometry,0);
4287 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4288 continue;
4289 }
4290 if (LocaleCompare(attribute,"gravity") == 0)
4291 {
4292 s=newSViv(image->gravity);
4293 (void) sv_setpv(s,
4294 MagickOptionToMnemonic(MagickGravityOptions,image->gravity));
4295 SvIOK_on(s);
4296 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4297 continue;
4298 }
4299 if (LocaleCompare(attribute,"green-primary") == 0)
4300 {
4301 if (image == (Image *) NULL)
4302 break;
4303 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4304 image->chromaticity.green_primary.x,
4305 image->chromaticity.green_primary.y);
4306 s=newSVpv(color,0);
4307 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4308 continue;
4309 }
4310 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4311 attribute);
4312 break;
4313 }
4314 case 'H':
4315 case 'h':
4316 {
4317 if (LocaleCompare(attribute,"height") == 0)
4318 {
4319 if (image != (Image *) NULL)
4320 s=newSViv((long) image->rows);
4321 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4322 continue;
4323 }
4324 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4325 attribute);
4326 break;
4327 }
4328 case 'I':
4329 case 'i':
4330 {
4331 if (LocaleCompare(attribute,"icc") == 0)
4332 {
4333 if (image != (Image *) NULL)
4334 {
4335 const StringInfo
4336 *profile;
4337
4338 profile=GetImageProfile(image,"icc");
4339 if (profile != (StringInfo *) NULL)
4340 s=newSVpv((const char *) GetStringInfoDatum(profile),
4341 GetStringInfoLength(profile));
4342 }
4343 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4344 continue;
4345 }
4346 if (LocaleCompare(attribute,"icm") == 0)
4347 {
4348 if (image != (Image *) NULL)
4349 {
4350 const StringInfo
4351 *profile;
4352
4353 profile=GetImageProfile(image,"icm");
4354 if (profile != (const StringInfo *) NULL)
4355 s=newSVpv((const char *) GetStringInfoDatum(profile),
4356 GetStringInfoLength(profile));
4357 }
4358 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4359 continue;
4360 }
4361 if (LocaleCompare(attribute,"id") == 0)
4362 {
4363 if (image != (Image *) NULL)
4364 s=newSViv(SetMagickRegistry(ImageRegistryType,image,0,
4365 &image->exception));
4366 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4367 continue;
4368 }
4369 if (LocaleNCompare(attribute,"index",5) == 0)
4370 {
4371 char
4372 name[MaxTextExtent];
4373
4374 int
4375 items;
4376
4377 long
4378 x,
4379 y;
4380
4381 register const IndexPacket
4382 *indexes;
4383
4384 register const PixelPacket
4385 *p;
4386
4387 CacheView
4388 *image_view;
4389
4390 if (image == (Image *) NULL)
4391 break;
4392 if (image->storage_class != PseudoClass)
4393 break;
4394 x=0;
4395 y=0;
4396 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
4397 image_view=OpenCacheView(image);
4398 p=AcquireCacheViewPixels(image_view,x,y,1,1,&image->exception);
4399 if (p != (const PixelPacket *) NULL)
4400 {
4401 indexes=AcquireCacheViewIndexes(image_view);
4402 (void) FormatMagickString(name,MaxTextExtent,QuantumFormat,
4403 *indexes);
4404 s=newSVpv(name,0);
4405 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4406 }
4407 image_view=CloseCacheView(image_view);
4408 continue;
4409 }
4410 if (LocaleCompare(attribute,"iptc") == 0)
4411 {
4412 if (image != (Image *) NULL)
4413 {
4414 const StringInfo
4415 *profile;
4416
4417 profile=GetImageProfile(image,"iptc");
4418 if (profile != (const StringInfo *) NULL)
4419 s=newSVpv((const char *) GetStringInfoDatum(profile),
4420 GetStringInfoLength(profile));
4421 }
4422 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4423 continue;
4424 }
4425 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
4426 {
4427 if (image != (Image *) NULL)
4428 s=newSViv((long) image->iterations);
4429 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4430 continue;
4431 }
4432 if (LocaleCompare(attribute,"interlace") == 0)
4433 {
4434 j=info ? info->image_info->interlace : image->interlace;
4435 s=newSViv(j);
4436 (void) sv_setpv(s,MagickOptionToMnemonic(MagickInterlaceOptions,
4437 j));
4438 SvIOK_on(s);
4439 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4440 continue;
4441 }
4442 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4443 attribute);
4444 break;
4445 }
4446 case 'L':
4447 case 'l':
4448 {
4449 if (LocaleCompare(attribute,"label") == 0)
4450 {
4451 const char
4452 *value;
4453
4454 if (image == (Image *) NULL)
4455 break;
4456 value=GetImageProperty(image,"Label");
4457 if (value != (const char *) NULL)
4458 s=newSVpv(value,0);
4459 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4460 continue;
4461 }
4462 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
4463 {
4464 if (image != (Image *) NULL)
4465 s=newSViv((long) image->iterations);
4466 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4467 continue;
4468 }
4469 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4470 attribute);
4471 break;
4472 }
4473 case 'M':
4474 case 'm':
4475 {
4476 if (LocaleCompare(attribute,"magick") == 0)
4477 {
4478 if (info && *info->image_info->magick)
4479 s=newSVpv(info->image_info->magick,0);
4480 if (image != (Image *) NULL)
4481 s=newSVpv(image->magick,0);
4482 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4483 continue;
4484 }
4485 if (LocaleCompare(attribute,"map") == 0)
4486 {
4487 s=newSViv(GetMagickResource(MapResource));
4488 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4489 continue;
4490 }
4491 if (LocaleCompare(attribute,"maximum-error") == 0)
4492 {
4493 if (image != (Image *) NULL)
4494 s=newSVnv(image->error.normalized_maximum_error);
4495 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4496 continue;
4497 }
4498 if (LocaleCompare(attribute,"memory") == 0)
4499 {
4500 s=newSViv(GetMagickResource(MemoryResource));
4501 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4502 continue;
4503 }
4504 if (LocaleCompare(attribute,"mean-error") == 0)
4505 {
4506 if (image != (Image *) NULL)
4507 s=newSVnv(image->error.normalized_mean_error);
4508 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4509 continue;
4510 }
4511 if (LocaleCompare(attribute,"mime") == 0)
4512 {
4513 if (info && *info->image_info->magick)
4514 s=newSVpv(MagickToMime(info->image_info->magick),0);
4515 if (image != (Image *) NULL)
4516 s=newSVpv(MagickToMime(image->magick),0);
4517 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4518 continue;
4519 }
4520 if (LocaleCompare(attribute,"monochrome") == 0)
4521 {
4522 if (image == (Image *) NULL)
4523 continue;
4524 j=info ? info->image_info->monochrome :
4525 IsMonochromeImage(image,&image->exception);
4526 s=newSViv(j);
4527 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4528 continue;
4529 }
4530 if (LocaleCompare(attribute,"mattecolor") == 0)
4531 {
4532 if (image == (Image *) NULL)
4533 break;
4534 (void) FormatMagickString(color,MaxTextExtent,QuantumFormat ","
4535 QuantumFormat "," QuantumFormat "," QuantumFormat,
4536 image->matte_color.red,image->matte_color.green,
4537 image->matte_color.blue,image->matte_color.opacity);
4538 s=newSVpv(color,0);
4539 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4540 continue;
4541 }
4542 if (LocaleCompare(attribute,"matte") == 0)
4543 {
4544 if (image != (Image *) NULL)
4545 s=newSViv((long) image->matte);
4546 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4547 continue;
4548 }
4549 if (LocaleCompare(attribute,"montage") == 0)
4550 {
4551 if (image && image->montage)
4552 s=newSVpv(image->montage,0);
4553 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4554 continue;
4555 }
4556 if (LocaleCompare(attribute,"mime") == 0)
4557 {
4558 const char
4559 *magick;
4560
4561 magick=NULL;
4562 if (info && *info->image_info->magick)
4563 magick=info->image_info->magick;
4564 if (image != (Image *) NULL)
4565 magick=image->magick;
4566 if (magick)
4567 {
4568 char
4569 *mime;
4570
4571 mime=MagickToMime(magick);
4572 s=newSVpv(mime,0);
4573 mime=(char *) RelinquishMagickMemory(mime);
4574 }
4575 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4576 continue;
4577 }
4578 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4579 attribute);
4580 break;
4581 }
4582 case 'O':
4583 case 'o':
4584 {
4585 if (LocaleCompare(attribute,"orientation") == 0)
4586 {
4587 j=info ? info->image_info->orientation : image->orientation;
4588 s=newSViv(j);
4589 (void) sv_setpv(s,MagickOptionToMnemonic(MagickOrientationOptions,
4590 j));
4591 SvIOK_on(s);
4592 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4593 continue;
4594 }
4595 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4596 attribute);
4597 break;
4598 }
4599 case 'P':
4600 case 'p':
4601 {
4602 if (LocaleCompare(attribute,"page") == 0)
4603 {
4604 if (info && info->image_info->page)
4605 s=newSVpv(info->image_info->page,0);
4606 if (image != (Image *) NULL)
4607 {
4608 char
4609 geometry[MaxTextExtent];
4610
4611 (void) FormatMagickString(geometry,MaxTextExtent,
4612 "%lux%lu%+ld%+ld",image->page.width,image->page.height,
4613 image->page.x,image->page.y);
4614 s=newSVpv(geometry,0);
4615 }
4616 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4617 continue;
4618 }
4619 if (LocaleCompare(attribute,"page.x") == 0)
4620 {
4621 if (image != (Image *) NULL)
4622 s=newSViv((long) image->page.x);
4623 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4624 continue;
4625 }
4626 if (LocaleCompare(attribute,"page.y") == 0)
4627 {
4628 if (image != (Image *) NULL)
4629 s=newSViv((long) image->page.y);
4630 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4631 continue;
4632 }
4633 if (LocaleNCompare(attribute,"pixel",5) == 0)
4634 {
4635 char
4636 tuple[MaxTextExtent];
4637
4638 int
4639 items;
4640
4641 long
4642 x,
4643 y;
4644
4645 register const PixelPacket
4646 *p;
4647
4648 register const IndexPacket
4649 *indexes;
4650
4651 if (image == (Image *) NULL)
4652 break;
4653 x=0;
4654 y=0;
4655 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
4656 p=GetVirtualPixels(image,x,y,1,1,exception);
4657 indexes=AcquireIndexes(image);
4658 if (image->colorspace != CMYKColorspace)
4659 (void) FormatMagickString(tuple,MaxTextExtent,QuantumFormat ","
4660 QuantumFormat "," QuantumFormat "," QuantumFormat,
4661 p->red,p->green,p->blue,p->opacity);
4662 else
4663 (void) FormatMagickString(tuple,MaxTextExtent,QuantumFormat ","
4664 QuantumFormat "," QuantumFormat "," QuantumFormat ","
4665 QuantumFormat,p->red,p->green,p->blue,*indexes,p->opacity);
4666 s=newSVpv(tuple,0);
4667 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4668 continue;
4669 }
4670 if (LocaleCompare(attribute,"pointsize") == 0)
4671 {
4672 if (info)
4673 s=newSViv((long) info->image_info->pointsize);
4674 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4675 continue;
4676 }
4677 if (LocaleCompare(attribute,"preview") == 0)
4678 {
4679 s=newSViv(info->image_info->preview_type);
4680 (void) sv_setpv(s,MagickOptionToMnemonic(MagickPreviewOptions,
4681 info->image_info->preview_type));
4682 SvIOK_on(s);
4683 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4684 continue;
4685 }
4686 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4687 attribute);
4688 break;
4689 }
4690 case 'Q':
4691 case 'q':
4692 {
4693 if (LocaleCompare(attribute,"quality") == 0)
4694 {
4695 if (info)
4696 s=newSViv((long) info->image_info->quality);
4697 if (image != (Image *) NULL)
4698 s=newSViv((long) image->quality);
4699 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4700 continue;
4701 }
4702 if (LocaleCompare(attribute,"quantum") == 0)
4703 {
4704 if (info)
4705 s=newSViv((long) MAGICKCORE_QUANTUM_DEPTH);
4706 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4707 continue;
4708 }
4709 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4710 attribute);
4711 break;
4712 }
4713 case 'R':
4714 case 'r':
4715 {
4716 if (LocaleCompare(attribute,"rendering-intent") == 0)
4717 {
4718 s=newSViv(image->rendering_intent);
4719 (void) sv_setpv(s,MagickOptionToMnemonic(MagickIntentOptions,
4720 image->rendering_intent));
4721 SvIOK_on(s);
4722 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4723 continue;
4724 }
4725 if (LocaleCompare(attribute,"red-primary") == 0)
4726 {
4727 if (image == (Image *) NULL)
4728 break;
4729 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4730 image->chromaticity.red_primary.x,
4731 image->chromaticity.red_primary.y);
4732 s=newSVpv(color,0);
4733 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4734 continue;
4735 }
4736 if (LocaleCompare(attribute,"rows") == 0)
4737 {
4738 if (image != (Image *) NULL)
4739 s=newSViv((long) image->rows);
4740 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4741 continue;
4742 }
4743 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4744 attribute);
4745 break;
4746 }
4747 case 'S':
4748 case 's':
4749 {
4750 if (LocaleCompare(attribute,"sampling-factor") == 0)
4751 {
4752 if (info && info->image_info->sampling_factor)
4753 s=newSVpv(info->image_info->sampling_factor,0);
4754 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4755 continue;
4756 }
4757 if (LocaleCompare(attribute,"subimage") == 0)
4758 {
4759 if (info)
4760 s=newSViv((long) info->image_info->subimage);
4761 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4762 continue;
4763 }
4764 if (LocaleCompare(attribute,"subrange") == 0)
4765 {
4766 if (info)
4767 s=newSViv((long) info->image_info->subrange);
4768 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4769 continue;
4770 }
4771 if (LocaleCompare(attribute,"server") == 0) /* same as display */
4772 {
4773 if (info && info->image_info->server_name)
4774 s=newSVpv(info->image_info->server_name,0);
4775 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4776 continue;
4777 }
4778 if (LocaleCompare(attribute,"size") == 0)
4779 {
4780 if (info && info->image_info->size)
4781 s=newSVpv(info->image_info->size,0);
4782 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4783 continue;
4784 }
4785 if (LocaleCompare(attribute,"scene") == 0)
4786 {
4787 if (image != (Image *) NULL)
4788 s=newSViv((long) image->scene);
4789 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4790 continue;
4791 }
4792 if (LocaleCompare(attribute,"scenes") == 0)
4793 {
4794 if (image != (Image *) NULL)
4795 s=newSViv((long) info->image_info->number_scenes);
4796 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4797 continue;
4798 }
4799 if (LocaleCompare(attribute,"signature") == 0)
4800 {
4801 const char
4802 *value;
4803
4804 if (image == (Image *) NULL)
4805 break;
4806 (void) SignatureImage(image);
4807 value=GetImageProperty(image,"Signature");
4808 if (value != (const char *) NULL)
4809 s=newSVpv(value,0);
4810 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4811 continue;
4812 }
4813 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4814 attribute);
4815 break;
4816 }
4817 case 'T':
4818 case 't':
4819 {
4820 if (LocaleCompare(attribute,"taint") == 0)
4821 {
4822 if (image != (Image *) NULL)
4823 s=newSViv((long) IsTaintImage(image));
4824 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4825 continue;
4826 }
4827 if (LocaleCompare(attribute,"tile") == 0)
4828 {
4829 if (info && info->image_info->tile)
4830 s=newSVpv(info->image_info->tile,0);
4831 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4832 continue;
4833 }
4834 if (LocaleCompare(attribute,"texture") == 0)
4835 {
4836 if (info && info->image_info->texture)
4837 s=newSVpv(info->image_info->texture,0);
4838 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4839 continue;
4840 }
4841 if (LocaleCompare(attribute,"total-ink-density") == 0)
4842 {
4843 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4844 if (image != (Image *) NULL)
4845 s=newSVnv(GetImageTotalInkDensity(image));
4846 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4847 continue;
4848 }
4849 if (LocaleCompare(attribute,"type") == 0)
4850 {
4851 if (image == (Image *) NULL)
4852 break;
4853 j=(long) GetImageType(image,&image->exception);
4854 s=newSViv(j);
4855 (void) sv_setpv(s,MagickOptionToMnemonic(MagickTypeOptions,j));
4856 SvIOK_on(s);
4857 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4858 continue;
4859 }
4860 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4861 attribute);
4862 break;
4863 }
4864 case 'U':
4865 case 'u':
4866 {
4867 if (LocaleCompare(attribute,"units") == 0)
4868 {
4869 j=info ? info->image_info->units : image->units;
4870 if (info)
4871 if (info->image_info->units == UndefinedResolution)
4872 j=image->units;
4873 if (j == UndefinedResolution)
4874 s=newSVpv("undefined units",0);
4875 else
4876 if (j == PixelsPerInchResolution)
4877 s=newSVpv("pixels / inch",0);
4878 else
4879 s=newSVpv("pixels / centimeter",0);
4880 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4881 continue;
4882 }
4883 if (LocaleCompare(attribute,"user-time") == 0)
4884 {
4885 if (image != (Image *) NULL)
4886 s=newSVnv(GetUserTime(&image->timer));
4887 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4888 continue;
4889 }
4890 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4891 attribute);
4892 break;
4893 }
4894 case 'V':
4895 case 'v':
4896 {
4897 if (LocaleCompare(attribute,"verbose") == 0)
4898 {
4899 if (info)
4900 s=newSViv((long) info->image_info->verbose);
4901 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4902 continue;
4903 }
4904 if (LocaleCompare(attribute,"version") == 0)
4905 {
4906 s=newSVpv(GetMagickVersion((unsigned long *) NULL),0);
4907 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4908 continue;
4909 }
4910 if (LocaleCompare(attribute,"view") == 0)
4911 {
4912 if (info && info->image_info->view)
4913 s=newSVpv(info->image_info->view,0);
4914 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4915 continue;
4916 }
4917 if (LocaleCompare(attribute,"virtual-pixel") == 0)
4918 {
4919 if (image == (Image *) NULL)
4920 break;
4921 j=(long) GetImageVirtualPixelMethod(image);
4922 s=newSViv(j);
4923 (void) sv_setpv(s,MagickOptionToMnemonic(
4924 MagickVirtualPixelOptions,j));
4925 SvIOK_on(s);
4926 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4927 continue;
4928 }
4929 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4930 attribute);
4931 break;
4932 }
4933 case 'W':
4934 case 'w':
4935 {
4936 if (LocaleCompare(attribute,"white-point") == 0)
4937 {
4938 if (image == (Image *) NULL)
4939 break;
4940 (void) FormatMagickString(color,MaxTextExtent,"%g,%g",
4941 image->chromaticity.white_point.x,
4942 image->chromaticity.white_point.y);
4943 s=newSVpv(color,0);
4944 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4945 continue;
4946 }
4947 if (LocaleCompare(attribute,"width") == 0)
4948 {
4949 if (image != (Image *) NULL)
4950 s=newSViv((long) image->columns);
4951 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4952 continue;
4953 }
4954 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4955 attribute);
4956 break;
4957 }
4958 case 'X':
4959 case 'x':
4960 {
4961 if (LocaleCompare(attribute,"x-resolution") == 0)
4962 {
4963 if (image != (Image *) NULL)
4964 s=newSVnv(image->x_resolution);
4965 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4966 continue;
4967 }
4968 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4969 attribute);
4970 break;
4971 }
4972 case 'Y':
4973 case 'y':
4974 {
4975 if (LocaleCompare(attribute,"y-resolution") == 0)
4976 {
4977 if (image != (Image *) NULL)
4978 s=newSVnv(image->y_resolution);
4979 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4980 continue;
4981 }
4982 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4983 attribute);
4984 break;
4985 }
4986 default:
4987 break;
4988 }
4989 if (image == (Image *) NULL)
4990 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4991 attribute)
4992 else
4993 {
4994 value=GetImageProperty(image,attribute);
4995 if (value != (const char *) NULL)
4996 {
4997 s=newSVpv(value,0);
4998 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4999 }
5000 else
5001 if (*attribute != '%')
5002 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5003 attribute)
5004 else
5005 {
5006 char
5007 *meta;
5008
5009 meta=InterpretImageProperties(info ? info->image_info :
5010 (ImageInfo *) NULL,image,attribute);
5011 s=newSVpv(meta,0);
5012 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5013 meta=(char *) RelinquishMagickMemory(meta);
5014 }
5015 }
5016 }
5017 exception=DestroyExceptionInfo(exception);
5018 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5019 }
5020
5021#
5022###############################################################################
5023# #
5024# #
5025# #
5026# G e t A u t h e n t i c P i x e l s #
5027# #
5028# #
5029# #
5030###############################################################################
5031#
5032#
5033void *
5034GetAuthenticPixels(ref,...)
5035 Image::Magick ref = NO_INIT
5036 ALIAS:
5037 getauthenticpixels = 1
5038 GetImagePixels = 2
5039 getimagepixels = 3
5040 CODE:
5041 {
5042 char
5043 *attribute;
5044
5045 ExceptionInfo
5046 *exception;
5047
5048 Image
5049 *image;
5050
5051 long
5052 i;
5053
5054 RectangleInfo
5055 region;
5056
5057 struct PackageInfo
5058 *info;
5059
5060 SV
5061 *perl_exception,
5062 *reference;
5063
5064 void
5065 *blob = NULL;
5066
5067 exception=AcquireExceptionInfo();
5068 perl_exception=newSVpv("",0);
5069 if (sv_isobject(ST(0)) == 0)
5070 {
5071 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5072 PackageName);
5073 goto PerlException;
5074 }
5075 reference=SvRV(ST(0));
5076
5077 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5078 if (image == (Image *) NULL)
5079 {
5080 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5081 PackageName);
5082 goto PerlException;
5083 }
5084
5085 region.x=0;
5086 region.y=0;
5087 region.width=image->columns;
5088 region.height=1;
5089 if (items == 1)
5090 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5091 for (i=2; i < items; i+=2)
5092 {
5093 attribute=(char *) SvPV(ST(i-1),na);
5094 switch (*attribute)
5095 {
5096 case 'g':
5097 case 'G':
5098 {
5099 if (LocaleCompare(attribute,"geometry") == 0)
5100 {
5101 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5102 break;
5103 }
5104 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5105 attribute);
5106 break;
5107 }
5108 case 'H':
5109 case 'h':
5110 {
5111 if (LocaleCompare(attribute,"height") == 0)
5112 {
5113 region.height=SvIV(ST(i));
5114 continue;
5115 }
5116 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5117 attribute);
5118 break;
5119 }
5120 case 'X':
5121 case 'x':
5122 {
5123 if (LocaleCompare(attribute,"x") == 0)
5124 {
5125 region.x=SvIV(ST(i));
5126 continue;
5127 }
5128 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5129 attribute);
5130 break;
5131 }
5132 case 'Y':
5133 case 'y':
5134 {
5135 if (LocaleCompare(attribute,"y") == 0)
5136 {
5137 region.y=SvIV(ST(i));
5138 continue;
5139 }
5140 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5141 attribute);
5142 break;
5143 }
5144 case 'W':
5145 case 'w':
5146 {
5147 if (LocaleCompare(attribute,"width") == 0)
5148 {
5149 region.width=SvIV(ST(i));
5150 continue;
5151 }
5152 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5153 attribute);
5154 break;
5155 }
5156 }
5157 }
5158 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5159 region.height,exception);
5160 if (blob != (void *) NULL)
5161 goto PerlEnd;
5162
5163 PerlException:
5164 InheritPerlException(exception,perl_exception);
5165 exception=DestroyExceptionInfo(exception);
5166 SvREFCNT_dec(perl_exception); /* throw away all errors */
5167
5168 PerlEnd:
5169 RETVAL = blob;
5170 }
5171 OUTPUT:
5172 RETVAL
5173
5174#
5175###############################################################################
5176# #
5177# #
5178# #
5179# G e t V i r t u a l P i x e l s #
5180# #
5181# #
5182# #
5183###############################################################################
5184#
5185#
5186void *
5187GetVirtualPixels(ref,...)
5188 Image::Magick ref = NO_INIT
5189 ALIAS:
5190 getvirtualpixels = 1
5191 AcquireImagePixels = 2
5192 acquireimagepixels = 3
5193 CODE:
5194 {
5195 char
5196 *attribute;
5197
5198 const void
5199 *blob = NULL;
5200
5201 ExceptionInfo
5202 *exception;
5203
5204 Image
5205 *image;
5206
5207 long
5208 i;
5209
5210 RectangleInfo
5211 region;
5212
5213 struct PackageInfo
5214 *info;
5215
5216 SV
5217 *perl_exception,
5218 *reference;
5219
5220 exception=AcquireExceptionInfo();
5221 perl_exception=newSVpv("",0);
5222 if (sv_isobject(ST(0)) == 0)
5223 {
5224 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5225 PackageName);
5226 goto PerlException;
5227 }
5228 reference=SvRV(ST(0));
5229
5230 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5231 if (image == (Image *) NULL)
5232 {
5233 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5234 PackageName);
5235 goto PerlException;
5236 }
5237
5238 region.x=0;
5239 region.y=0;
5240 region.width=image->columns;
5241 region.height=1;
5242 if (items == 1)
5243 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5244 for (i=2; i < items; i+=2)
5245 {
5246 attribute=(char *) SvPV(ST(i-1),na);
5247 switch (*attribute)
5248 {
5249 case 'g':
5250 case 'G':
5251 {
5252 if (LocaleCompare(attribute,"geometry") == 0)
5253 {
5254 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5255 break;
5256 }
5257 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5258 attribute);
5259 break;
5260 }
5261 case 'H':
5262 case 'h':
5263 {
5264 if (LocaleCompare(attribute,"height") == 0)
5265 {
5266 region.height=SvIV(ST(i));
5267 continue;
5268 }
5269 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5270 attribute);
5271 break;
5272 }
5273 case 'X':
5274 case 'x':
5275 {
5276 if (LocaleCompare(attribute,"x") == 0)
5277 {
5278 region.x=SvIV(ST(i));
5279 continue;
5280 }
5281 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5282 attribute);
5283 break;
5284 }
5285 case 'Y':
5286 case 'y':
5287 {
5288 if (LocaleCompare(attribute,"y") == 0)
5289 {
5290 region.y=SvIV(ST(i));
5291 continue;
5292 }
5293 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5294 attribute);
5295 break;
5296 }
5297 case 'W':
5298 case 'w':
5299 {
5300 if (LocaleCompare(attribute,"width") == 0)
5301 {
5302 region.width=SvIV(ST(i));
5303 continue;
5304 }
5305 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5306 attribute);
5307 break;
5308 }
5309 }
5310 }
5311 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
5312 region.height,exception);
5313 if (blob != (void *) NULL)
5314 goto PerlEnd;
5315
5316 PerlException:
5317 InheritPerlException(exception,perl_exception);
5318 exception=DestroyExceptionInfo(exception);
5319 SvREFCNT_dec(perl_exception); /* throw away all errors */
5320
5321 PerlEnd:
5322 RETVAL = (void *) blob;
5323 }
5324 OUTPUT:
5325 RETVAL
5326
5327#
5328###############################################################################
5329# #
5330# #
5331# #
5332# G e t A u t h e n t i c I n d e x Q u e u e #
5333# #
5334# #
5335# #
5336###############################################################################
5337#
5338#
5339void *
5340GetAuthenticIndexQueue(ref,...)
5341 Image::Magick ref = NO_INIT
5342 ALIAS:
5343 getauthenticindexqueue = 1
5344 GetIndexes = 2
5345 getindexes = 3
5346 CODE:
5347 {
5348 ExceptionInfo
5349 *exception;
5350
5351 Image
5352 *image;
5353
5354 struct PackageInfo
5355 *info;
5356
5357 SV
5358 *perl_exception,
5359 *reference;
5360
5361 void
5362 *blob = NULL;
5363
5364 exception=AcquireExceptionInfo();
5365 perl_exception=newSVpv("",0);
5366 if (sv_isobject(ST(0)) == 0)
5367 {
5368 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5369 PackageName);
5370 goto PerlException;
5371 }
5372 reference=SvRV(ST(0));
5373
5374 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5375 if (image == (Image *) NULL)
5376 {
5377 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5378 PackageName);
5379 goto PerlException;
5380 }
5381
5382 blob=(void *) GetAuthenticIndexQueue(image);
5383 if (blob != (void *) NULL)
5384 goto PerlEnd;
5385
5386 PerlException:
5387 InheritPerlException(exception,perl_exception);
5388 exception=DestroyExceptionInfo(exception);
5389 SvREFCNT_dec(perl_exception); /* throw away all errors */
5390
5391 PerlEnd:
5392 RETVAL = blob;
5393 }
5394 OUTPUT:
5395 RETVAL
5396
5397#
5398###############################################################################
5399# #
5400# #
5401# #
5402# G e t V i r t u a l I n d e x Q u e u e #
5403# #
5404# #
5405# #
5406###############################################################################
5407#
5408#
5409void *
5410GetVirtualIndexQueue(ref,...)
5411 Image::Magick ref = NO_INIT
5412 ALIAS:
5413 getvirtualindexqueue = 1
5414 CODE:
5415 {
5416 ExceptionInfo
5417 *exception;
5418
5419 Image
5420 *image;
5421
5422 struct PackageInfo
5423 *info;
5424
5425 SV
5426 *perl_exception,
5427 *reference;
5428
5429 void
5430 *blob = NULL;
5431
5432 exception=AcquireExceptionInfo();
5433 perl_exception=newSVpv("",0);
5434 if (sv_isobject(ST(0)) == 0)
5435 {
5436 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5437 PackageName);
5438 goto PerlException;
5439 }
5440 reference=SvRV(ST(0));
5441
5442 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5443 if (image == (Image *) NULL)
5444 {
5445 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5446 PackageName);
5447 goto PerlException;
5448 }
5449
5450 blob=(void *) GetVirtualIndexQueue(image);
5451 if (blob != (void *) NULL)
5452 goto PerlEnd;
5453
5454 PerlException:
5455 InheritPerlException(exception,perl_exception);
5456 exception=DestroyExceptionInfo(exception);
5457 SvREFCNT_dec(perl_exception); /* throw away all errors */
5458
5459 PerlEnd:
5460 RETVAL = blob;
5461 }
5462 OUTPUT:
5463 RETVAL
5464
5465#
5466###############################################################################
5467# #
5468# #
5469# #
5470# H i s t o g r a m #
5471# #
5472# #
5473# #
5474###############################################################################
5475#
5476#
5477void
5478Histogram(ref,...)
5479 Image::Magick ref=NO_INIT
5480 ALIAS:
5481 HistogramImage = 1
5482 histogram = 2
5483 histogramimage = 3
5484 PPCODE:
5485 {
5486 AV
5487 *av;
5488
5489 char
5490 message[MaxTextExtent];
5491
5492 ColorPacket
5493 *histogram;
5494
5495 ExceptionInfo
5496 *exception;
5497
5498 HV
5499 *hv;
5500
5501 Image
5502 *image;
5503
5504 register long
5505 i;
5506
5507 ssize_t
5508 count;
5509
5510 struct PackageInfo
5511 *info;
5512
5513 SV
5514 *av_reference,
5515 *perl_exception,
5516 *reference;
5517
5518 unsigned long
5519 number_colors;
5520
5521 exception=AcquireExceptionInfo();
5522 perl_exception=newSVpv("",0);
5523 av=NULL;
5524 if (sv_isobject(ST(0)) == 0)
5525 {
5526 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5527 PackageName);
5528 goto PerlException;
5529 }
5530 reference=SvRV(ST(0));
5531 hv=SvSTASH(reference);
5532 av=newAV();
5533 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
5534 SvREFCNT_dec(av);
5535 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5536 if (image == (Image *) NULL)
5537 {
5538 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5539 PackageName);
5540 goto PerlException;
5541 }
5542 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
5543 count=0;
5544 for ( ; image; image=image->next)
5545 {
5546 histogram=GetImageHistogram(image,&number_colors,&image->exception);
5547 if (histogram == (ColorPacket *) NULL)
5548 continue;
5549 count+=number_colors;
5550 EXTEND(sp,6*count);
5551 for (i=0; i < (long) number_colors; i++)
5552 {
5553 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5554 histogram[i].pixel.red);
5555 PUSHs(sv_2mortal(newSVpv(message,0)));
5556 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5557 histogram[i].pixel.green);
5558 PUSHs(sv_2mortal(newSVpv(message,0)));
5559 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5560 histogram[i].pixel.blue);
5561 PUSHs(sv_2mortal(newSVpv(message,0)));
5562 if (image->colorspace == CMYKColorspace)
5563 {
5564 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5565 histogram[i].index);
5566 PUSHs(sv_2mortal(newSVpv(message,0)));
5567 }
5568 (void) FormatMagickString(message,MaxTextExtent,QuantumFormat,
5569 histogram[i].pixel.opacity);
5570 PUSHs(sv_2mortal(newSVpv(message,0)));
5571 (void) FormatMagickString(message,MaxTextExtent,"%lu",
5572 (unsigned long) histogram[i].count);
5573 PUSHs(sv_2mortal(newSVpv(message,0)));
5574 }
5575 histogram=(ColorPacket *) RelinquishMagickMemory(histogram);
5576 }
5577
5578 PerlException:
5579 InheritPerlException(exception,perl_exception);
5580 exception=DestroyExceptionInfo(exception);
5581 SvREFCNT_dec(perl_exception);
5582 }
5583
5584#
5585###############################################################################
5586# #
5587# #
5588# #
5589# G e t P i x e l #
5590# #
5591# #
5592# #
5593###############################################################################
5594#
5595#
5596void
5597GetPixel(ref,...)
5598 Image::Magick ref=NO_INIT
5599 ALIAS:
5600 getpixel = 1
5601 getPixel = 2
5602 PPCODE:
5603 {
5604 AV
5605 *av;
5606
5607 char
5608 *attribute;
5609
5610 ChannelType
5611 channel;
5612
5613 ExceptionInfo
5614 *exception;
5615
5616 Image
5617 *image;
5618
5619 long
5620 option;
5621
5622 MagickBooleanType
5623 normalize;
5624
5625 RectangleInfo
5626 region;
5627
5628 register const IndexPacket
5629 *indexes;
5630
5631 register const PixelPacket
5632 *p;
5633
5634 register long
5635 i;
5636
5637 struct PackageInfo
5638 *info;
5639
5640 SV
5641 *perl_exception,
5642 *reference; /* reference is the SV* of ref=SvIV(reference) */
5643
5644 exception=AcquireExceptionInfo();
5645 perl_exception=newSVpv("",0);
5646 reference=SvRV(ST(0));
5647 av=(AV *) reference;
5648 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
5649 exception);
5650 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5651 if (image == (Image *) NULL)
5652 {
5653 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5654 PackageName);
5655 goto PerlException;
5656 }
5657 channel=DefaultChannels;
5658 normalize=MagickTrue;
5659 region.x=0;
5660 region.y=0;
5661 region.width=image->columns;
5662 region.height=1;
5663 if (items == 1)
5664 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5665 for (i=2; i < items; i+=2)
5666 {
5667 attribute=(char *) SvPV(ST(i-1),na);
5668 switch (*attribute)
5669 {
5670 case 'C':
5671 case 'c':
5672 {
5673 if (LocaleCompare(attribute,"channel") == 0)
5674 {
5675 long
5676 option;
5677
5678 option=ParseChannelOption(SvPV(ST(i),na));
5679 if (option < 0)
5680 {
5681 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5682 SvPV(ST(i),na));
5683 return;
5684 }
5685 channel=(ChannelType) option;
5686 break;
5687 }
5688 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5689 attribute);
5690 break;
5691 }
5692 case 'g':
5693 case 'G':
5694 {
5695 if (LocaleCompare(attribute,"geometry") == 0)
5696 {
5697 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5698 break;
5699 }
5700 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5701 attribute);
5702 break;
5703 }
5704 case 'N':
5705 case 'n':
5706 {
5707 if (LocaleCompare(attribute,"normalize") == 0)
5708 {
5709 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
5710 SvPV(ST(i),na));
5711 if (option < 0)
5712 {
5713 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5714 SvPV(ST(i),na));
5715 break;
5716 }
5717 normalize=option != 0 ? MagickTrue : MagickFalse;
5718 break;
5719 }
5720 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5721 attribute);
5722 break;
5723 }
5724 case 'x':
5725 case 'X':
5726 {
5727 if (LocaleCompare(attribute,"x") == 0)
5728 {
5729 region.x=SvIV(ST(i));
5730 break;
5731 }
5732 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5733 attribute);
5734 break;
5735 }
5736 case 'y':
5737 case 'Y':
5738 {
5739 if (LocaleCompare(attribute,"y") == 0)
5740 {
5741 region.y=SvIV(ST(i));
5742 break;
5743 }
5744 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5745 attribute);
5746 break;
5747 }
5748 default:
5749 {
5750 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5751 attribute);
5752 break;
5753 }
5754 }
5755 }
5756 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
5757 if (p == (const PixelPacket *) NULL)
5758 PUSHs(&sv_undef);
5759 else
5760 {
5761 double
5762 scale;
5763
5764 indexes=AcquireIndexes(image);
5765 scale=1.0;
5766 if (normalize != MagickFalse)
5767 scale=1.0/QuantumRange;
5768 if ((channel & RedChannel) != 0)
5769 PUSHs(sv_2mortal(newSVnv(scale*p->red)));
5770 if ((channel & GreenChannel) != 0)
5771 PUSHs(sv_2mortal(newSVnv(scale*p->green)));
5772 if ((channel & BlueChannel) != 0)
5773 PUSHs(sv_2mortal(newSVnv(scale*p->blue)));
5774 if (((channel & IndexChannel) != 0) &&
5775 (image->colorspace == CMYKColorspace))
5776 PUSHs(sv_2mortal(newSVnv(scale*(*indexes))));
5777 if ((channel & OpacityChannel) != 0)
5778 PUSHs(sv_2mortal(newSVnv(scale*p->opacity)));
5779 }
5780
5781 PerlException:
5782 InheritPerlException(exception,perl_exception);
5783 exception=DestroyExceptionInfo(exception);
5784 SvREFCNT_dec(perl_exception);
5785 }
5786
5787#
5788###############################################################################
5789# #
5790# #
5791# #
5792# G e t P i x e l s #
5793# #
5794# #
5795# #
5796###############################################################################
5797#
5798#
5799void
5800GetPixels(ref,...)
5801 Image::Magick ref=NO_INIT
5802 ALIAS:
5803 getpixels = 1
5804 getPixels = 2
5805 PPCODE:
5806 {
5807 AV
5808 *av;
5809
5810 char
5811 *attribute;
5812
5813 const char
5814 *map;
5815
5816 ExceptionInfo
5817 *exception;
5818
5819 Image
5820 *image;
5821
5822 long
5823 option;
5824
5825 MagickBooleanType
5826 normalize,
5827 status;
5828
5829 RectangleInfo
5830 region;
5831
5832 register long
5833 i;
5834
5835 struct PackageInfo
5836 *info;
5837
5838 SV
5839 *perl_exception,
5840 *reference; /* reference is the SV* of ref=SvIV(reference) */
5841
5842 exception=AcquireExceptionInfo();
5843 perl_exception=newSVpv("",0);
5844 reference=SvRV(ST(0));
5845 av=(AV *) reference;
5846 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
5847 exception);
5848 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5849 if (image == (Image *) NULL)
5850 {
5851 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5852 PackageName);
5853 goto PerlException;
5854 }
5855 map="RGB";
5856 if (image->matte != MagickFalse)
5857 map="RGBA";
5858 if (image->colorspace == CMYKColorspace)
5859 {
5860 map="CMYK";
5861 if (image->matte != MagickFalse)
5862 map="CMYKA";
5863 }
5864 normalize=MagickFalse;
5865 region.x=0;
5866 region.y=0;
5867 region.width=image->columns;
5868 region.height=1;
5869 if (items == 1)
5870 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5871 for (i=2; i < items; i+=2)
5872 {
5873 attribute=(char *) SvPV(ST(i-1),na);
5874 switch (*attribute)
5875 {
5876 case 'g':
5877 case 'G':
5878 {
5879 if (LocaleCompare(attribute,"geometry") == 0)
5880 {
5881 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5882 break;
5883 }
5884 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5885 attribute);
5886 break;
5887 }
5888 case 'H':
5889 case 'h':
5890 {
5891 if (LocaleCompare(attribute,"height") == 0)
5892 {
5893 region.height=SvIV(ST(i));
5894 break;
5895 }
5896 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5897 attribute);
5898 break;
5899 }
5900 case 'M':
5901 case 'm':
5902 {
5903 if (LocaleCompare(attribute,"map") == 0)
5904 {
5905 map=SvPV(ST(i),na);
5906 break;
5907 }
5908 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5909 attribute);
5910 break;
5911 }
5912 case 'N':
5913 case 'n':
5914 {
5915 if (LocaleCompare(attribute,"normalize") == 0)
5916 {
5917 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
5918 SvPV(ST(i),na));
5919 if (option < 0)
5920 {
5921 ThrowPerlException(exception,OptionError,"UnrecognizedType",
5922 SvPV(ST(i),na));
5923 break;
5924 }
5925 normalize=option != 0 ? MagickTrue : MagickFalse;
5926 break;
5927 }
5928 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5929 attribute);
5930 break;
5931 }
5932 case 'W':
5933 case 'w':
5934 {
5935 if (LocaleCompare(attribute,"width") == 0)
5936 {
5937 region.width=SvIV(ST(i));
5938 break;
5939 }
5940 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5941 attribute);
5942 break;
5943 }
5944 case 'x':
5945 case 'X':
5946 {
5947 if (LocaleCompare(attribute,"x") == 0)
5948 {
5949 region.x=SvIV(ST(i));
5950 break;
5951 }
5952 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5953 attribute);
5954 break;
5955 }
5956 case 'y':
5957 case 'Y':
5958 {
5959 if (LocaleCompare(attribute,"y") == 0)
5960 {
5961 region.y=SvIV(ST(i));
5962 break;
5963 }
5964 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5965 attribute);
5966 break;
5967 }
5968 default:
5969 {
5970 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5971 attribute);
5972 break;
5973 }
5974 }
5975 }
5976 if (normalize != MagickFalse)
5977 {
5978 float
5979 *pixels;
5980
5981 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
5982 region.height*sizeof(*pixels));
5983 if (pixels == (float *) NULL)
5984 {
5985 ThrowPerlException(exception,ResourceLimitError,
5986 "MemoryAllocationFailed",PackageName);
5987 goto PerlException;
5988 }
5989 status=ExportImagePixels(image,region.x,region.y,region.width,
5990 region.height,map,FloatPixel,pixels,exception);
5991 if (status == MagickFalse)
5992 PUSHs(&sv_undef);
5993 else
5994 {
5995 EXTEND(sp,strlen(map)*region.width*region.height);
5996 for (i=0; i < (long) (strlen(map)*region.width*region.height); i++)
5997 PUSHs(sv_2mortal(newSVnv(pixels[i])));
5998 }
5999 pixels=(float *) RelinquishMagickMemory(pixels);
6000 }
6001 else
6002 {
6003 Quantum
6004 *pixels;
6005
6006 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6007 region.height*sizeof(*pixels));
6008 if (pixels == (Quantum *) NULL)
6009 {
6010 ThrowPerlException(exception,ResourceLimitError,
6011 "MemoryAllocationFailed",PackageName);
6012 goto PerlException;
6013 }
6014 status=ExportImagePixels(image,region.x,region.y,region.width,
6015 region.height,map,QuantumPixel,pixels,exception);
6016 if (status == MagickFalse)
6017 PUSHs(&sv_undef);
6018 else
6019 {
6020 EXTEND(sp,strlen(map)*region.width*region.height);
6021 for (i=0; i < (long) (strlen(map)*region.width*region.height); i++)
6022 PUSHs(sv_2mortal(newSViv(pixels[i])));
6023 }
6024 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6025 }
6026
6027 PerlException:
6028 InheritPerlException(exception,perl_exception);
6029 exception=DestroyExceptionInfo(exception);
6030 SvREFCNT_dec(perl_exception);
6031 }
6032
6033#
6034###############################################################################
6035# #
6036# #
6037# #
6038# I m a g e T o B l o b #
6039# #
6040# #
6041# #
6042###############################################################################
6043#
6044#
6045void
6046ImageToBlob(ref,...)
6047 Image::Magick ref=NO_INIT
6048 ALIAS:
6049 ImageToBlob = 1
6050 imagetoblob = 2
6051 toblob = 3
6052 blob = 4
6053 PPCODE:
6054 {
6055 char
6056 filename[MaxTextExtent];
6057
6058 ExceptionInfo
6059 *exception;
6060
6061 Image
6062 *image,
6063 *next;
6064
6065 long
6066 scene;
6067
6068 register long
6069 i;
6070
6071 struct PackageInfo
6072 *info,
6073 *package_info;
6074
6075 size_t
6076 length;
6077
6078 SV
6079 *perl_exception,
6080 *reference;
6081
6082 void
6083 *blob;
6084
6085 exception=AcquireExceptionInfo();
6086 perl_exception=newSVpv("",0);
6087 package_info=(struct PackageInfo *) NULL;
6088 if (sv_isobject(ST(0)) == 0)
6089 {
6090 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6091 PackageName);
6092 goto PerlException;
6093 }
6094 reference=SvRV(ST(0));
6095 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6096 if (image == (Image *) NULL)
6097 {
6098 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6099 PackageName);
6100 goto PerlException;
6101 }
6102 package_info=ClonePackageInfo(info,exception);
6103 for (i=2; i < items; i+=2)
6104 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6105 (void) CopyMagickString(filename,package_info->image_info->filename,
6106 MaxTextExtent);
6107 scene=0;
6108 for (next=image; next; next=next->next)
6109 {
6110 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
6111 next->scene=scene++;
6112 }
6113 SetImageInfo(package_info->image_info,MagickTrue,&image->exception);
6114 EXTEND(sp,(long) GetImageListLength(image));
6115 for ( ; image; image=image->next)
6116 {
6117 length=0;
6118 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6119 if (blob != (char *) NULL)
6120 {
6121 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6122 blob=(unsigned char *) RelinquishMagickMemory(blob);
6123 }
6124 if (package_info->image_info->adjoin)
6125 break;
6126 }
6127
6128 PerlException:
6129 if (package_info != (struct PackageInfo *) NULL)
6130 DestroyPackageInfo(package_info);
6131 InheritPerlException(exception,perl_exception);
6132 exception=DestroyExceptionInfo(exception);
6133 SvREFCNT_dec(perl_exception); /* throw away all errors */
6134 }
6135
6136#
6137###############################################################################
6138# #
6139# #
6140# #
6141# L a y e r s #
6142# #
6143# #
6144# #
6145###############################################################################
6146#
6147#
6148void
6149Layers(ref,...)
6150 Image::Magick ref=NO_INIT
6151 ALIAS:
6152 Layers = 1
6153 layers = 2
6154 OptimizeImageLayers = 3
6155 optimizelayers = 4
6156 optimizeimagelayers = 5
6157 PPCODE:
6158 {
6159 AV
6160 *av;
6161
6162 char
6163 *attribute;
6164
6165 CompositeOperator
6166 compose;
6167
6168 ExceptionInfo
6169 *exception;
6170
6171 HV
6172 *hv;
6173
6174 Image
6175 *image,
6176 *layers;
6177
6178 long
6179 option,
6180 sp;
6181
6182 MagickBooleanType
6183 dither;
6184
6185 ImageLayerMethod
6186 method;
6187
6188 register long
6189 i;
6190
6191 struct PackageInfo
6192 *info;
6193
6194 SV
6195 *av_reference,
6196 *perl_exception,
6197 *reference,
6198 *rv,
6199 *sv;
6200
6201 exception=AcquireExceptionInfo();
6202 perl_exception=newSVpv("",0);
6203 if (sv_isobject(ST(0)) == 0)
6204 {
6205 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6206 PackageName);
6207 goto PerlException;
6208 }
6209 reference=SvRV(ST(0));
6210 hv=SvSTASH(reference);
6211 av=newAV();
6212 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
6213 SvREFCNT_dec(av);
6214 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6215 if (image == (Image *) NULL)
6216 {
6217 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6218 PackageName);
6219 goto PerlException;
6220 }
6221 compose=image->compose;
6222 dither=MagickFalse;
6223 method=OptimizeLayer;
6224 for (i=2; i < items; i+=2)
6225 {
6226 attribute=(char *) SvPV(ST(i-1),na);
6227 switch (*attribute)
6228 {
6229 case 'C':
6230 case 'c':
6231 {
6232 if (LocaleCompare(attribute,"compose") == 0)
6233 {
6234 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
6235 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
6236 if (sp < 0)
6237 {
6238 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6239 SvPV(ST(i),na));
6240 break;
6241 }
6242 compose=(CompositeOperator) sp;
6243 break;
6244 }
6245 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6246 attribute);
6247 break;
6248 }
6249 case 'D':
6250 case 'd':
6251 {
6252 if (LocaleCompare(attribute,"dither") == 0)
6253 {
6254 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
6255 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
6256 if (sp < 0)
6257 {
6258 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6259 SvPV(ST(i),na));
6260 break;
6261 }
6262 dither=(MagickBooleanType) sp;
6263 break;
6264 }
6265 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6266 attribute);
6267 break;
6268 }
6269 case 'M':
6270 case 'm':
6271 {
6272 if (LocaleCompare(attribute,"method") == 0)
6273 {
6274 option=ParseMagickOption(MagickLayerOptions,MagickFalse,
6275 SvPV(ST(i),na));
6276 if (option < 0)
6277 {
6278 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6279 SvPV(ST(i),na));
6280 break;
6281 }
6282 method=(ImageLayerMethod) option;
6283 break;
6284 }
6285 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6286 attribute);
6287 break;
6288 }
6289 default:
6290 {
6291 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6292 attribute);
6293 break;
6294 }
6295 }
6296 }
6297 layers=(Image *) NULL;
6298 switch (method)
6299 {
6300 case CompareAnyLayer:
6301 case CompareClearLayer:
6302 case CompareOverlayLayer:
6303 default:
6304 {
6305 layers=CompareImageLayers(image,method,exception);
6306 break;
6307 }
6308 case MergeLayer:
6309 case FlattenLayer:
6310 case MosaicLayer:
6311 {
6312 layers=MergeImageLayers(image,method,exception);
6313 break;
6314 }
6315 case DisposeLayer:
6316 {
6317 layers=DisposeImages(image,exception);
6318 break;
6319 }
6320 case OptimizeImageLayer:
6321 {
6322 layers=OptimizeImageLayers(image,exception);
6323 break;
6324 }
6325 case OptimizePlusLayer:
6326 {
6327 layers=OptimizePlusImageLayers(image,exception);
6328 break;
6329 }
6330 case OptimizeTransLayer:
6331 {
6332 OptimizeImageTransparency(image,exception);
6333 InheritException(&(image->exception),exception);
6334 break;
6335 }
6336 case RemoveDupsLayer:
6337 {
6338 RemoveDuplicateLayers(&image,exception);
6339 InheritException(&(image->exception),exception);
6340 break;
6341 }
6342 case RemoveZeroLayer:
6343 {
6344 RemoveZeroDelayLayers(&image,exception);
6345 InheritException(&(image->exception),exception);
6346 break;
6347 }
6348 case OptimizeLayer:
6349 {
6350 QuantizeInfo
6351 *quantize_info;
6352
6353 /*
6354 General Purpose, GIF Animation Optimizer.
6355 */
6356 layers=CoalesceImages(image,exception);
6357 if (layers == (Image *) NULL)
6358 break;
6359 InheritException(&(layers->exception),exception);
6360 image=layers;
6361 layers=OptimizeImageLayers(image,exception);
6362 if (layers == (Image *) NULL)
6363 break;
6364 InheritException(&(layers->exception),exception);
6365 image=DestroyImageList(image);
6366 image=layers;
6367 layers=(Image *) NULL;
6368 OptimizeImageTransparency(image,exception);
6369 InheritException(&(image->exception),exception);
6370 quantize_info=AcquireQuantizeInfo(info->image_info);
6371 (void) RemapImages(quantize_info,image,(Image *) NULL);
6372 quantize_info=DestroyQuantizeInfo(quantize_info);
6373 break;
6374 }
6375 case CompositeLayer:
6376 {
6377 Image
6378 *source;
6379
6380 RectangleInfo
6381 geometry;
6382
6383 /*
6384 Split image sequence at the first 'NULL:' image.
6385 */
6386 source=image;
6387 while (source != (Image *) NULL)
6388 {
6389 source=GetNextImageInList(source);
6390 if ((source != (Image *) NULL) &&
6391 (LocaleCompare(source->magick,"NULL") == 0))
6392 break;
6393 }
6394 if (source != (Image *) NULL)
6395 {
6396 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
6397 (GetNextImageInList(source) == (Image *) NULL))
6398 source=(Image *) NULL;
6399 else
6400 {
6401 /*
6402 Separate the two lists, junk the null: image.
6403 */
6404 source=SplitImageList(source->previous);
6405 DeleteImageFromList(&source);
6406 }
6407 }
6408 if (source == (Image *) NULL)
6409 {
6410 (void) ThrowMagickException(exception,GetMagickModule(),
6411 OptionError,"MissingNullSeparator","layers Composite");
6412 break;
6413 }
6414 /*
6415 Adjust offset with gravity and virtual canvas.
6416 */
6417 SetGeometry(image,&geometry);
6418 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
6419 geometry.width=source->page.width != 0 ? source->page.width :
6420 source->columns;
6421 geometry.height=source->page.height != 0 ? source->page.height :
6422 source->rows;
6423 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
6424 image->columns,image->page.height != 0 ? image->page.height :
6425 image->rows,image->gravity,&geometry);
6426 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
6427 source=DestroyImageList(source);
6428 InheritException(&(image->exception),exception);
6429 break;
6430 }
6431 }
6432 if (layers != (Image *) NULL)
6433 {
6434 InheritException(&(layers->exception),exception);
6435 image=layers;
6436 }
6437 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
6438 goto PerlException;
6439 for ( ; image; image=image->next)
6440 {
6441 AddImageToRegistry(image);
6442 rv=newRV(sv);
6443 av_push(av,sv_bless(rv,hv));
6444 SvREFCNT_dec(sv);
6445 }
6446 exception=DestroyExceptionInfo(exception);
6447 ST(0)=av_reference;
6448 SvREFCNT_dec(perl_exception);
6449 XSRETURN(1);
6450
6451 PerlException:
6452 InheritPerlException(exception,perl_exception);
6453 exception=DestroyExceptionInfo(exception);
6454 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
6455 SvPOK_on(perl_exception);
6456 ST(0)=sv_2mortal(perl_exception);
6457 XSRETURN(1);
6458 }
6459
6460#
6461###############################################################################
6462# #
6463# #
6464# #
6465# M a g i c k T o M i m e #
6466# #
6467# #
6468# #
6469###############################################################################
6470#
6471#
6472SV *
6473MagickToMime(ref,name)
6474 Image::Magick ref=NO_INIT
6475 char *name
6476 ALIAS:
6477 magicktomime = 1
6478 CODE:
6479 {
6480 char
6481 *mime;
6482
6483 mime=MagickToMime(name);
6484 RETVAL=newSVpv(mime,0);
6485 mime=(char *) RelinquishMagickMemory(mime);
6486 }
6487 OUTPUT:
6488 RETVAL
6489
6490#
6491###############################################################################
6492# #
6493# #
6494# #
6495# M o g r i f y #
6496# #
6497# #
6498# #
6499###############################################################################
6500#
6501#
6502void
6503Mogrify(ref,...)
6504 Image::Magick ref=NO_INIT
6505 ALIAS:
6506 Comment = 1
6507 CommentImage = 2
6508 Label = 3
6509 LabelImage = 4
6510 AddNoise = 5
6511 AddNoiseImage = 6
6512 Colorize = 7
6513 ColorizeImage = 8
6514 Border = 9
6515 BorderImage = 10
6516 Blur = 11
6517 BlurImage = 12
6518 Chop = 13
6519 ChopImage = 14
6520 Crop = 15
6521 CropImage = 16
6522 Despeckle = 17
6523 DespeckleImage = 18
6524 Edge = 19
6525 EdgeImage = 20
6526 Emboss = 21
6527 EmbossImage = 22
6528 Enhance = 23
6529 EnhanceImage = 24
6530 Flip = 25
6531 FlipImage = 26
6532 Flop = 27
6533 FlopImage = 28
6534 Frame = 29
6535 FrameImage = 30
6536 Implode = 31
6537 ImplodeImage = 32
6538 Magnify = 33
6539 MagnifyImage = 34
6540 MedianFilter = 35
6541 MedianFilterImage = 36
6542 Minify = 37
6543 MinifyImage = 38
6544 OilPaint = 39
6545 OilPaintImage = 40
6546 ReduceNoise = 41
6547 ReduceNoiseImage = 42
6548 Roll = 43
6549 RollImage = 44
6550 Rotate = 45
6551 RotateImage = 46
6552 Sample = 47
6553 SampleImage = 48
6554 Scale = 49
6555 ScaleImage = 50
6556 Shade = 51
6557 ShadeImage = 52
6558 Sharpen = 53
6559 SharpenImage = 54
6560 Shear = 55
6561 ShearImage = 56
6562 Spread = 57
6563 SpreadImage = 58
6564 Swirl = 59
6565 SwirlImage = 60
6566 Resize = 61
6567 ResizeImage = 62
6568 Zoom = 63
6569 ZoomImage = 64
6570 Annotate = 65
6571 AnnotateImage = 66
6572 ColorFloodfill = 67
6573 ColorFloodfillImage= 68
6574 Composite = 69
6575 CompositeImage = 70
6576 Contrast = 71
6577 ContrastImage = 72
6578 CycleColormap = 73
6579 CycleColormapImage = 74
6580 Draw = 75
6581 DrawImage = 76
6582 Equalize = 77
6583 EqualizeImage = 78
6584 Gamma = 79
6585 GammaImage = 80
6586 Map = 81
6587 MapImage = 82
6588 MatteFloodfill = 83
6589 MatteFloodfillImage= 84
6590 Modulate = 85
6591 ModulateImage = 86
6592 Negate = 87
6593 NegateImage = 88
6594 Normalize = 89
6595 NormalizeImage = 90
6596 NumberColors = 91
6597 NumberColorsImage = 92
6598 Opaque = 93
6599 OpaqueImage = 94
6600 Quantize = 95
6601 QuantizeImage = 96
6602 Raise = 97
6603 RaiseImage = 98
6604 Segment = 99
6605 SegmentImage = 100
6606 Signature = 101
6607 SignatureImage = 102
6608 Solarize = 103
6609 SolarizeImage = 104
6610 Sync = 105
6611 SyncImage = 106
6612 Texture = 107
6613 TextureImage = 108
6614 Evaluate = 109
6615 EvaluateImage = 110
6616 Transparent = 111
6617 TransparentImage = 112
6618 Threshold = 113
6619 ThresholdImage = 114
6620 Charcoal = 115
6621 CharcoalImage = 116
6622 Trim = 117
6623 TrimImage = 118
6624 Wave = 119
6625 WaveImage = 120
6626 Separate = 121
6627 SeparateImage = 122
6628 Stereo = 125
6629 StereoImage = 126
6630 Stegano = 127
6631 SteganoImage = 128
6632 Deconstruct = 129
6633 DeconstructImage = 130
6634 GaussianBlur = 131
6635 GaussianBlurImage = 132
6636 Convolve = 133
6637 ConvolveImage = 134
6638 Profile = 135
6639 ProfileImage = 136
6640 UnsharpMask = 137
6641 UnsharpMaskImage = 138
6642 MotionBlur = 139
6643 MotionBlurImage = 140
6644 OrderedDither = 141
6645 OrderedDitherImage = 142
6646 Shave = 143
6647 ShaveImage = 144
6648 Level = 145
6649 LevelImage = 146
6650 Clip = 147
6651 ClipImage = 148
6652 AffineTransform = 149
6653 AffineTransformImage = 150
6654 Difference = 151
6655 DifferenceImage = 152
6656 AdaptiveThreshold = 153
6657 AdaptiveThresholdImage = 154
6658 Resample = 155
6659 ResampleImage = 156
6660 Describe = 157
6661 DescribeImage = 158
6662 BlackThreshold = 159
6663 BlackThresholdImage= 160
6664 WhiteThreshold = 161
6665 WhiteThresholdImage= 162
6666 RadialBlur = 163
6667 RadialBlurImage = 164
6668 Thumbnail = 165
6669 ThumbnailImage = 166
6670 Strip = 167
6671 StripImage = 168
6672 Tint = 169
6673 TintImage = 170
6674 Channel = 171
6675 ChannelImage = 172
6676 Splice = 173
6677 SpliceImage = 174
6678 Posterize = 175
6679 PosterizeImage = 176
6680 Shadow = 177
6681 ShadowImage = 178
6682 Identify = 179
6683 IdentifyImage = 180
6684 SepiaTone = 181
6685 SepiaToneImage = 182
6686 SigmoidalContrast = 183
6687 SigmoidalContrastImage = 184
6688 Extent = 185
6689 ExtentImage = 186
6690 Vignette = 187
6691 VignetteImage = 188
6692 ContrastStretch = 189
6693 ContrastStretchImage = 190
6694 Sans0 = 191
6695 Sans0Image = 192
6696 Sans1 = 193
6697 Sans1Image = 194
6698 AdaptiveSharpen = 195
6699 AdaptiveSharpenImage = 196
6700 Transpose = 197
6701 TransposeImage = 198
6702 Transverse = 199
6703 TransverseImage = 200
6704 AutoOrient = 201
6705 AutoOrientImage = 202
6706 AdaptiveBlur = 203
6707 AdaptiveBlurImage = 204
6708 Sketch = 205
6709 SketchImage = 206
6710 UniqueColors = 207
6711 UniqueColorsImage = 208
6712 AdaptiveResize = 209
6713 AdaptiveResizeImage= 210
6714 ClipMask = 211
6715 ClipMaskImage = 212
6716 LinearStretch = 213
6717 LinearStretchImage = 214
6718 RecolorImage = 215
6719 Recolor = 216
6720 Mask = 217
6721 MaskImage = 218
6722 Polaroid = 219
6723 PolaroidImage = 220
6724 FloodfillPaint = 221
6725 FloodfillPaintImage= 222
6726 Distort = 223
6727 DistortImage = 224
6728 Clut = 225
6729 ClutImage = 226
6730 LiquidRescale = 227
6731 LiquidRescaleImage = 228
6732 Encipher = 229
6733 EncipherImage = 230
6734 Decipher = 231
6735 DecipherImage = 232
6736 Deskew = 233
6737 DeskewImage = 234
6738 Remap = 235
6739 RemapImage = 236
6740 SparseColor = 237
6741 SparseColorImage = 238
6742 Function = 239
6743 FunctionImage = 240
6744 SelectiveBlur = 241
6745 SelectiveBlurImage = 242
6746 HaldClut = 243
6747 HaldClutImage = 244
6748 BlueShift = 245
6749 BlueShiftImage = 246
6750 ForwardFourierTransform = 247
6751 ForwardFourierTransformImage = 248
6752 InverseFourierTransform = 249
6753 InverseFourierTransformImage = 250
6754 ColorDecisionList = 251
6755 ColorDecisionListImage = 252
6756 AutoGamma = 253
6757 AutoGammaImage = 254
6758 AutoLevel = 255
6759 AutoLevelImage = 256
6760 MogrifyRegion = 666
6761 PPCODE:
6762 {
6763 AffineMatrix
6764 affine,
6765 current;
6766
6767 char
6768 attribute_flag[MaxArguments],
6769 message[MaxTextExtent];
6770
6771 ChannelType
6772 channel;
6773
6774 CompositeOperator
6775 compose;
6776
6777 const char
6778 *attribute,
6779 *value;
6780
6781 double
6782 angle;
6783
6784 ExceptionInfo
6785 *exception;
6786
6787 GeometryInfo
6788 geometry_info;
6789
6790 Image
6791 *image,
6792 *next,
6793 *region_image;
6794
6795 long
6796 base,
6797 j,
6798 number_images;
6799
6800 MagickBooleanType
6801 status;
6802
6803 MagickStatusType
6804 flags;
6805
6806 PixelPacket
6807 fill_color;
6808
6809 RectangleInfo
6810 geometry,
6811 region_info;
6812
6813 register long
6814 i;
6815
6816 struct PackageInfo
6817 *info;
6818
6819 struct Methods
6820 *rp;
6821
6822 SV
6823 *perl_exception,
6824 **pv,
6825 *reference,
6826 **reference_vector;
6827
6828 struct ArgumentList
6829 argument_list[MaxArguments];
6830
6831 exception=AcquireExceptionInfo();
6832 perl_exception=newSVpv("",0);
6833 reference_vector=NULL;
6834 region_image=NULL;
6835 number_images=0;
6836 base=2;
6837 if (sv_isobject(ST(0)) == 0)
6838 {
6839 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6840 PackageName);
6841 goto PerlException;
6842 }
6843 reference=SvRV(ST(0));
6844 region_info.width=0;
6845 region_info.height=0;
6846 region_info.x=0;
6847 region_info.y=0;
6848 region_image=(Image *) NULL;
6849 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
6850 if (ix && (ix != 666))
6851 {
6852 /*
6853 Called as Method(...)
6854 */
6855 ix=(ix+1)/2;
6856 rp=(&Methods[ix-1]);
6857 attribute=rp->name;
6858 }
6859 else
6860 {
6861 /*
6862 Called as Mogrify("Method",...)
6863 */
6864 attribute=(char *) SvPV(ST(1),na);
6865 if (ix)
6866 {
6867 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
6868 attribute=(char *) SvPV(ST(2),na);
6869 base++;
6870 }
6871 for (rp=Methods; ; rp++)
6872 {
6873 if (rp >= EndOf(Methods))
6874 {
6875 ThrowPerlException(exception,OptionError,
6876 "UnrecognizedPerlMagickMethod",attribute);
6877 goto PerlException;
6878 }
6879 if (strEQcase(attribute,rp->name))
6880 break;
6881 }
6882 ix=rp-Methods+1;
6883 base++;
6884 }
6885 if (image == (Image *) NULL)
6886 {
6887 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
6888 goto PerlException;
6889 }
6890 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
6891 Zero(&attribute_flag,NumberOf(attribute_flag),char);
6892 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
6893 {
6894 long
6895 longest;
6896
6897 Arguments
6898 *pp,
6899 *qq;
6900
6901 struct ArgumentList
6902 *al;
6903
6904 SV
6905 *sv;
6906
6907 longest=0;
6908 pp=(Arguments *) NULL;
6909 qq=rp->arguments;
6910 if (i == items)
6911 {
6912 pp=rp->arguments,
6913 sv=ST(i-1);
6914 }
6915 else
6916 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
6917 {
6918 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
6919 break;
6920 if (strEQcase(attribute,qq->method) > longest)
6921 {
6922 pp=qq;
6923 longest=strEQcase(attribute,qq->method);
6924 }
6925 }
6926 if (pp == (Arguments *) NULL)
6927 {
6928 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6929 attribute);
6930 goto continue_outer_loop;
6931 }
6932 al=(&argument_list[pp-rp->arguments]);
6933 switch (pp->type)
6934 {
6935 case ArrayReference:
6936 {
6937 if (SvTYPE(sv) != SVt_RV)
6938 {
6939 (void) FormatMagickString(message,MaxTextExtent,
6940 "invalid %.60s value",pp->method);
6941 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
6942 goto continue_outer_loop;
6943 }
6944 al->array_reference=SvRV(sv);
6945 break;
6946 }
6947 case RealReference:
6948 {
6949 al->real_reference=SvNV(sv);
6950 break;
6951 }
6952 case FileReference:
6953 {
6954 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
6955 break;
6956 }
6957 case ImageReference:
6958 {
6959 if (!sv_isobject(sv) ||
6960 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
6961 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
6962 {
6963 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6964 PackageName);
6965 goto PerlException;
6966 }
6967 break;
6968 }
6969 case IntegerReference:
6970 {
6971 al->long_reference=SvIV(sv);
6972 break;
6973 }
6974 case StringReference:
6975 {
6976 al->string_reference=(char *) SvPV(sv,al->length);
6977 if (sv_isobject(sv))
6978 al->image_reference=SetupList(aTHX_ SvRV(sv),
6979 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
6980 break;
6981 }
6982 default:
6983 {
6984 /*
6985 Is a string; look up name.
6986 */
6987 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
6988 {
6989 al->string_reference=(char *) SvPV(sv,al->length);
6990 al->long_reference=(-1);
6991 break;
6992 }
6993 al->long_reference=ParseMagickOption((MagickOption) pp->type,
6994 MagickFalse,SvPV(sv,na));
6995 if (pp->type == MagickChannelOptions)
6996 al->long_reference=ParseChannelOption(SvPV(sv,na));
6997 if ((al->long_reference < 0) && ((al->long_reference=SvIV(sv)) <= 0))
6998 {
6999 (void) FormatMagickString(message,MaxTextExtent,
7000 "invalid %.60s value",pp->method);
7001 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7002 goto continue_outer_loop;
7003 }
7004 break;
7005 }
7006 }
7007 attribute_flag[pp-rp->arguments]++;
7008 continue_outer_loop: ;
7009 }
7010 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7011 pv=reference_vector;
7012 SetGeometryInfo(&geometry_info);
7013 channel=DefaultChannels;
7014 for (next=image; next; next=next->next)
7015 {
7016 image=next;
7017 SetGeometry(image,&geometry);
7018 if ((region_info.width*region_info.height) != 0)
7019 {
7020 region_image=image;
7021 image=CropImage(image,&region_info,exception);
7022 }
7023 switch (ix)
7024 {
7025 default:
7026 {
7027 (void) FormatMagickString(message,MaxTextExtent,"%ld",(long) ix);
7028 ThrowPerlException(exception,OptionError,
7029 "UnrecognizedPerlMagickMethod",message);
7030 goto PerlException;
7031 }
7032 case 1: /* Comment */
7033 {
7034 if (attribute_flag[0] == 0)
7035 argument_list[0].string_reference=(char *) NULL;
7036 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7037 info ? info->image_info : (ImageInfo *) NULL,image,
7038 argument_list[0].string_reference));
7039 break;
7040 }
7041 case 2: /* Label */
7042 {
7043 if (attribute_flag[0] == 0)
7044 argument_list[0].string_reference=(char *) NULL;
7045 (void) SetImageProperty(image,"label",InterpretImageProperties(
7046 info ? info->image_info : (ImageInfo *) NULL,image,
7047 argument_list[0].string_reference));
7048 break;
7049 }
7050 case 3: /* AddNoise */
7051 {
7052 if (attribute_flag[0] == 0)
7053 argument_list[0].long_reference=UniformNoise;
7054 if (attribute_flag[1] != 0)
7055 channel=(ChannelType) argument_list[1].long_reference;
7056 image=AddNoiseImageChannel(image,channel,(NoiseType)
7057 argument_list[0].long_reference,exception);
7058 break;
7059 }
7060 case 4: /* Colorize */
7061 {
7062 PixelPacket
7063 target;
7064
7065 (void) GetOneVirtualPixel(image,0,0,&target,exception);
7066 if (attribute_flag[0] != 0)
7067 (void) QueryColorDatabase(argument_list[0].string_reference,&target,
7068 exception);
7069 if (attribute_flag[1] == 0)
7070 argument_list[1].string_reference="100%";
7071 image=ColorizeImage(image,argument_list[1].string_reference,target,
7072 exception);
7073 break;
7074 }
7075 case 5: /* Border */
7076 {
7077 geometry.width=0;
7078 geometry.height=0;
7079 if (attribute_flag[0] != 0)
7080 {
7081 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7082 &geometry,exception);
7083 if ((flags & HeightValue) == 0)
7084 geometry.height=geometry.width;
7085 }
7086 if (attribute_flag[1] != 0)
7087 geometry.width=argument_list[1].long_reference;
7088 if (attribute_flag[2] != 0)
7089 geometry.height=argument_list[2].long_reference;
7090 if (attribute_flag[3] != 0)
7091 QueryColorDatabase(argument_list[3].string_reference,
7092 &image->border_color,exception);
7093 if (attribute_flag[4] != 0)
7094 QueryColorDatabase(argument_list[4].string_reference,
7095 &image->border_color,exception);
7096 if (attribute_flag[5] != 0)
7097 QueryColorDatabase(argument_list[5].string_reference,
7098 &image->border_color,exception);
7099 if (attribute_flag[6] != 0)
7100 image->compose=(CompositeOperator) argument_list[6].long_reference;
7101 image=BorderImage(image,&geometry,exception);
7102 break;
7103 }
7104 case 6: /* Blur */
7105 {
7106 if (attribute_flag[0] != 0)
7107 {
7108 flags=ParseGeometry(argument_list[0].string_reference,
7109 &geometry_info);
7110 if ((flags & SigmaValue) == 0)
7111 geometry_info.sigma=1.0;
7112 }
7113 if (attribute_flag[1] != 0)
7114 geometry_info.rho=argument_list[1].real_reference;
7115 if (attribute_flag[2] != 0)
7116 geometry_info.sigma=argument_list[2].real_reference;
7117 if (attribute_flag[3] != 0)
7118 channel=(ChannelType) argument_list[3].long_reference;
7119 image=BlurImageChannel(image,channel,geometry_info.rho,
7120 geometry_info.sigma,exception);
7121 break;
7122 }
7123 case 7: /* Chop */
7124 {
7125 if (attribute_flag[0] != 0)
7126 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7127 &geometry,exception);
7128 if (attribute_flag[1] != 0)
7129 geometry.width=argument_list[1].long_reference;
7130 if (attribute_flag[2] != 0)
7131 geometry.height=argument_list[2].long_reference;
7132 if (attribute_flag[3] != 0)
7133 geometry.x=argument_list[3].long_reference;
7134 if (attribute_flag[4] != 0)
7135 geometry.y=argument_list[4].long_reference;
7136 image=ChopImage(image,&geometry,exception);
7137 break;
7138 }
7139 case 8: /* Crop */
7140 {
7141 if (attribute_flag[0] != 0)
7142 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7143 &geometry,exception);
7144 if (attribute_flag[1] != 0)
7145 geometry.width=argument_list[1].long_reference;
7146 if (attribute_flag[2] != 0)
7147 geometry.height=argument_list[2].long_reference;
7148 if (attribute_flag[3] != 0)
7149 geometry.x=argument_list[3].long_reference;
7150 if (attribute_flag[4] != 0)
7151 geometry.y=argument_list[4].long_reference;
7152 if (attribute_flag[5] != 0)
7153 image->fuzz=
7154 StringToDouble(argument_list[5].string_reference,QuantumRange);
7155 image=CropImage(image,&geometry,exception);
7156 break;
7157 }
7158 case 9: /* Despeckle */
7159 {
7160 image=DespeckleImage(image,exception);
7161 break;
7162 }
7163 case 10: /* Edge */
7164 {
7165 if (attribute_flag[0] != 0)
7166 geometry_info.rho=argument_list[0].real_reference;
7167 image=EdgeImage(image,geometry_info.rho,exception);
7168 break;
7169 }
7170 case 11: /* Emboss */
7171 {
7172 if (attribute_flag[0] != 0)
7173 {
7174 flags=ParseGeometry(argument_list[0].string_reference,
7175 &geometry_info);
7176 if ((flags & SigmaValue) == 0)
7177 geometry_info.sigma=1.0;
7178 }
7179 if (attribute_flag[1] != 0)
7180 geometry_info.rho=argument_list[1].real_reference;
7181 if (attribute_flag[2] != 0)
7182 geometry_info.sigma=argument_list[2].real_reference;
7183 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
7184 exception);
7185 break;
7186 }
7187 case 12: /* Enhance */
7188 {
7189 image=EnhanceImage(image,exception);
7190 break;
7191 }
7192 case 13: /* Flip */
7193 {
7194 image=FlipImage(image,exception);
7195 break;
7196 }
7197 case 14: /* Flop */
7198 {
7199 image=FlopImage(image,exception);
7200 break;
7201 }
7202 case 15: /* Frame */
7203 {
7204 FrameInfo
7205 frame_info;
7206
7207 if (attribute_flag[0] != 0)
7208 {
7209 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7210 &geometry,exception);
7211 if ((flags & HeightValue) == 0)
7212 geometry.height=geometry.width;
7213 frame_info.width=geometry.width;
7214 frame_info.height=geometry.height;
7215 frame_info.outer_bevel=geometry.x;
7216 frame_info.inner_bevel=geometry.y;
7217 }
7218 if (attribute_flag[1] != 0)
7219 frame_info.width=argument_list[1].long_reference;
7220 if (attribute_flag[2] != 0)
7221 frame_info.height=argument_list[2].long_reference;
7222 if (attribute_flag[3] != 0)
7223 frame_info.inner_bevel=argument_list[3].long_reference;
7224 if (attribute_flag[4] != 0)
7225 frame_info.outer_bevel=argument_list[4].long_reference;
7226 if (attribute_flag[5] != 0)
7227 QueryColorDatabase(argument_list[5].string_reference,&fill_color,
7228 exception);
7229 if (attribute_flag[6] != 0)
7230 QueryColorDatabase(argument_list[6].string_reference,&fill_color,
7231 exception);
7232 frame_info.x=(long) frame_info.width;
7233 frame_info.y=(long) frame_info.height;
7234 frame_info.width=image->columns+2*frame_info.x;
7235 frame_info.height=image->rows+2*frame_info.y;
7236 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
7237 image->matte_color=fill_color;
7238 if (attribute_flag[7] != 0)
7239 image->compose=(CompositeOperator) argument_list[7].long_reference;
7240 image=FrameImage(image,&frame_info,exception);
7241 break;
7242 }
7243 case 16: /* Implode */
7244 {
7245 if (attribute_flag[0] == 0)
7246 argument_list[0].real_reference=0.5;
7247 if (attribute_flag[1] != 0)
7248 image->interpolate=(InterpolatePixelMethod)
7249 argument_list[1].long_reference;
7250 image=ImplodeImage(image,argument_list[0].real_reference,
7251 exception);
7252 break;
7253 }
7254 case 17: /* Magnify */
7255 {
7256 image=MagnifyImage(image,exception);
7257 break;
7258 }
7259 case 18: /* MedianFilter */
7260 {
7261 if (attribute_flag[0] == 0)
7262 argument_list[0].real_reference=0.0;
7263 image=MedianFilterImage(image,argument_list[0].real_reference,
7264 exception);
7265 break;
7266 }
7267 case 19: /* Minify */
7268 {
7269 image=MinifyImage(image,exception);
7270 break;
7271 }
7272 case 20: /* OilPaint */
7273 {
7274 if (attribute_flag[0] == 0)
7275 argument_list[0].real_reference=0.0;
7276 image=OilPaintImage(image,argument_list[0].real_reference,
7277 exception);
7278 break;
7279 }
7280 case 21: /* ReduceNoise */
7281 {
7282 if (attribute_flag[0] == 0)
7283 argument_list[0].real_reference=0.0;
7284 image=ReduceNoiseImage(image,argument_list[0].real_reference,
7285 exception);
7286 break;
7287 }
7288 case 22: /* Roll */
7289 {
7290 if (attribute_flag[0] != 0)
7291 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7292 &geometry,exception);
7293 if (attribute_flag[1] != 0)
7294 geometry.x=argument_list[1].long_reference;
7295 if (attribute_flag[2] != 0)
7296 geometry.y=argument_list[2].long_reference;
7297 image=RollImage(image,geometry.x,geometry.y,exception);
7298 break;
7299 }
7300 case 23: /* Rotate */
7301 {
7302 if (attribute_flag[0] == 0)
7303 argument_list[0].real_reference=90.0;
7304 if (attribute_flag[1] != 0)
7305 QueryColorDatabase(argument_list[1].string_reference,
7306 &image->background_color,exception);
7307 if (attribute_flag[2] != 0)
7308 QueryColorDatabase(argument_list[2].string_reference,
7309 &image->background_color,exception);
7310 if (attribute_flag[3] != 0)
7311 QueryColorDatabase(argument_list[3].string_reference,
7312 &image->background_color,exception);
7313 image=RotateImage(image,argument_list[0].real_reference,exception);
7314 break;
7315 }
7316 case 24: /* Sample */
7317 {
7318 if (attribute_flag[0] != 0)
7319 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7320 &geometry,exception);
7321 if (attribute_flag[1] != 0)
7322 geometry.width=argument_list[1].long_reference;
7323 if (attribute_flag[2] != 0)
7324 geometry.height=argument_list[2].long_reference;
7325 image=SampleImage(image,geometry.width,geometry.height,exception);
7326 break;
7327 }
7328 case 25: /* Scale */
7329 {
7330 if (attribute_flag[0] != 0)
7331 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7332 &geometry,exception);
7333 if (attribute_flag[1] != 0)
7334 geometry.width=argument_list[1].long_reference;
7335 if (attribute_flag[2] != 0)
7336 geometry.height=argument_list[2].long_reference;
7337 image=ScaleImage(image,geometry.width,geometry.height,exception);
7338 break;
7339 }
7340 case 26: /* Shade */
7341 {
7342 if (attribute_flag[0] != 0)
7343 {
7344 flags=ParseGeometry(argument_list[0].string_reference,
7345 &geometry_info);
7346 if ((flags & SigmaValue) == 0)
7347 geometry_info.sigma=0.0;
7348 }
7349 if (attribute_flag[1] != 0)
7350 geometry_info.rho=argument_list[1].real_reference;
7351 if (attribute_flag[2] != 0)
7352 geometry_info.sigma=argument_list[2].real_reference;
7353 image=ShadeImage(image,
7354 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse,
7355 geometry_info.rho,geometry_info.sigma,exception);
7356 break;
7357 }
7358 case 27: /* Sharpen */
7359 {
7360 if (attribute_flag[0] != 0)
7361 {
7362 flags=ParseGeometry(argument_list[0].string_reference,
7363 &geometry_info);
7364 if ((flags & SigmaValue) == 0)
7365 geometry_info.sigma=1.0;
7366 }
7367 if (attribute_flag[1] != 0)
7368 geometry_info.rho=argument_list[1].real_reference;
7369 if (attribute_flag[2] != 0)
7370 geometry_info.sigma=argument_list[2].real_reference;
7371 if (attribute_flag[3] != 0)
7372 channel=(ChannelType) argument_list[3].long_reference;
7373 image=SharpenImageChannel(image,channel,geometry_info.rho,
7374 geometry_info.sigma,exception);
7375 break;
7376 }
7377 case 28: /* Shear */
7378 {
7379 if (attribute_flag[0] != 0)
7380 {
7381 flags=ParseGeometry(argument_list[0].string_reference,
7382 &geometry_info);
7383 if ((flags & SigmaValue) == 0)
7384 geometry_info.sigma=geometry_info.rho;
7385 }
7386 if (attribute_flag[1] != 0)
7387 geometry_info.rho=argument_list[1].real_reference;
7388 if (attribute_flag[2] != 0)
7389 geometry_info.sigma=argument_list[2].real_reference;
7390 if (attribute_flag[3] != 0)
7391 QueryColorDatabase(argument_list[3].string_reference,
7392 &image->background_color,exception);
7393 if (attribute_flag[4] != 0)
7394 QueryColorDatabase(argument_list[4].string_reference,
7395 &image->background_color,exception);
7396 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
7397 exception);
7398 break;
7399 }
7400 case 29: /* Spread */
7401 {
7402 if (attribute_flag[0] == 0)
7403 argument_list[0].real_reference=1.0;
7404 image=SpreadImage(image,argument_list[0].real_reference,exception);
7405 break;
7406 }
7407 case 30: /* Swirl */
7408 {
7409 if (attribute_flag[0] == 0)
7410 argument_list[0].real_reference=50.0;
7411 if (attribute_flag[1] != 0)
7412 image->interpolate=(InterpolatePixelMethod)
7413 argument_list[1].long_reference;
7414 image=SwirlImage(image,argument_list[0].real_reference,exception);
7415 break;
7416 }
7417 case 31: /* Resize */
7418 case 32: /* Zoom */
7419 {
7420 if (attribute_flag[0] != 0)
7421 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7422 &geometry,exception);
7423 if (attribute_flag[1] != 0)
7424 geometry.width=argument_list[1].long_reference;
7425 if (attribute_flag[2] != 0)
7426 geometry.height=argument_list[2].long_reference;
7427 if (attribute_flag[3] == 0)
7428 argument_list[3].long_reference=(long) UndefinedFilter;
7429 if (attribute_flag[4] != 0)
7430 SetImageArtifact(image,"filter:support",
7431 argument_list[4].string_reference);
7432 if (attribute_flag[5] == 0)
7433 argument_list[5].real_reference=1.0;
7434 image=ResizeImage(image,geometry.width,geometry.height,
7435 (FilterTypes) argument_list[3].long_reference,
7436 argument_list[5].real_reference,exception);
7437 break;
7438 }
7439 case 33: /* Annotate */
7440 {
7441 DrawInfo
7442 *draw_info;
7443
7444 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
7445 (DrawInfo *) NULL);
7446 if (attribute_flag[0] != 0)
7447 {
7448 char
7449 *text;
7450
7451 text=InterpretImageProperties(info ? info->image_info :
7452 (ImageInfo *) NULL,image,argument_list[0].string_reference);
7453 (void) CloneString(&draw_info->text,text);
7454 text=DestroyString(text);
7455 }
7456 if (attribute_flag[1] != 0)
7457 (void) CloneString(&draw_info->font,
7458 argument_list[1].string_reference);
7459 if (attribute_flag[2] != 0)
7460 draw_info->pointsize=argument_list[2].real_reference;
7461 if (attribute_flag[3] != 0)
7462 (void) CloneString(&draw_info->density,
7463 argument_list[3].string_reference);
7464 if (attribute_flag[4] != 0)
7465 (void) QueryColorDatabase(argument_list[4].string_reference,
7466 &draw_info->undercolor,exception);
7467 if (attribute_flag[5] != 0)
7468 {
7469 (void) QueryColorDatabase(argument_list[5].string_reference,
7470 &draw_info->stroke,exception);
7471 if (argument_list[5].image_reference != (Image *) NULL)
7472 draw_info->stroke_pattern=CloneImage(
7473 argument_list[5].image_reference,0,0,MagickTrue,exception);
7474 }
7475 if (attribute_flag[6] != 0)
7476 {
7477 (void) QueryColorDatabase(argument_list[6].string_reference,
7478 &draw_info->fill,exception);
7479 if (argument_list[6].image_reference != (Image *) NULL)
7480 draw_info->fill_pattern=CloneImage(
7481 argument_list[6].image_reference,0,0,MagickTrue,exception);
7482 }
7483 if (attribute_flag[7] != 0)
7484 {
7485 (void) CloneString(&draw_info->geometry,
7486 argument_list[7].string_reference);
7487 flags=ParsePageGeometry(image,argument_list[7].string_reference,
7488 &geometry,exception);
7489 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
7490 geometry_info.sigma=geometry_info.xi;
7491 }
7492 if (attribute_flag[8] != 0)
7493 (void) QueryColorDatabase(argument_list[8].string_reference,
7494 &draw_info->fill,exception);
7495 if (attribute_flag[11] != 0)
7496 draw_info->gravity=(GravityType) argument_list[11].long_reference;
7497 if (attribute_flag[25] != 0)
7498 {
7499 AV
7500 *av;
7501
7502 av=(AV *) argument_list[25].array_reference;
7503 if ((av_len(av) != 3) && (av_len(av) != 5))
7504 {
7505 ThrowPerlException(exception,OptionError,
7506 "affine matrix must have 4 or 6 elements",PackageName);
7507 goto PerlException;
7508 }
7509 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
7510 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
7511 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
7512 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
7513 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
7514 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
7515 {
7516 ThrowPerlException(exception,OptionError,
7517 "affine matrix is singular",PackageName);
7518 goto PerlException;
7519 }
7520 if (av_len(av) == 5)
7521 {
7522 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
7523 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
7524 }
7525 }
7526 for (j=12; j < 17; j++)
7527 {
7528 if (attribute_flag[j] == 0)
7529 continue;
7530 value=argument_list[j].string_reference;
7531 angle=argument_list[j].real_reference;
7532 current=draw_info->affine;
7533 GetAffineMatrix(&affine);
7534 switch (j)
7535 {
7536 case 12:
7537 {
7538 /*
7539 Translate.
7540 */
7541 flags=ParseGeometry(value,&geometry_info);
7542 affine.tx=geometry_info.xi;
7543 affine.ty=geometry_info.psi;
7544 if ((flags & PsiValue) == 0)
7545 affine.ty=affine.tx;
7546 break;
7547 }
7548 case 13:
7549 {
7550 /*
7551 Scale.
7552 */
7553 flags=ParseGeometry(value,&geometry_info);
7554 affine.sx=geometry_info.rho;
7555 affine.sy=geometry_info.sigma;
7556 if ((flags & SigmaValue) == 0)
7557 affine.sy=affine.sx;
7558 break;
7559 }
7560 case 14:
7561 {
7562 /*
7563 Rotate.
7564 */
7565 if (angle == 0.0)
7566 break;
7567 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
7568 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
7569 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
7570 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
7571 break;
7572 }
7573 case 15:
7574 {
7575 /*
7576 SkewX.
7577 */
7578 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
7579 break;
7580 }
7581 case 16:
7582 {
7583 /*
7584 SkewY.
7585 */
7586 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
7587 break;
7588 }
7589 }
7590 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
7591 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
7592 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
7593 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
7594 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
7595 current.tx;
7596 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
7597 current.ty;
7598 }
7599 if (attribute_flag[9] == 0)
7600 argument_list[9].real_reference=0.0;
7601 if (attribute_flag[10] == 0)
7602 argument_list[10].real_reference=0.0;
7603 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
7604 {
7605 char
7606 geometry[MaxTextExtent];
7607
7608 (void) FormatMagickString(geometry,MaxTextExtent,"%+f%+f",
7609 (double) argument_list[9].real_reference+draw_info->affine.tx,
7610 (double) argument_list[10].real_reference+draw_info->affine.ty);
7611 (void) CloneString(&draw_info->geometry,geometry);
7612 }
7613 if (attribute_flag[17] != 0)
7614 draw_info->stroke_width=argument_list[17].real_reference;
7615 if (attribute_flag[18] != 0)
7616 {
7617 draw_info->text_antialias=argument_list[18].long_reference != 0 ?
7618 MagickTrue : MagickFalse;
7619 draw_info->stroke_antialias=draw_info->text_antialias;
7620 }
7621 if (attribute_flag[19] != 0)
7622 (void) CloneString(&draw_info->family,
7623 argument_list[19].string_reference);
7624 if (attribute_flag[20] != 0)
7625 draw_info->style=(StyleType) argument_list[20].long_reference;
7626 if (attribute_flag[21] != 0)
7627 draw_info->stretch=(StretchType) argument_list[21].long_reference;
7628 if (attribute_flag[22] != 0)
7629 draw_info->weight=argument_list[22].long_reference;
7630 if (attribute_flag[23] != 0)
7631 draw_info->align=(AlignType) argument_list[23].long_reference;
7632 if (attribute_flag[24] != 0)
7633 (void) CloneString(&draw_info->encoding,
7634 argument_list[24].string_reference);
7635 if (attribute_flag[25] != 0)
7636 draw_info->fill_pattern=CloneImage(
7637 argument_list[25].image_reference,0,0,MagickTrue,exception);
7638 if (attribute_flag[26] != 0)
7639 draw_info->fill_pattern=CloneImage(
7640 argument_list[26].image_reference,0,0,MagickTrue,exception);
7641 if (attribute_flag[27] != 0)
7642 draw_info->stroke_pattern=CloneImage(
7643 argument_list[27].image_reference,0,0,MagickTrue,exception);
7644 if (attribute_flag[29] != 0)
7645 draw_info->kerning=argument_list[29].real_reference;
7646 if (attribute_flag[30] != 0)
7647 draw_info->interword_spacing=argument_list[30].real_reference;
7648 (void) AnnotateImage(image,draw_info);
7649 draw_info=DestroyDrawInfo(draw_info);
7650 break;
7651 }
7652 case 34: /* ColorFloodfill */
7653 {
7654 DrawInfo
7655 *draw_info;
7656
7657 MagickBooleanType
7658 invert;
7659
7660 MagickPixelPacket
7661 target;
7662
7663 draw_info=CloneDrawInfo(info ? info->image_info :
7664 (ImageInfo *) NULL,(DrawInfo *) NULL);
7665 if (attribute_flag[0] != 0)
7666 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7667 &geometry,exception);
7668 if (attribute_flag[1] != 0)
7669 geometry.x=argument_list[1].long_reference;
7670 if (attribute_flag[2] != 0)
7671 geometry.y=argument_list[2].long_reference;
7672 if (attribute_flag[3] != 0)
7673 (void) QueryColorDatabase(argument_list[3].string_reference,
7674 &draw_info->fill,exception);
7675 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
7676 exception);
7677 invert=MagickFalse;
7678 if (attribute_flag[4] != 0)
7679 {
7680 QueryMagickColor(argument_list[4].string_reference,&target,
7681 exception);
7682 invert=MagickTrue;
7683 }
7684 if (attribute_flag[5] != 0)
7685 image->fuzz=StringToDouble(argument_list[5].string_reference,
7686 QuantumRange);
7687 if (attribute_flag[6] != 0)
7688 invert=(MagickBooleanType) argument_list[6].long_reference;
7689 (void) FloodfillPaintImage(image,DefaultChannels,draw_info,&target,
7690 geometry.x,geometry.y,invert);
7691 draw_info=DestroyDrawInfo(draw_info);
7692 break;
7693 }
7694 case 35: /* Composite */
7695 {
7696 char
7697 composite_geometry[MaxTextExtent];
7698
7699 Image
7700 *composite_image,
7701 *rotate_image;
7702
7703 compose=OverCompositeOp;
7704 if (attribute_flag[0] != 0)
7705 composite_image=argument_list[0].image_reference;
7706 else
7707 {
7708 ThrowPerlException(exception,OptionError,
7709 "CompositeImageRequired",PackageName);
7710 goto PerlException;
7711 }
7712 /*
7713 Parameter Handling used for BOTH normal and tiled composition.
7714 */
7715 if (attribute_flag[1] != 0) /* compose */
7716 compose=(CompositeOperator) argument_list[1].long_reference;
7717 if (attribute_flag[6] != 0) /* opacity */
7718 {
7719 if (compose != DissolveCompositeOp)
7720 (void) SetImageOpacity(composite_image,(Quantum) (QuantumRange-
7721 StringToDouble(argument_list[6].string_reference,
7722 QuantumRange)));
7723 else
7724 {
7725 double
7726 opacity;
7727
7728 long
7729 y;
7730
7731 MagickBooleanType
7732 sync;
7733
7734 register long
7735 x;
7736
7737 register PixelPacket
7738 *q;
7739
7740 CacheView
7741 *composite_view;
7742
7743 /*
7744 Handle dissolve composite operator (patch by
7745 Kevin A. McGrail).
7746 */
7747 (void) CloneString(&image->geometry,
7748 argument_list[6].string_reference);
7749 opacity=(Quantum) (QuantumRange-StringToDouble(
7750 argument_list[6].string_reference,QuantumRange));
7751 if (composite_image->matte != MagickTrue)
7752 (void) SetImageOpacity(composite_image,OpaqueOpacity);
7753 composite_view=OpenCacheView(composite_image);
7754 for (y=0; y < (long) composite_image->rows ; y++)
7755 {
7756 q=GetCacheViewPixels(composite_view,0,y,(long)
7757 composite_image->columns,1);
7758 for (x=0; x < (long) composite_image->columns; x++)
7759 {
7760 if (q->opacity == OpaqueOpacity)
7761 q->opacity=RoundToQuantum(opacity);
7762 q++;
7763 }
7764 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
7765 if (sync == MagickFalse)
7766 break;
7767 }
7768 composite_view=CloseCacheView(composite_view);
7769 }
7770 }
7771 if (attribute_flag[9] != 0) /* "color=>" */
7772 QueryColorDatabase(argument_list[9].string_reference,
7773 &composite_image->background_color,exception);
7774 if (attribute_flag[12] != 0) /* "interpolate=>" */
7775 image->interpolate=(InterpolatePixelMethod)
7776 argument_list[12].long_reference;
7777 if (attribute_flag[13] != 0) /* "args=>" */
7778 (void) SetImageArtifact(composite_image,"compose:args",
7779 argument_list[13].string_reference);
7780 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
7781 (void) SetImageArtifact(composite_image,"compose:args",
7782 argument_list[14].string_reference);
7783 /*
7784 Tiling Composition (with orthogonal rotate).
7785 */
7786 rotate_image=(Image *) NULL;
7787 if (attribute_flag[8] != 0) /* "rotate=>" */
7788 {
7789 /*
7790 Rotate image.
7791 */
7792 rotate_image=RotateImage(composite_image,
7793 argument_list[8].real_reference,exception);
7794 if (rotate_image == (Image *) NULL)
7795 break;
7796 }
7797 if (attribute_flag[7] && argument_list[7].long_reference) /* tile */
7798 {
7799 long
7800 x,
7801 y;
7802
7803 /*
7804 Tile the composite image.
7805 */
7806 if (attribute_flag[8] != 0) /* "tile=>" */
7807 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
7808 "false");
7809 else
7810 (void) SetImageArtifact(composite_image,
7811 "compose:outside-overlay","false");
7812 for (y=0; y < (long) image->rows; y+=composite_image->rows)
7813 for (x=0; x < (long) image->columns; x+=composite_image->columns)
7814 {
7815 if (attribute_flag[8] != 0) /* rotate */
7816 (void) CompositeImage(image,compose,rotate_image,x,y);
7817 else
7818 (void) CompositeImage(image,compose,composite_image,x,y);
7819 }
7820 if (attribute_flag[8] != 0) /* rotate */
7821 rotate_image=DestroyImage(rotate_image);
7822 break;
7823 }
7824 /*
7825 Parameter Handling used used ONLY for normal composition.
7826 */
7827 if (attribute_flag[5] != 0) /* gravity */
7828 image->gravity=(GravityType) argument_list[5].long_reference;
7829 if (attribute_flag[2] != 0) /* geometry offset */
7830 {
7831 SetGeometry(image,&geometry);
7832 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
7833 &geometry);
7834 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
7835 &geometry);
7836 }
7837 if (attribute_flag[3] != 0) /* x offset */
7838 geometry.x=argument_list[3].long_reference;
7839 if (attribute_flag[4] != 0) /* y offset */
7840 geometry.y=argument_list[4].long_reference;
7841 if (attribute_flag[10] != 0) /* mask */
7842 {
7843 if ((image->compose == DisplaceCompositeOp) ||
7844 (image->compose == DistortCompositeOp))
7845 {
7846 /*
7847 Merge Y displacement into X displacement image.
7848 */
7849 composite_image=CloneImage(composite_image,0,0,MagickTrue,
7850 &image->exception);
7851 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
7852 argument_list[10].image_reference,0,0);
7853 }
7854 else
7855 {
7856 /*
7857 Set a blending mask for the composition.
7858 */
7859 image->mask=CloneImage(argument_list[10].image_reference,0,0,
7860 MagickTrue,&image->exception);
7861 (void) NegateImage(image->mask,MagickFalse);
7862 }
7863 }
7864 if (attribute_flag[11] != 0) /* channel */
7865 channel=(ChannelType) argument_list[11].long_reference;
7866 /*
7867 Composite two images (normal composition).
7868 */
7869 (void) FormatMagickString(composite_geometry,MaxTextExtent,
7870 "%lux%lu%+ld%+ld",composite_image->columns,composite_image->rows,
7871 geometry.x,geometry.y);
7872 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
7873 exception);
7874 if (attribute_flag[8] == 0) /* no rotate */
7875 CompositeImageChannel(image,channel,compose,composite_image,
7876 geometry.x,geometry.y);
7877 else
7878 {
7879 /*
7880 Position adjust rotated image then composite.
7881 */
7882 geometry.x-=(long) (rotate_image->columns-
7883 composite_image->columns)/2;
7884 geometry.y-=(long) (rotate_image->rows-composite_image->rows)/2;
7885 CompositeImageChannel(image,channel,compose,rotate_image,
7886 geometry.x,geometry.y);
7887 rotate_image=DestroyImage(rotate_image);
7888 }
7889 if (attribute_flag[10] != 0) /* mask */
7890 {
7891 if ((image->compose == DisplaceCompositeOp) ||
7892 (image->compose == DistortCompositeOp))
7893 composite_image=DestroyImage(composite_image);
7894 else
7895 image->mask=DestroyImage(image->mask);
7896 }
7897 break;
7898 }
7899 case 36: /* Contrast */
7900 {
7901 if (attribute_flag[0] == 0)
7902 argument_list[0].long_reference=0;
7903 (void) ContrastImage(image,argument_list[0].long_reference != 0 ?
7904 MagickTrue : MagickFalse);
7905 break;
7906 }
7907 case 37: /* CycleColormap */
7908 {
7909 if (attribute_flag[0] == 0)
7910 argument_list[0].long_reference=6;
7911 (void) CycleColormapImage(image,argument_list[0].long_reference);
7912 break;
7913 }
7914 case 38: /* Draw */
7915 {
7916 DrawInfo
7917 *draw_info;
7918
7919 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
7920 (DrawInfo *) NULL);
7921 (void) CloneString(&draw_info->primitive,"point");
7922 if (attribute_flag[0] != 0)
7923 {
7924 if (argument_list[0].long_reference < 0)
7925 (void) CloneString(&draw_info->primitive,
7926 argument_list[0].string_reference);
7927 else
7928 (void) CloneString(&draw_info->primitive,MagickOptionToMnemonic(
7929 MagickPrimitiveOptions,argument_list[0].long_reference));
7930 }
7931 if (attribute_flag[1] != 0)
7932 {
7933 if (LocaleCompare(draw_info->primitive,"path") == 0)
7934 {
7935 (void) ConcatenateString(&draw_info->primitive," '");
7936 ConcatenateString(&draw_info->primitive,
7937 argument_list[1].string_reference);
7938 (void) ConcatenateString(&draw_info->primitive,"'");
7939 }
7940 else
7941 {
7942 (void) ConcatenateString(&draw_info->primitive," ");
7943 ConcatenateString(&draw_info->primitive,
7944 argument_list[1].string_reference);
7945 }
7946 }
7947 if (attribute_flag[2] != 0)
7948 {
7949 (void) ConcatenateString(&draw_info->primitive," ");
7950 (void) ConcatenateString(&draw_info->primitive,
7951 MagickOptionToMnemonic(MagickMethodOptions,
7952 argument_list[2].long_reference));
7953 }
7954 if (attribute_flag[3] != 0)
7955 {
7956 (void) QueryColorDatabase(argument_list[3].string_reference,
7957 &draw_info->stroke,exception);
7958 if (argument_list[3].image_reference != (Image *) NULL)
7959 draw_info->stroke_pattern=CloneImage(
7960 argument_list[3].image_reference,0,0,MagickTrue,exception);
7961 }
7962 if (attribute_flag[4] != 0)
7963 {
7964 (void) QueryColorDatabase(argument_list[4].string_reference,
7965 &draw_info->fill,exception);
7966 if (argument_list[4].image_reference != (Image *) NULL)
7967 draw_info->fill_pattern=CloneImage(
7968 argument_list[4].image_reference,0,0,MagickTrue,exception);
7969 }
7970 if (attribute_flag[5] != 0)
7971 draw_info->stroke_width=argument_list[5].real_reference;
7972 if (attribute_flag[6] != 0)
7973 (void) CloneString(&draw_info->font,
7974 argument_list[6].string_reference);
7975 if (attribute_flag[7] != 0)
7976 (void) QueryColorDatabase(argument_list[7].string_reference,
7977 &draw_info->border_color,exception);
7978 if (attribute_flag[8] != 0)
7979 draw_info->affine.tx=argument_list[8].real_reference;
7980 if (attribute_flag[9] != 0)
7981 draw_info->affine.ty=argument_list[9].real_reference;
7982 if (attribute_flag[20] != 0)
7983 {
7984 AV
7985 *av;
7986
7987 av=(AV *) argument_list[20].array_reference;
7988 if ((av_len(av) != 3) && (av_len(av) != 5))
7989 {
7990 ThrowPerlException(exception,OptionError,
7991 "affine matrix must have 4 or 6 elements",PackageName);
7992 goto PerlException;
7993 }
7994 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
7995 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
7996 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
7997 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
7998 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
7999 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8000 {
8001 ThrowPerlException(exception,OptionError,
8002 "affine matrix is singular",PackageName);
8003 goto PerlException;
8004 }
8005 if (av_len(av) == 5)
8006 {
8007 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8008 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8009 }
8010 }
8011 for (j=10; j < 15; j++)
8012 {
8013 if (attribute_flag[j] == 0)
8014 continue;
8015 value=argument_list[j].string_reference;
8016 angle=argument_list[j].real_reference;
8017 current=draw_info->affine;
8018 GetAffineMatrix(&affine);
8019 switch (j)
8020 {
8021 case 10:
8022 {
8023 /*
8024 Translate.
8025 */
8026 flags=ParseGeometry(value,&geometry_info);
8027 affine.tx=geometry_info.xi;
8028 affine.ty=geometry_info.psi;
8029 if ((flags & PsiValue) == 0)
8030 affine.ty=affine.tx;
8031 break;
8032 }
8033 case 11:
8034 {
8035 /*
8036 Scale.
8037 */
8038 flags=ParseGeometry(value,&geometry_info);
8039 affine.sx=geometry_info.rho;
8040 affine.sy=geometry_info.sigma;
8041 if ((flags & SigmaValue) == 0)
8042 affine.sy=affine.sx;
8043 break;
8044 }
8045 case 12:
8046 {
8047 /*
8048 Rotate.
8049 */
8050 if (angle == 0.0)
8051 break;
8052 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8053 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8054 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8055 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8056 break;
8057 }
8058 case 13:
8059 {
8060 /*
8061 SkewX.
8062 */
8063 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8064 break;
8065 }
8066 case 14:
8067 {
8068 /*
8069 SkewY.
8070 */
8071 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8072 break;
8073 }
8074 }
8075 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8076 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8077 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8078 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8079 draw_info->affine.tx=
8080 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8081 draw_info->affine.ty=
8082 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8083 }
8084 if (attribute_flag[15] != 0)
8085 draw_info->fill_pattern=CloneImage(
8086 argument_list[15].image_reference,0,0,MagickTrue,exception);
8087 if (attribute_flag[16] != 0)
8088 draw_info->pointsize=argument_list[16].real_reference;
8089 if (attribute_flag[17] != 0)
8090 {
8091 draw_info->stroke_antialias=argument_list[17].long_reference != 0
8092 ? MagickTrue : MagickFalse;
8093 draw_info->text_antialias=draw_info->stroke_antialias;
8094 }
8095 if (attribute_flag[18] != 0)
8096 (void) CloneString(&draw_info->density,
8097 argument_list[18].string_reference);
8098 if (attribute_flag[19] != 0)
8099 draw_info->stroke_width=argument_list[19].real_reference;
8100 if (attribute_flag[21] != 0)
8101 draw_info->dash_offset=argument_list[21].real_reference;
8102 if (attribute_flag[22] != 0)
8103 {
8104 AV
8105 *av;
8106
8107 av=(AV *) argument_list[22].array_reference;
8108 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
8109 av_len(av)+1UL,sizeof(draw_info->dash_pattern));
8110 if (draw_info->dash_pattern != (double *) NULL)
8111 {
8112 for (i=0; i <= av_len(av); i++)
8113 draw_info->dash_pattern[i]=(double)
8114 SvNV(*(av_fetch(av,i,0)));
8115 draw_info->dash_pattern[i]=0.0;
8116 }
8117 }
8118 if (attribute_flag[23] != 0)
8119 image->interpolate=(InterpolatePixelMethod)
8120 argument_list[23].long_reference;
8121 if ((attribute_flag[24] != 0) &&
8122 (draw_info->fill_pattern != (Image *) NULL))
8123 flags=ParsePageGeometry(draw_info->fill_pattern,
8124 argument_list[24].string_reference,
8125 &draw_info->fill_pattern->tile_offset,exception);
8126 if (attribute_flag[25] != 0)
8127 {
8128 (void) ConcatenateString(&draw_info->primitive," '");
8129 (void) ConcatenateString(&draw_info->primitive,
8130 argument_list[25].string_reference);
8131 (void) ConcatenateString(&draw_info->primitive,"'");
8132 }
8133 if (attribute_flag[26] != 0)
8134 draw_info->fill_pattern=CloneImage(
8135 argument_list[26].image_reference,0,0,MagickTrue,exception);
8136 if (attribute_flag[27] != 0)
8137 draw_info->stroke_pattern=CloneImage(
8138 argument_list[27].image_reference,0,0,MagickTrue,exception);
8139 if (attribute_flag[28] != 0)
8140 (void) CloneString(&draw_info->primitive,
8141 argument_list[28].string_reference);
8142 if (attribute_flag[29] != 0)
8143 draw_info->kerning=argument_list[29].real_reference;
8144 if (attribute_flag[30] != 0)
8145 draw_info->interword_spacing=argument_list[30].real_reference;
8146 DrawImage(image,draw_info);
8147 draw_info=DestroyDrawInfo(draw_info);
8148 break;
8149 }
8150 case 39: /* Equalize */
8151 {
8152 if (attribute_flag[0] != 0)
8153 channel=(ChannelType) argument_list[0].long_reference;
8154 EqualizeImageChannel(image,channel);
8155 break;
8156 }
8157 case 40: /* Gamma */
8158 {
8159 if (attribute_flag[1] != 0)
8160 channel=(ChannelType) argument_list[1].long_reference;
8161 if (attribute_flag[2] == 0)
8162 argument_list[2].real_reference=1.0;
8163 if (attribute_flag[3] == 0)
8164 argument_list[3].real_reference=1.0;
8165 if (attribute_flag[4] == 0)
8166 argument_list[4].real_reference=1.0;
8167 if (attribute_flag[0] == 0)
8168 {
8169 (void) FormatMagickString(message,MaxTextExtent,"%g,%g,%g",
8170 (double) argument_list[2].real_reference,
8171 (double) argument_list[3].real_reference,
8172 (double) argument_list[4].real_reference);
8173 argument_list[0].string_reference=message;
8174 }
8175 if (strchr(argument_list[0].string_reference,',') != (char *) NULL)
8176 (void) GammaImage(image,argument_list[0].string_reference);
8177 else
8178 (void) GammaImageChannel(image,channel,
8179 atof(argument_list[0].string_reference));
8180 break;
8181 }
8182 case 41: /* Map */
8183 {
8184 QuantizeInfo
8185 *quantize_info;
8186
8187 if (attribute_flag[0] == 0)
8188 {
8189 ThrowPerlException(exception,OptionError,"MapImageRequired",
8190 PackageName);
8191 goto PerlException;
8192 }
8193 quantize_info=AcquireQuantizeInfo(info->image_info);
8194 if (attribute_flag[1] != 0)
8195 quantize_info->dither=(MagickBooleanType)
8196 argument_list[1].long_reference;
8197 (void) RemapImages(quantize_info,image,
8198 argument_list[0].image_reference);
8199 quantize_info=DestroyQuantizeInfo(quantize_info);
8200 break;
8201 }
8202 case 42: /* MatteFloodfill */
8203 {
8204 DrawInfo
8205 *draw_info;
8206
8207 MagickBooleanType
8208 invert;
8209
8210 MagickPixelPacket
8211 target;
8212
8213 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8214 (DrawInfo *) NULL);
8215 if (attribute_flag[0] != 0)
8216 if (attribute_flag[0] != 0)
8217 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8218 &geometry,exception);
8219 if (attribute_flag[1] != 0)
8220 geometry.x=argument_list[1].long_reference;
8221 if (attribute_flag[2] != 0)
8222 geometry.y=argument_list[2].long_reference;
8223 if (image->matte == MagickFalse)
8224 (void) SetImageOpacity(image,OpaqueOpacity);
8225 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
8226 exception);
8227 if (attribute_flag[4] != 0)
8228 QueryMagickColor(argument_list[4].string_reference,&target,
8229 exception);
8230 if (attribute_flag[3] != 0)
8231 target.opacity=StringToDouble(argument_list[3].string_reference,
8232 QuantumRange);
8233 if (attribute_flag[5] != 0)
8234 image->fuzz=StringToDouble(argument_list[5].string_reference,
8235 QuantumRange);
8236 invert=MagickFalse;
8237 if (attribute_flag[6] != 0)
8238 invert=(MagickBooleanType) argument_list[6].long_reference;
8239 (void) FloodfillPaintImage(image,OpacityChannel,draw_info,&target,
8240 geometry.x,geometry.y,invert);
8241 draw_info=DestroyDrawInfo(draw_info);
8242 break;
8243 }
8244 case 43: /* Modulate */
8245 {
8246 char
8247 modulate[MaxTextExtent];
8248
8249 ColorspaceType
8250 colorspace;
8251
8252 colorspace=image->colorspace;
8253 geometry_info.rho=100.0;
8254 geometry_info.sigma=100.0;
8255 geometry_info.xi=100.0;
8256 if (attribute_flag[0] != 0)
8257 (void)ParseGeometry(argument_list[0].string_reference,
8258 &geometry_info);
8259 if (attribute_flag[1] != 0)
8260 geometry_info.xi=argument_list[1].real_reference;
8261 if (attribute_flag[2] != 0)
8262 geometry_info.sigma=argument_list[2].real_reference;
8263 if (attribute_flag[3] != 0)
8264 {
8265 (void) SetImageColorspace(image,HWBColorspace);
8266 geometry_info.sigma=argument_list[3].real_reference;
8267 }
8268 if (attribute_flag[4] != 0)
8269 geometry_info.rho=argument_list[4].real_reference;
8270 if (attribute_flag[5] != 0)
8271 {
8272 (void) SetImageColorspace(image,HSLColorspace);
8273 geometry_info.sigma=argument_list[5].real_reference;
8274 }
8275 if (attribute_flag[6] != 0)
8276 {
8277 (void) SetImageColorspace(image,HWBColorspace);
8278 geometry_info.rho=argument_list[6].real_reference;
8279 }
8280 (void) FormatMagickString(modulate,MaxTextExtent,"%g,%g,%g",
8281 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
8282 (void) ModulateImage(image,modulate);
8283 (void) SetImageColorspace(image,colorspace);
8284 break;
8285 }
8286 case 44: /* Negate */
8287 {
8288 if (attribute_flag[0] == 0)
8289 argument_list[0].long_reference=0;
8290 if (attribute_flag[1] != 0)
8291 channel=(ChannelType) argument_list[1].long_reference;
8292 (void) NegateImageChannel(image,channel,
8293 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse);
8294 break;
8295 }
8296 case 45: /* Normalize */
8297 {
8298 if (attribute_flag[0] != 0)
8299 channel=(ChannelType) argument_list[0].long_reference;
8300 NormalizeImageChannel(image,channel);
8301 break;
8302 }
8303 case 46: /* NumberColors */
8304 break;
8305 case 47: /* Opaque */
8306 {
8307 MagickBooleanType
8308 invert;
8309
8310 MagickPixelPacket
8311 fill_color,
8312 target;
8313
8314 (void) QueryMagickColor("none",&target,exception);
8315 (void) QueryMagickColor("none",&fill_color,exception);
8316 if (attribute_flag[0] != 0)
8317 (void) QueryMagickColor(argument_list[0].string_reference,
8318 &target,exception);
8319 if (attribute_flag[1] != 0)
8320 (void) QueryMagickColor(argument_list[1].string_reference,
8321 &fill_color,exception);
8322 if (attribute_flag[2] != 0)
8323 image->fuzz=StringToDouble(argument_list[2].string_reference,
8324 QuantumRange);
8325 if (attribute_flag[3] != 0)
8326 channel=(ChannelType) argument_list[3].long_reference;
8327 invert=MagickFalse;
8328 if (attribute_flag[4] != 0)
8329 invert=(MagickBooleanType) argument_list[4].long_reference;
8330 (void) OpaquePaintImageChannel(image,channel,&target,&fill_color,
8331 invert);
8332 break;
8333 }
8334 case 48: /* Quantize */
8335 {
8336 QuantizeInfo
8337 *quantize_info;
8338
8339 quantize_info=AcquireQuantizeInfo(info->image_info);
8340 if (attribute_flag[0] != 0)
8341 quantize_info->number_colors=(unsigned long)
8342 argument_list[0].long_reference;
8343 if (attribute_flag[1] != 0)
8344 quantize_info->tree_depth=(unsigned long)
8345 argument_list[1].long_reference;
8346 if (attribute_flag[2] != 0)
8347 quantize_info->colorspace=(ColorspaceType)
8348 argument_list[2].long_reference;
8349 if (attribute_flag[3] != 0)
8350 quantize_info->dither=argument_list[3].long_reference != 0 ?
8351 MagickTrue : MagickFalse;
8352 if (attribute_flag[4] != 0)
8353 quantize_info->measure_error=
8354 argument_list[4].long_reference != 0 ? MagickTrue : MagickFalse;
8355 if (attribute_flag[5] != 0)
8356 (void) QueryColorDatabase(argument_list[5].string_reference,
8357 &image->transparent_color,exception);
8358 if (attribute_flag[5] && argument_list[5].long_reference)
8359 {
8360 (void) QuantizeImages(quantize_info,image);
8361 goto PerlException;
8362 }
8363 if (attribute_flag[6] != 0)
8364 quantize_info->dither_method=(DitherMethod)
8365 argument_list[6].long_reference;
8366 if ((image->storage_class == DirectClass) ||
8367 (image->colors > quantize_info->number_colors) ||
8368 (quantize_info->colorspace == GRAYColorspace))
8369 (void) QuantizeImage(quantize_info,image);
8370 else
8371 CompressImageColormap(image);
8372 quantize_info=DestroyQuantizeInfo(quantize_info);
8373 break;
8374 }
8375 case 49: /* Raise */
8376 {
8377 if (attribute_flag[0] != 0)
8378 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8379 &geometry,exception);
8380 if (attribute_flag[1] != 0)
8381 geometry.width=argument_list[1].long_reference;
8382 if (attribute_flag[2] != 0)
8383 geometry.height=argument_list[2].long_reference;
8384 if (attribute_flag[3] == 0)
8385 argument_list[3].long_reference=1;
8386 (void) RaiseImage(image,&geometry,argument_list[3].long_reference !=
8387 0 ? MagickTrue : MagickFalse);
8388 break;
8389 }
8390 case 50: /* Segment */
8391 {
8392 ColorspaceType
8393 colorspace;
8394
8395 double
8396 cluster_threshold,
8397 smoothing_threshold;
8398
8399 MagickBooleanType
8400 verbose;
8401
8402 cluster_threshold=1.0;
8403 smoothing_threshold=1.5;
8404 colorspace=RGBColorspace;
8405 verbose=MagickFalse;
8406 if (attribute_flag[0] != 0)
8407 {
8408 flags=ParseGeometry(argument_list[0].string_reference,
8409 &geometry_info);
8410 cluster_threshold=geometry_info.rho;
8411 if (flags & SigmaValue)
8412 smoothing_threshold=geometry_info.sigma;
8413 }
8414 if (attribute_flag[1] != 0)
8415 cluster_threshold=argument_list[1].real_reference;
8416 if (attribute_flag[2] != 0)
8417 smoothing_threshold=argument_list[2].real_reference;
8418 if (attribute_flag[3] != 0)
8419 colorspace=(ColorspaceType) argument_list[3].long_reference;
8420 if (attribute_flag[4] != 0)
8421 verbose=argument_list[4].long_reference != 0 ?
8422 MagickTrue : MagickFalse;
8423 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
8424 smoothing_threshold);
8425 break;
8426 }
8427 case 51: /* Signature */
8428 {
8429 (void) SignatureImage(image);
8430 break;
8431 }
8432 case 52: /* Solarize */
8433 {
8434 geometry_info.rho=QuantumRange/2.0;
8435 if (attribute_flag[0] != 0)
8436 flags=ParseGeometry(argument_list[0].string_reference,
8437 &geometry_info);
8438 if (attribute_flag[1] != 0)
8439 geometry_info.rho=StringToDouble(argument_list[1].string_reference,
8440 QuantumRange);
8441 (void) SolarizeImage(image,geometry_info.rho);
8442 break;
8443 }
8444 case 53: /* Sync */
8445 {
8446 (void) SyncImage(image);
8447 break;
8448 }
8449 case 54: /* Texture */
8450 {
8451 if (attribute_flag[0] == 0)
8452 break;
8453 TextureImage(image,argument_list[0].image_reference);
8454 break;
8455 }
8456 case 55: /* Evalute */
8457 {
8458 MagickEvaluateOperator
8459 op;
8460
8461 op=SetEvaluateOperator;
8462 if (attribute_flag[0] == MagickFalse)
8463 argument_list[0].real_reference=0.0;
8464 if (attribute_flag[1] != MagickFalse)
8465 op=(MagickEvaluateOperator) argument_list[1].long_reference;
8466 if (attribute_flag[2] != MagickFalse)
8467 channel=(ChannelType) argument_list[2].long_reference;
8468 (void) EvaluateImageChannel(image,channel,op,
8469 argument_list[0].real_reference,exception);
8470 break;
8471 }
8472 case 56: /* Transparent */
8473 {
8474 double
8475 opacity;
8476
8477 MagickBooleanType
8478 invert;
8479
8480 MagickPixelPacket
8481 target;
8482
8483 (void) QueryMagickColor("none",&target,exception);
8484 if (attribute_flag[0] != 0)
8485 (void) QueryMagickColor(argument_list[0].string_reference,&target,
8486 exception);
8487 opacity=TransparentOpacity;
8488 if (attribute_flag[1] != 0)
8489 opacity=StringToDouble(argument_list[1].string_reference,
8490 QuantumRange);
8491 if (attribute_flag[2] != 0)
8492 image->fuzz=StringToDouble(argument_list[2].string_reference,
8493 QuantumRange);
8494 if (attribute_flag[3] == 0)
8495 argument_list[3].long_reference=0;
8496 invert=MagickFalse;
8497 if (attribute_flag[3] != 0)
8498 invert=(MagickBooleanType) argument_list[3].long_reference;
8499 (void) TransparentPaintImage(image,&target,RoundToQuantum(opacity),
8500 invert);
8501 break;
8502 }
8503 case 57: /* Threshold */
8504 {
8505 double
8506 threshold;
8507
8508 if (attribute_flag[0] == 0)
8509 argument_list[0].string_reference="50%";
8510 if (attribute_flag[1] != 0)
8511 channel=(ChannelType) argument_list[1].long_reference;
8512 threshold=StringToDouble(argument_list[0].string_reference,
8513 QuantumRange);
8514 (void) BilevelImageChannel(image,channel,threshold);
8515 break;
8516 }
8517 case 58: /* Charcoal */
8518 {
8519 if (attribute_flag[0] != 0)
8520 {
8521 flags=ParseGeometry(argument_list[0].string_reference,
8522 &geometry_info);
8523 if ((flags & SigmaValue) == 0)
8524 geometry_info.sigma=1.0;
8525 }
8526 if (attribute_flag[1] != 0)
8527 geometry_info.rho=argument_list[1].real_reference;
8528 if (attribute_flag[2] != 0)
8529 geometry_info.sigma=argument_list[2].real_reference;
8530 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
8531 exception);
8532 break;
8533 }
8534 case 59: /* Trim */
8535 {
8536 if (attribute_flag[0] != 0)
8537 image->fuzz=StringToDouble(argument_list[0].string_reference,
8538 QuantumRange);
8539 image=TrimImage(image,exception);
8540 break;
8541 }
8542 case 60: /* Wave */
8543 {
8544 if (attribute_flag[0] != 0)
8545 {
8546 flags=ParseGeometry(argument_list[0].string_reference,
8547 &geometry_info);
8548 if ((flags & SigmaValue) == 0)
8549 geometry_info.sigma=1.0;
8550 }
8551 if (attribute_flag[1] != 0)
8552 geometry_info.rho=argument_list[1].real_reference;
8553 if (attribute_flag[2] != 0)
8554 geometry_info.sigma=argument_list[2].real_reference;
8555 if (attribute_flag[3] != 0)
8556 image->interpolate=(InterpolatePixelMethod)
8557 argument_list[3].long_reference;
8558 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
8559 exception);
8560 break;
8561 }
8562 case 61: /* Separate */
8563 {
8564 if (attribute_flag[0] != 0)
8565 channel=(ChannelType) argument_list[0].long_reference;
8566 (void) SeparateImageChannel(image,channel);
8567 break;
8568 }
8569 case 63: /* Stereo */
8570 {
8571 if (attribute_flag[0] == 0)
8572 {
8573 ThrowPerlException(exception,OptionError,"StereoImageRequired",
8574 PackageName);
8575 goto PerlException;
8576 }
8577 if (attribute_flag[1] != 0)
8578 geometry.x=argument_list[1].long_reference;
8579 if (attribute_flag[2] != 0)
8580 geometry.y=argument_list[2].long_reference;
8581 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
8582 geometry.x,geometry.y,exception);
8583 break;
8584 }
8585 case 64: /* Stegano */
8586 {
8587 if (attribute_flag[0] == 0)
8588 {
8589 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
8590 PackageName);
8591 goto PerlException;
8592 }
8593 if (attribute_flag[1] == 0)
8594 argument_list[1].long_reference=0;
8595 image->offset=argument_list[1].long_reference;
8596 image=SteganoImage(image,argument_list[0].image_reference,exception);
8597 break;
8598 }
8599 case 65: /* Deconstruct */
8600 {
8601 image=DeconstructImages(image,exception);
8602 break;
8603 }
8604 case 66: /* GaussianBlur */
8605 {
8606 if (attribute_flag[0] != 0)
8607 {
8608 flags=ParseGeometry(argument_list[0].string_reference,
8609 &geometry_info);
8610 if ((flags & SigmaValue) == 0)
8611 geometry_info.sigma=1.0;
8612 }
8613 if (attribute_flag[1] != 0)
8614 geometry_info.rho=argument_list[1].real_reference;
8615 if (attribute_flag[2] != 0)
8616 geometry_info.sigma=argument_list[2].real_reference;
8617 if (attribute_flag[3] != 0)
8618 channel=(ChannelType) argument_list[3].long_reference;
8619 image=GaussianBlurImageChannel(image,channel,geometry_info.rho,
8620 geometry_info.sigma,exception);
8621 break;
8622 }
8623 case 67: /* Convolve */
8624 {
8625 AV
8626 *av;
8627
8628 double
8629 *kernel;
8630
8631 unsigned long
8632 order;
8633
8634 if (attribute_flag[0] == 0)
8635 break;
8636 if (attribute_flag[1] != 0)
8637 channel=(ChannelType) argument_list[1].long_reference;
8638 if (attribute_flag[2] != 0)
8639 image->bias=StringToDouble(argument_list[2].string_reference,
8640 QuantumRange);
8641 av=(AV *) argument_list[0].array_reference;
8642 order=(unsigned long) sqrt(av_len(av)+1);
8643 kernel=(double *) AcquireQuantumMemory(order,order*sizeof(*kernel));
8644 if (kernel == (double *) NULL)
8645 {
8646 ThrowPerlException(exception,ResourceLimitFatalError,
8647 "MemoryAllocationFailed",PackageName);
8648 goto PerlException;
8649 }
8650 for (j=0; (j < (long) (order*order)) && (j < (av_len(av)+1)); j++)
8651 kernel[j]=(double) SvNV(*(av_fetch(av,j,0)));
8652 for ( ; j < (long) (order*order); j++)
8653 kernel[j]=0.0;
8654 image=ConvolveImageChannel(image,channel,order,kernel,exception);
8655 kernel=(double *) RelinquishMagickMemory(kernel);
8656 break;
8657 }
8658 case 68: /* Profile */
8659 {
8660 const char
8661 *name;
8662
8663 Image
8664 *profile_image;
8665
8666 ImageInfo
8667 *profile_info;
8668
8669 StringInfo
8670 *profile;
8671
8672 name="*";
8673 if (attribute_flag[0] != 0)
8674 name=argument_list[0].string_reference;
8675 if (attribute_flag[2] != 0)
8676 image->rendering_intent=(RenderingIntent)
8677 argument_list[2].long_reference;
8678 if (attribute_flag[3] != 0)
8679 image->black_point_compensation=
8680 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse;
8681 if (attribute_flag[1] != 0)
8682 {
8683 if (argument_list[1].length == 0)
8684 {
8685 /*
8686 Remove a profile from the image.
8687 */
8688 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
8689 MagickTrue);
8690 break;
8691 }
8692 /*
8693 Associate user supplied profile with the image.
8694 */
8695 profile=AcquireStringInfo(argument_list[1].length);
8696 SetStringInfoDatum(profile,(const unsigned char *)
8697 argument_list[1].string_reference);
8698 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
8699 (unsigned long) GetStringInfoLength(profile),MagickFalse);
8700 profile=DestroyStringInfo(profile);
8701 break;
8702 }
8703 /*
8704 Associate a profile with the image.
8705 */
8706 profile_info=
8707 CloneImageInfo(info ? info->image_info : (ImageInfo *) NULL);
8708 (void) CopyMagickString(profile_info->filename,name,MaxTextExtent);
8709 profile_image=ReadImages(profile_info,&image->exception);
8710 if (profile_image == (Image *) NULL)
8711 break;
8712 ResetImageProfileIterator(profile_image);
8713 name=GetNextImageProfile(profile_image);
8714 while (name != (const char *) NULL)
8715 {
8716 const StringInfo
8717 *profile;
8718
8719 profile=GetImageProfile(profile_image,name);
8720 if (profile != (const StringInfo *) NULL)
8721 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
8722 (unsigned long) GetStringInfoLength(profile),MagickFalse);
8723 name=GetNextImageProfile(profile_image);
8724 }
8725 profile_image=DestroyImage(profile_image);
8726 profile_info=DestroyImageInfo(profile_info);
8727 break;
8728 }
8729 case 69: /* UnsharpMask */
8730 {
8731 if (attribute_flag[0] != 0)
8732 {
8733 flags=ParseGeometry(argument_list[0].string_reference,
8734 &geometry_info);
8735 if ((flags & SigmaValue) == 0)
8736 geometry_info.sigma=1.0;
8737 if ((flags & XiValue) == 0)
8738 geometry_info.xi=1.0;
8739 if ((flags & PsiValue) == 0)
8740 geometry_info.psi=0.5;
8741 }
8742 if (attribute_flag[1] != 0)
8743 geometry_info.rho=argument_list[1].real_reference;
8744 if (attribute_flag[2] != 0)
8745 geometry_info.sigma=argument_list[2].real_reference;
8746 if (attribute_flag[3] != 0)
8747 geometry_info.xi=argument_list[3].real_reference;
8748 if (attribute_flag[4] != 0)
8749 geometry_info.psi=argument_list[4].real_reference;
8750 if (attribute_flag[5] != 0)
8751 channel=(ChannelType) argument_list[5].long_reference;
8752 image=UnsharpMaskImageChannel(image,channel,geometry_info.rho,
8753 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
8754 break;
8755 }
8756 case 70: /* MotionBlur */
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 }
8767 if (attribute_flag[1] != 0)
8768 geometry_info.rho=argument_list[1].real_reference;
8769 if (attribute_flag[2] != 0)
8770 geometry_info.sigma=argument_list[2].real_reference;
8771 if (attribute_flag[3] != 0)
8772 geometry_info.xi=argument_list[3].real_reference;
8773 if (attribute_flag[4] != 0)
8774 channel=(ChannelType) argument_list[4].long_reference;
8775 image=MotionBlurImageChannel(image,channel,geometry_info.rho,geometry_info.sigma,
8776 geometry_info.xi,exception);
8777 break;
8778 }
8779 case 71: /* OrderedDither */
8780 {
8781 if (attribute_flag[0] == 0)
8782 argument_list[0].string_reference="o8x8";
8783 if (attribute_flag[1] != 0)
8784 channel=(ChannelType) argument_list[1].long_reference;
8785 (void) OrderedPosterizeImageChannel(image,channel,
8786 argument_list[0].string_reference,exception);
8787 break;
8788 }
8789 case 72: /* Shave */
8790 {
8791 if (attribute_flag[0] != 0)
8792 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8793 &geometry,exception);
8794 if (attribute_flag[1] != 0)
8795 geometry.width=argument_list[1].long_reference;
8796 if (attribute_flag[2] != 0)
8797 geometry.height=argument_list[2].long_reference;
8798 image=ShaveImage(image,&geometry,exception);
8799 break;
8800 }
8801 case 73: /* Level */
8802 {
8803 double
8804 black_point,
8805 gamma,
8806 white_point;
8807
8808 black_point=0.0;
8809 white_point=(MagickRealType) image->columns*image->rows;
8810 gamma=1.0;
8811 if (attribute_flag[0] != 0)
8812 {
8813 flags=ParseGeometry(argument_list[0].string_reference,
8814 &geometry_info);
8815 black_point=geometry_info.rho;
8816 if ((flags & SigmaValue) != 0)
8817 white_point=geometry_info.sigma;
8818 if ((flags & XiValue) != 0)
8819 gamma=geometry_info.xi;
8820 if ((flags & PercentValue) != 0)
8821 {
8822 black_point*=(double) (QuantumRange/100.0);
8823 white_point*=(double) (QuantumRange/100.0);
8824 }
8825 if ((flags & SigmaValue) == 0)
8826 white_point=(double) QuantumRange-black_point;
8827 }
8828 if (attribute_flag[1] != 0)
8829 black_point=argument_list[1].real_reference;
8830 if (attribute_flag[2] != 0)
8831 white_point=argument_list[2].real_reference;
8832 if (attribute_flag[3] != 0)
8833 gamma=argument_list[3].real_reference;
8834 if (attribute_flag[4] != 0)
8835 channel=(ChannelType) argument_list[4].long_reference;
8836 if (attribute_flag[5] != 0)
8837 {
8838 argument_list[0].real_reference=argument_list[5].real_reference;
8839 attribute_flag[0]=attribute_flag[5];
8840 }
8841 (void) LevelImageChannel(image,channel,black_point,white_point,gamma);
8842 break;
8843 }
8844 case 74: /* Clip */
8845 {
8846 if (attribute_flag[0] == 0)
8847 argument_list[0].string_reference="#1";
8848 if (attribute_flag[1] == 0)
8849 argument_list[1].long_reference=MagickTrue;
8850 (void) ClipImagePath(image,argument_list[0].string_reference,
8851 argument_list[1].long_reference != 0 ? MagickTrue : MagickFalse);
8852 break;
8853 }
8854 case 75: /* AffineTransform */
8855 {
8856 DrawInfo
8857 *draw_info;
8858
8859 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8860 (DrawInfo *) NULL);
8861 if (attribute_flag[0] != 0)
8862 {
8863 AV
8864 *av;
8865
8866 av=(AV *) argument_list[0].array_reference;
8867 if ((av_len(av) != 3) && (av_len(av) != 5))
8868 {
8869 ThrowPerlException(exception,OptionError,
8870 "affine matrix must have 4 or 6 elements",PackageName);
8871 goto PerlException;
8872 }
8873 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8874 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8875 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8876 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8877 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8878 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8879 {
8880 ThrowPerlException(exception,OptionError,
8881 "affine matrix is singular",PackageName);
8882 goto PerlException;
8883 }
8884 if (av_len(av) == 5)
8885 {
8886 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8887 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8888 }
8889 }
8890 for (j=1; j < 6; j++)
8891 {
8892 if (attribute_flag[j] == 0)
8893 continue;
8894 value=argument_list[j].string_reference;
8895 angle=argument_list[j].real_reference;
8896 current=draw_info->affine;
8897 GetAffineMatrix(&affine);
8898 switch (j)
8899 {
8900 case 1:
8901 {
8902 /*
8903 Translate.
8904 */
8905 flags=ParseGeometry(value,&geometry_info);
8906 affine.tx=geometry_info.xi;
8907 affine.ty=geometry_info.psi;
8908 if ((flags & PsiValue) == 0)
8909 affine.ty=affine.tx;
8910 break;
8911 }
8912 case 2:
8913 {
8914 /*
8915 Scale.
8916 */
8917 flags=ParseGeometry(value,&geometry_info);
8918 affine.sx=geometry_info.rho;
8919 affine.sy=geometry_info.sigma;
8920 if ((flags & SigmaValue) == 0)
8921 affine.sy=affine.sx;
8922 break;
8923 }
8924 case 3:
8925 {
8926 /*
8927 Rotate.
8928 */
8929 if (angle == 0.0)
8930 break;
8931 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8932 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8933 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8934 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8935 break;
8936 }
8937 case 4:
8938 {
8939 /*
8940 SkewX.
8941 */
8942 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8943 break;
8944 }
8945 case 5:
8946 {
8947 /*
8948 SkewY.
8949 */
8950 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8951 break;
8952 }
8953 }
8954 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8955 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8956 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8957 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8958 draw_info->affine.tx=
8959 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8960 draw_info->affine.ty=
8961 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8962 }
8963 if (attribute_flag[6] != 0)
8964 image->interpolate=(InterpolatePixelMethod)
8965 argument_list[6].long_reference;
8966 if (attribute_flag[7] != 0)
8967 QueryColorDatabase(argument_list[7].string_reference,
8968 &image->background_color,exception);
8969 image=AffineTransformImage(image,&draw_info->affine,exception);
8970 draw_info=DestroyDrawInfo(draw_info);
8971 break;
8972 }
8973 case 76: /* Difference */
8974 {
8975 if (attribute_flag[0] == 0)
8976 {
8977 ThrowPerlException(exception,OptionError,
8978 "ReferenceImageRequired",PackageName);
8979 goto PerlException;
8980 }
8981 if (attribute_flag[1] != 0)
8982 image->fuzz=StringToDouble(argument_list[1].string_reference,
8983 QuantumRange);
8984 (void) IsImagesEqual(image,argument_list[0].image_reference);
8985 break;
8986 }
8987 case 77: /* AdaptiveThreshold */
8988 {
8989 if (attribute_flag[0] != 0)
8990 {
8991 flags=ParseGeometry(argument_list[0].string_reference,
8992 &geometry_info);
8993 if ((flags & PercentValue) != 0)
8994 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
8995 }
8996 if (attribute_flag[1] != 0)
8997 geometry_info.rho=argument_list[1].long_reference;
8998 if (attribute_flag[2] != 0)
8999 geometry_info.sigma=argument_list[2].long_reference;
9000 if (attribute_flag[3] != 0)
9001 geometry_info.xi=argument_list[3].long_reference;;
9002 image=AdaptiveThresholdImage(image,(unsigned long) geometry_info.rho,
9003 (unsigned long) geometry_info.sigma,(long) geometry_info.xi,
9004 exception);
9005 break;
9006 }
9007 case 78: /* Resample */
9008 {
9009 unsigned long
9010 height,
9011 width;
9012
9013 if (attribute_flag[0] != 0)
9014 {
9015 flags=ParseGeometry(argument_list[0].string_reference,
9016 &geometry_info);
9017 if ((flags & SigmaValue) == 0)
9018 geometry_info.sigma=geometry_info.rho;
9019 }
9020 if (attribute_flag[1] != 0)
9021 geometry_info.rho=argument_list[1].real_reference;
9022 if (attribute_flag[2] != 0)
9023 geometry_info.sigma=argument_list[2].real_reference;
9024 if (attribute_flag[3] == 0)
9025 argument_list[3].long_reference=(long) UndefinedFilter;
9026 if (attribute_flag[4] == 0)
9027 SetImageArtifact(image,"filter:support",
9028 argument_list[4].string_reference);
9029 if (attribute_flag[5] != 0)
9030 argument_list[5].real_reference=1.0;
9031 width=(unsigned long) (geometry_info.rho*image->columns/
9032 (image->x_resolution == 0.0 ? 72.0 : image->x_resolution)+0.5);
9033 height=(unsigned long) (geometry_info.sigma*image->rows/
9034 (image->y_resolution == 0.0 ? 72.0 : image->y_resolution)+0.5);
9035 image=ResizeImage(image,width,height,(FilterTypes)
9036 argument_list[3].long_reference,argument_list[5].real_reference,
9037 exception);
9038 if (image != (Image *) NULL)
9039 {
9040 image->x_resolution=geometry_info.rho;
9041 image->y_resolution=geometry_info.sigma;
9042 }
9043 break;
9044 }
9045 case 79: /* Describe */
9046 {
9047 if (attribute_flag[0] == 0)
9048 argument_list[0].file_reference=(FILE *) NULL;
9049 (void) IdentifyImage(image,argument_list[0].file_reference,
9050 MagickTrue);
9051 break;
9052 }
9053 case 80: /* BlackThreshold */
9054 {
9055 if (attribute_flag[0] == 0)
9056 argument_list[0].string_reference="50%";
9057 if (attribute_flag[2] != 0)
9058 channel=(ChannelType) argument_list[2].long_reference;
9059 BlackThresholdImageChannel(image,channel,
9060 argument_list[0].string_reference,exception);
9061 break;
9062 }
9063 case 81: /* WhiteThreshold */
9064 {
9065 if (attribute_flag[0] == 0)
9066 argument_list[0].string_reference="50%";
9067 if (attribute_flag[2] != 0)
9068 channel=(ChannelType) argument_list[2].long_reference;
9069 WhiteThresholdImageChannel(image,channel,
9070 argument_list[0].string_reference,exception);
9071 break;
9072 }
9073 case 82: /* RadialBlur */
9074 {
9075 if (attribute_flag[0] != 0)
9076 {
9077 flags=ParseGeometry(argument_list[0].string_reference,
9078 &geometry_info);
9079 if ((flags & SigmaValue) == 0)
9080 geometry_info.sigma=1.0;
9081 }
9082 if (attribute_flag[1] != 0)
9083 geometry_info.rho=argument_list[1].real_reference;
9084 if (attribute_flag[2] != 0)
9085 channel=(ChannelType) argument_list[2].long_reference;
9086 image=RadialBlurImageChannel(image,channel,geometry_info.rho,
9087 exception);
9088 break;
9089 }
9090 case 83: /* Thumbnail */
9091 {
9092 if (attribute_flag[0] != 0)
9093 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9094 &geometry,exception);
9095 if (attribute_flag[1] != 0)
9096 geometry.width=argument_list[1].long_reference;
9097 if (attribute_flag[2] != 0)
9098 geometry.height=argument_list[2].long_reference;
9099 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
9100 break;
9101 }
9102 case 84: /* Strip */
9103 {
9104 (void) StripImage(image);
9105 break;
9106 }
9107 case 85: /* Tint */
9108 {
9109 PixelPacket
9110 target;
9111
9112 (void) GetOneVirtualPixel(image,0,0,&target,exception);
9113 if (attribute_flag[0] != 0)
9114 (void) QueryColorDatabase(argument_list[0].string_reference,&target,
9115 exception);
9116 if (attribute_flag[1] == 0)
9117 argument_list[1].string_reference="100";
9118 image=TintImage(image,argument_list[1].string_reference,target,
9119 exception);
9120 break;
9121 }
9122 case 86: /* Channel */
9123 {
9124 if (attribute_flag[0] != 0)
9125 channel=(ChannelType) argument_list[0].long_reference;
9126 (void) SeparateImageChannel(image,channel);
9127 break;
9128 }
9129 case 87: /* Splice */
9130 {
9131 if (attribute_flag[0] != 0)
9132 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
9133 &geometry,exception);
9134 if (attribute_flag[1] != 0)
9135 geometry.width=argument_list[1].long_reference;
9136 if (attribute_flag[2] != 0)
9137 geometry.height=argument_list[2].long_reference;
9138 if (attribute_flag[3] != 0)
9139 geometry.x=argument_list[3].long_reference;
9140 if (attribute_flag[4] != 0)
9141 geometry.y=argument_list[4].long_reference;
9142 if (attribute_flag[5] != 0)
9143 image->fuzz=StringToDouble(argument_list[5].string_reference,
9144 QuantumRange);
9145 if (attribute_flag[6] != 0)
9146 (void) QueryColorDatabase(argument_list[6].string_reference,
9147 &image->background_color,exception);
9148 if (attribute_flag[7] != 0)
9149 image->gravity=(GravityType) argument_list[7].long_reference;
9150 image=SpliceImage(image,&geometry,exception);
9151 break;
9152 }
9153 case 88: /* Posterize */
9154 {
9155 if (attribute_flag[0] == 0)
9156 argument_list[0].long_reference=3;
9157 if (attribute_flag[1] == 0)
9158 argument_list[1].long_reference=0;
9159 (void) PosterizeImage(image,argument_list[0].long_reference,
9160 argument_list[1].long_reference ? MagickTrue : MagickFalse);
9161 break;
9162 }
9163 case 89: /* Shadow */
9164 {
9165 if (attribute_flag[0] != 0)
9166 {
9167 flags=ParseGeometry(argument_list[0].string_reference,
9168 &geometry_info);
9169 if ((flags & SigmaValue) == 0)
9170 geometry_info.sigma=1.0;
9171 if ((flags & XiValue) == 0)
9172 geometry_info.xi=4.0;
9173 if ((flags & PsiValue) == 0)
9174 geometry_info.psi=4.0;
9175 }
9176 if (attribute_flag[1] != 0)
9177 geometry_info.rho=argument_list[1].real_reference;
9178 if (attribute_flag[2] != 0)
9179 geometry_info.sigma=argument_list[2].real_reference;
9180 if (attribute_flag[3] != 0)
9181 geometry_info.xi=argument_list[3].long_reference;
9182 if (attribute_flag[4] != 0)
9183 geometry_info.psi=argument_list[4].long_reference;
9184 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
9185 (long) (geometry_info.xi+0.5),(long) (geometry_info.psi+0.5),
9186 exception);
9187 break;
9188 }
9189 case 90: /* Identify */
9190 {
9191 if (attribute_flag[0] == 0)
9192 argument_list[0].file_reference=(FILE *) NULL;
9193 (void) IdentifyImage(image,argument_list[0].file_reference,
9194 MagickTrue);
9195 break;
9196 }
9197 case 91: /* SepiaTone */
9198 {
9199 if (attribute_flag[0] == 0)
9200 argument_list[0].real_reference=80.0*QuantumRange/100.0;
9201 image=SepiaToneImage(image,argument_list[0].real_reference,
9202 exception);
9203 break;
9204 }
9205 case 92: /* SigmoidalContrast */
9206 {
9207 MagickBooleanType
9208 sharpen;
9209
9210 if (attribute_flag[0] != 0)
9211 {
9212 flags=ParseGeometry(argument_list[0].string_reference,
9213 &geometry_info);
9214 if ((flags & SigmaValue) == 0)
9215 geometry_info.sigma=QuantumRange/2.0;
9216 if ((flags & PercentValue) != 0)
9217 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
9218 }
9219 if (attribute_flag[1] != 0)
9220 geometry_info.rho=argument_list[1].real_reference;
9221 if (attribute_flag[2] != 0)
9222 geometry_info.sigma=argument_list[2].real_reference;
9223 if (attribute_flag[3] != 0)
9224 channel=(ChannelType) argument_list[3].long_reference;
9225 sharpen=MagickTrue;
9226 if (attribute_flag[4] != 0)
9227 sharpen=argument_list[4].long_reference != 0 ? MagickTrue :
9228 MagickFalse;
9229 (void) SigmoidalContrastImageChannel(image,channel,sharpen,
9230 geometry_info.rho,geometry_info.sigma);
9231 break;
9232 }
9233 case 93: /* Extent */
9234 {
9235 GravityType
9236 gravity;
9237
9238 gravity=image->gravity;
9239 if (attribute_flag[7] != 0)
9240 gravity=(GravityType) argument_list[7].long_reference;
9241 if (attribute_flag[0] != 0)
9242 {
9243 SetGeometry(image,&geometry);
9244 (void) ParseAbsoluteGeometry(argument_list[0].string_reference,
9245 &geometry);
9246 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
9247 &geometry);
9248 }
9249 if (attribute_flag[1] != 0)
9250 geometry.width=argument_list[1].long_reference;
9251 if (attribute_flag[2] != 0)
9252 geometry.height=argument_list[2].long_reference;
9253 if (attribute_flag[3] != 0)
9254 geometry.x=argument_list[3].long_reference;
9255 if (attribute_flag[4] != 0)
9256 geometry.y=argument_list[4].long_reference;
9257 if (attribute_flag[5] != 0)
9258 image->fuzz=StringToDouble(argument_list[5].string_reference,
9259 QuantumRange);
9260 if (attribute_flag[6] != 0)
9261 (void) QueryColorDatabase(argument_list[6].string_reference,
9262 &image->background_color,exception);
9263 GravityAdjustGeometry(image->columns,image->rows,gravity,&geometry);
9264 image=ExtentImage(image,&geometry,exception);
9265 break;
9266 }
9267 case 94: /* Vignette */
9268 {
9269 if (attribute_flag[0] != 0)
9270 {
9271 flags=ParseGeometry(argument_list[0].string_reference,
9272 &geometry_info);
9273 if ((flags & SigmaValue) == 0)
9274 geometry_info.sigma=1.0;
9275 if ((flags & XiValue) == 0)
9276 geometry_info.xi=0.1*image->columns;
9277 if ((flags & PsiValue) == 0)
9278 geometry_info.psi=0.1*image->rows;
9279 }
9280 if (attribute_flag[1] != 0)
9281 geometry_info.rho=argument_list[1].real_reference;
9282 if (attribute_flag[2] != 0)
9283 geometry_info.sigma=argument_list[2].real_reference;
9284 if (attribute_flag[3] != 0)
9285 geometry_info.xi=argument_list[3].long_reference;
9286 if (attribute_flag[4] != 0)
9287 geometry_info.psi=argument_list[4].long_reference;
9288 if (attribute_flag[5] != 0)
9289 (void) QueryColorDatabase(argument_list[5].string_reference,
9290 &image->background_color,exception);
9291 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
9292 (long) (geometry_info.xi+0.5),(long) (geometry_info.psi+0.5),
9293 exception);
9294 break;
9295 }
9296 case 95: /* ContrastStretch */
9297 {
9298 double
9299 black_point,
9300 white_point;
9301
9302 black_point=0.0;
9303 white_point=(MagickRealType) image->columns*image->rows;
9304 if (attribute_flag[0] != 0)
9305 {
9306 flags=ParseGeometry(argument_list[0].string_reference,
9307 &geometry_info);
9308 black_point=geometry_info.rho;
9309 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
9310 black_point;
9311 if ((flags & PercentValue) != 0)
9312 {
9313 black_point*=(double) image->columns*image->rows/100.0;
9314 white_point*=(double) image->columns*image->rows/100.0;
9315 }
9316 white_point=(MagickRealType) image->columns*image->rows-
9317 white_point;
9318 }
9319 if (attribute_flag[1] != 0)
9320 black_point=argument_list[1].real_reference;
9321 if (attribute_flag[2] != 0)
9322 white_point=argument_list[2].real_reference;
9323 if (attribute_flag[4] != 0)
9324 channel=(ChannelType) argument_list[4].long_reference;
9325 (void) ContrastStretchImageChannel(image,channel,black_point,
9326 white_point);
9327 break;
9328 }
9329 case 96: /* Sans0 */
9330 {
9331 break;
9332 }
9333 case 97: /* Sans1 */
9334 {
9335 break;
9336 }
9337 case 98: /* AdaptiveSharpen */
9338 {
9339 if (attribute_flag[0] != 0)
9340 {
9341 flags=ParseGeometry(argument_list[0].string_reference,
9342 &geometry_info);
9343 if ((flags & SigmaValue) == 0)
9344 geometry_info.sigma=1.0;
9345 }
9346 if (attribute_flag[1] != 0)
9347 geometry_info.rho=argument_list[1].real_reference;
9348 if (attribute_flag[2] != 0)
9349 geometry_info.sigma=argument_list[2].real_reference;
9350 if (attribute_flag[3] != 0)
9351 channel=(ChannelType) argument_list[3].long_reference;
9352 image=AdaptiveSharpenImageChannel(image,channel,geometry_info.rho,
9353 geometry_info.sigma,exception);
9354 break;
9355 }
9356 case 99: /* Transpose */
9357 {
9358 image=TransposeImage(image,exception);
9359 break;
9360 }
9361 case 100: /* Tranverse */
9362 {
9363 image=TransverseImage(image,exception);
9364 break;
9365 }
9366 case 101: /* AutoOrient */
9367 {
9368 switch (image->orientation)
9369 {
9370 case TopRightOrientation:
9371 {
9372 image=FlopImage(image,exception);
9373 break;
9374 }
9375 case BottomRightOrientation:
9376 {
9377 image=RotateImage(image,180.0,exception);
9378 break;
9379 }
9380 case BottomLeftOrientation:
9381 {
9382 image=FlipImage(image,exception);
9383 break;
9384 }
9385 case LeftTopOrientation:
9386 {
9387 image=TransposeImage(image,exception);
9388 break;
9389 }
9390 case RightTopOrientation:
9391 {
9392 image=RotateImage(image,90.0,exception);
9393 break;
9394 }
9395 case RightBottomOrientation:
9396 {
9397 image=TransverseImage(image,exception);
9398 break;
9399 }
9400 case LeftBottomOrientation:
9401 {
9402 image=RotateImage(image,270.0,exception);
9403 break;
9404 }
9405 default:
9406 break;
9407 }
9408 break;
9409 }
9410 case 102: /* AdaptiveBlur */
9411 {
9412 if (attribute_flag[0] != 0)
9413 {
9414 flags=ParseGeometry(argument_list[0].string_reference,
9415 &geometry_info);
9416 if ((flags & SigmaValue) == 0)
9417 geometry_info.sigma=1.0;
9418 }
9419 if (attribute_flag[1] != 0)
9420 geometry_info.rho=argument_list[1].real_reference;
9421 if (attribute_flag[2] != 0)
9422 geometry_info.sigma=argument_list[2].real_reference;
9423 if (attribute_flag[3] != 0)
9424 channel=(ChannelType) argument_list[3].long_reference;
9425 image=AdaptiveBlurImageChannel(image,channel,geometry_info.rho,
9426 geometry_info.sigma,exception);
9427 break;
9428 }
9429 case 103: /* Sketch */
9430 {
9431 if (attribute_flag[0] != 0)
9432 {
9433 flags=ParseGeometry(argument_list[0].string_reference,
9434 &geometry_info);
9435 if ((flags & SigmaValue) == 0)
9436 geometry_info.sigma=1.0;
9437 if ((flags & XiValue) == 0)
9438 geometry_info.xi=1.0;
9439 }
9440 if (attribute_flag[1] != 0)
9441 geometry_info.rho=argument_list[1].real_reference;
9442 if (attribute_flag[2] != 0)
9443 geometry_info.sigma=argument_list[2].real_reference;
9444 if (attribute_flag[3] != 0)
9445 geometry_info.xi=argument_list[3].real_reference;
9446 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
9447 geometry_info.xi,exception);
9448 break;
9449 }
9450 case 104: /* UniqueColors */
9451 {
9452 image=UniqueImageColors(image,exception);
9453 break;
9454 }
9455 case 105: /* AdaptiveResize */
9456 {
9457 if (attribute_flag[0] != 0)
9458 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9459 &geometry,exception);
9460 if (attribute_flag[1] != 0)
9461 geometry.width=argument_list[1].long_reference;
9462 if (attribute_flag[2] != 0)
9463 geometry.height=argument_list[2].long_reference;
9464 if (attribute_flag[3] != 0)
9465 image->filter=(FilterTypes) argument_list[4].long_reference;
9466 if (attribute_flag[4] != 0)
9467 SetImageArtifact(image,"filter:support",
9468 argument_list[4].string_reference);
9469 if (attribute_flag[5] != 0)
9470 image->blur=argument_list[5].real_reference;
9471 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
9472 exception);
9473 break;
9474 }
9475 case 106: /* ClipMask */
9476 {
9477 if (attribute_flag[0] == 0)
9478 {
9479 ThrowPerlException(exception,OptionError,"MaskImageRequired",
9480 PackageName);
9481 goto PerlException;
9482 }
9483 image->clip_mask=CloneImage(argument_list[0].image_reference,0,0,
9484 MagickTrue,exception);
9485 (void) NegateImage(image->clip_mask,MagickFalse);
9486 break;
9487 }
9488 case 107: /* LinearStretch */
9489 {
9490 double
9491 black_point,
9492 white_point;
9493
9494 black_point=0.0;
9495 white_point=(MagickRealType) image->columns*image->rows;
9496 if (attribute_flag[0] != 0)
9497 {
9498 flags=ParseGeometry(argument_list[0].string_reference,
9499 &geometry_info);
9500 if ((flags & SigmaValue) != 0)
9501 white_point=geometry_info.sigma;
9502 if ((flags & PercentValue) != 0)
9503 {
9504 black_point*=(double) image->columns*image->rows/100.0;
9505 white_point*=(double) image->columns*image->rows/100.0;
9506 }
9507 if ((flags & SigmaValue) == 0)
9508 white_point=(double) image->columns*image->rows-black_point;
9509 }
9510 if (attribute_flag[1] != 0)
9511 black_point=argument_list[1].real_reference;
9512 if (attribute_flag[2] != 0)
9513 white_point=argument_list[2].real_reference;
9514 (void) LinearStretchImage(image,black_point,white_point);
9515 break;
9516 }
9517 case 108: /* Recolor */
9518 {
9519 AV
9520 *av;
9521
9522 double
9523 *color_matrix;
9524
9525 unsigned long
9526 order;
9527
9528 if (attribute_flag[0] == 0)
9529 break;
9530 av=(AV *) argument_list[0].array_reference;
9531 order=(unsigned long) sqrt(av_len(av)+1);
9532 color_matrix=(double *) AcquireQuantumMemory(order,order*
9533 sizeof(*color_matrix));
9534 if (color_matrix == (double *) NULL)
9535 {
9536 ThrowPerlException(exception,ResourceLimitFatalError,
9537 "MemoryAllocationFailed",PackageName);
9538 goto PerlException;
9539 }
9540 for (j=0; (j < (long) (order*order)) && (j < (av_len(av)+1)); j++)
9541 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
9542 for ( ; j < (long) (order*order); j++)
9543 color_matrix[j]=0.0;
9544 image=RecolorImage(image,order,color_matrix,exception);
9545 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
9546 break;
9547 }
9548 case 109: /* Mask */
9549 {
9550 if (attribute_flag[0] == 0)
9551 {
9552 ThrowPerlException(exception,OptionError,"MaskImageRequired",
9553 PackageName);
9554 goto PerlException;
9555 }
9556 image->mask=CloneImage(argument_list[0].image_reference,0,0,
9557 MagickTrue,exception);
9558 (void) NegateImage(image->mask,MagickFalse);
9559 break;
9560 }
9561 case 110: /* Polaroid */
9562 {
9563 DrawInfo
9564 *draw_info;
9565
9566 double
9567 angle;
9568
9569 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9570 (DrawInfo *) NULL);
9571 if (attribute_flag[0] != 0)
9572 (void) SetImageProperty(image,"caption",InterpretImageProperties(
9573 info ? info->image_info : (ImageInfo *) NULL,image,
9574 argument_list[0].string_reference));
9575 angle=0.0;
9576 if (attribute_flag[1] != 0)
9577 angle=argument_list[1].real_reference;
9578 if (attribute_flag[2] != 0)
9579 (void) CloneString(&draw_info->font,
9580 argument_list[2].string_reference);
9581 if (attribute_flag[3] != 0)
9582 (void) QueryColorDatabase(argument_list[3].string_reference,
9583 &draw_info->stroke,exception);
9584 if (attribute_flag[4] != 0)
9585 (void) QueryColorDatabase(argument_list[4].string_reference,
9586 &draw_info->fill,exception);
9587 if (attribute_flag[5] != 0)
9588 draw_info->stroke_width=argument_list[5].real_reference;
9589 if (attribute_flag[6] != 0)
9590 draw_info->pointsize=argument_list[6].real_reference;
9591 if (attribute_flag[7] != 0)
9592 draw_info->gravity=(GravityType) argument_list[7].long_reference;
9593 if (attribute_flag[8] != 0)
9594 (void) QueryColorDatabase(argument_list[8].string_reference,
9595 &image->background_color,exception);
9596 image=PolaroidImage(image,draw_info,angle,exception);
9597 draw_info=DestroyDrawInfo(draw_info);
9598 break;
9599 }
9600 case 111: /* FloodfillPaint */
9601 {
9602 DrawInfo
9603 *draw_info;
9604
9605 MagickBooleanType
9606 invert;
9607
9608 MagickPixelPacket
9609 target;
9610
9611 draw_info=CloneDrawInfo(info ? info->image_info :
9612 (ImageInfo *) NULL,(DrawInfo *) NULL);
9613 if (attribute_flag[0] != 0)
9614 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9615 &geometry,exception);
9616 if (attribute_flag[1] != 0)
9617 geometry.x=argument_list[1].long_reference;
9618 if (attribute_flag[2] != 0)
9619 geometry.y=argument_list[2].long_reference;
9620 if (attribute_flag[3] != 0)
9621 (void) QueryColorDatabase(argument_list[3].string_reference,
9622 &draw_info->fill,exception);
9623 (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target,
9624 exception);
9625 if (attribute_flag[4] != 0)
9626 QueryMagickColor(argument_list[4].string_reference,&target,
9627 exception);
9628 if (attribute_flag[5] != 0)
9629 image->fuzz=StringToDouble(argument_list[5].string_reference,
9630 QuantumRange);
9631 if (attribute_flag[6] != 0)
9632 channel=(ChannelType) argument_list[6].long_reference;
9633 invert=MagickFalse;
9634 if (attribute_flag[7] != 0)
9635 invert=(MagickBooleanType) argument_list[7].long_reference;
9636 (void) FloodfillPaintImage(image,channel,draw_info,&target,geometry.x,
9637 geometry.y,invert);
9638 draw_info=DestroyDrawInfo(draw_info);
9639 break;
9640 }
9641 case 112: /* Distort */
9642 {
9643 AV
9644 *av;
9645
9646 double
9647 *coordinates;
9648
9649 DistortImageMethod
9650 method;
9651
9652 unsigned long
9653 number_coordinates;
9654
9655 VirtualPixelMethod
9656 virtual_pixel;
9657
9658 if (attribute_flag[0] == 0)
9659 break;
9660 method=UndefinedDistortion;
9661 if (attribute_flag[1] != 0)
9662 method=(DistortImageMethod) argument_list[1].long_reference;
9663 av=(AV *) argument_list[0].array_reference;
9664 number_coordinates=(unsigned long) av_len(av)+1;
9665 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
9666 sizeof(*coordinates));
9667 if (coordinates == (double *) NULL)
9668 {
9669 ThrowPerlException(exception,ResourceLimitFatalError,
9670 "MemoryAllocationFailed",PackageName);
9671 goto PerlException;
9672 }
9673 for (j=0; j < (long) number_coordinates; j++)
9674 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
9675 virtual_pixel=UndefinedVirtualPixelMethod;
9676 if (attribute_flag[2] != 0)
9677 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9678 argument_list[2].long_reference);
9679 image=DistortImage(image,method,number_coordinates,coordinates,
9680 argument_list[3].long_reference != 0 ? MagickTrue : MagickFalse,
9681 exception);
9682 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9683 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9684 coordinates=(double *) RelinquishMagickMemory(coordinates);
9685 break;
9686 }
9687 case 113: /* Clut */
9688 {
9689 if (attribute_flag[0] == 0)
9690 {
9691 ThrowPerlException(exception,OptionError,"ClutImageRequired",
9692 PackageName);
9693 goto PerlException;
9694 }
9695 if (attribute_flag[1] != 0)
9696 channel=(ChannelType) argument_list[1].long_reference;
9697 (void) ClutImageChannel(image,channel,
9698 argument_list[0].image_reference);
9699 break;
9700 }
9701 case 114: /* LiquidRescale */
9702 {
9703 if (attribute_flag[0] != 0)
9704 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9705 &geometry,exception);
9706 if (attribute_flag[1] != 0)
9707 geometry.width=argument_list[1].long_reference;
9708 if (attribute_flag[2] != 0)
9709 geometry.height=argument_list[2].long_reference;
9710 if (attribute_flag[3] == 0)
9711 argument_list[3].real_reference=1.0;
9712 if (attribute_flag[4] == 0)
9713 argument_list[4].real_reference=0.0;
9714 image=LiquidRescaleImage(image,geometry.width,geometry.height,
9715 argument_list[3].real_reference,argument_list[4].real_reference,
9716 exception);
9717 break;
9718 }
9719 case 115: /* EncipherImage */
9720 {
9721 (void) EncipherImage(image,argument_list[0].string_reference,
9722 exception);
9723 break;
9724 }
9725 case 116: /* DecipherImage */
9726 {
9727 (void) DecipherImage(image,argument_list[0].string_reference,
9728 exception);
9729 break;
9730 }
9731 case 117: /* Deskew */
9732 {
9733 geometry_info.rho=QuantumRange/2.0;
9734 if (attribute_flag[0] != 0)
9735 flags=ParseGeometry(argument_list[0].string_reference,
9736 &geometry_info);
9737 if (attribute_flag[1] != 0)
9738 geometry_info.rho=StringToDouble(argument_list[1].string_reference,
9739 QuantumRange);
9740 image=DeskewImage(image,geometry_info.rho,exception);
9741 break;
9742 }
9743 case 118: /* Remap */
9744 {
9745 QuantizeInfo
9746 *quantize_info;
9747
9748 if (attribute_flag[0] == 0)
9749 {
9750 ThrowPerlException(exception,OptionError,"RemapImageRequired",
9751 PackageName);
9752 goto PerlException;
9753 }
9754 quantize_info=AcquireQuantizeInfo(info->image_info);
9755 if (attribute_flag[1] == 0)
9756 quantize_info->dither_method=(DitherMethod)
9757 argument_list[1].long_reference;
9758 (void) RemapImages(quantize_info,image,
9759 argument_list[0].image_reference);
9760 quantize_info=DestroyQuantizeInfo(quantize_info);
9761 break;
9762 }
9763 case 119: /* SparseColor */
9764 {
9765 AV
9766 *av;
9767
9768 double
9769 *coordinates;
9770
9771 SparseColorMethod
9772 method;
9773
9774 unsigned long
9775 number_coordinates;
9776
9777 VirtualPixelMethod
9778 virtual_pixel;
9779
9780 if (attribute_flag[0] == 0)
9781 break;
9782 method=UndefinedColorInterpolate;
9783 if (attribute_flag[1] != 0)
9784 method=(SparseColorMethod) argument_list[1].long_reference;
9785 av=(AV *) argument_list[0].array_reference;
9786 number_coordinates=(unsigned long) av_len(av)+1;
9787 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
9788 sizeof(*coordinates));
9789 if (coordinates == (double *) NULL)
9790 {
9791 ThrowPerlException(exception,ResourceLimitFatalError,
9792 "MemoryAllocationFailed",PackageName);
9793 goto PerlException;
9794 }
9795 for (j=0; j < (long) number_coordinates; j++)
9796 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
9797 virtual_pixel=UndefinedVirtualPixelMethod;
9798 if (attribute_flag[2] != 0)
9799 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9800 argument_list[2].long_reference);
9801 if (attribute_flag[3] != 0)
9802 channel=(ChannelType) argument_list[3].long_reference;
9803 image=SparseColorImage(image,channel,method,number_coordinates,
9804 coordinates,exception);
9805 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9806 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9807 coordinates=(double *) RelinquishMagickMemory(coordinates);
9808 break;
9809 }
9810 case 120: /* Function */
9811 {
9812 AV
9813 *av;
9814
9815 double
9816 *parameters;
9817
9818 MagickFunction
9819 function;
9820
9821 unsigned long
9822 number_parameters;
9823
9824 VirtualPixelMethod
9825 virtual_pixel;
9826
9827 if (attribute_flag[0] == 0)
9828 break;
9829 function=UndefinedFunction;
9830 if (attribute_flag[1] != 0)
9831 function=(MagickFunction) argument_list[1].long_reference;
9832 av=(AV *) argument_list[0].array_reference;
9833 number_parameters=(unsigned long) av_len(av)+1;
9834 parameters=(double *) AcquireQuantumMemory(number_parameters,
9835 sizeof(*parameters));
9836 if (parameters == (double *) NULL)
9837 {
9838 ThrowPerlException(exception,ResourceLimitFatalError,
9839 "MemoryAllocationFailed",PackageName);
9840 goto PerlException;
9841 }
9842 for (j=0; j < (long) number_parameters; j++)
9843 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
9844 virtual_pixel=UndefinedVirtualPixelMethod;
9845 if (attribute_flag[2] != 0)
9846 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
9847 argument_list[2].long_reference);
9848 (void) FunctionImage(image,function,number_parameters,parameters,
9849 exception);
9850 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
9851 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel);
9852 parameters=(double *) RelinquishMagickMemory(parameters);
9853 break;
9854 }
9855 case 121: /* SelectiveBlur */
9856 {
9857 if (attribute_flag[0] != 0)
9858 {
9859 flags=ParseGeometry(argument_list[0].string_reference,
9860 &geometry_info);
9861 if ((flags & SigmaValue) == 0)
9862 geometry_info.sigma=1.0;
9863 if ((flags & PercentValue) != 0)
9864 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9865 }
9866 if (attribute_flag[1] != 0)
9867 geometry_info.rho=argument_list[1].real_reference;
9868 if (attribute_flag[2] != 0)
9869 geometry_info.sigma=argument_list[2].real_reference;
9870 if (attribute_flag[3] != 0)
9871 geometry_info.xi=argument_list[3].long_reference;;
9872 if (attribute_flag[4] != 0)
9873 channel=(ChannelType) argument_list[4].long_reference;
9874 image=SelectiveBlurImageChannel(image,channel,geometry_info.rho,
9875 geometry_info.sigma,geometry_info.xi,exception);
9876 break;
9877 }
9878 case 122: /* HaldClut */
9879 {
9880 if (attribute_flag[0] == 0)
9881 {
9882 ThrowPerlException(exception,OptionError,"ClutImageRequired",
9883 PackageName);
9884 goto PerlException;
9885 }
9886 if (attribute_flag[1] != 0)
9887 channel=(ChannelType) argument_list[1].long_reference;
9888 (void) HaldClutImageChannel(image,channel,
9889 argument_list[0].image_reference);
9890 break;
9891 }
9892 case 123: /* BlueShift */
9893 {
9894 if (attribute_flag[0] != 0)
9895 (void) ParseGeometry(argument_list[0].string_reference,
9896 &geometry_info);
9897 image=BlueShiftImage(image,geometry_info.rho,exception);
9898 break;
9899 }
9900 case 124: /* ForwardFourierTransformImage */
9901 {
9902 image=ForwardFourierTransformImage(image,
9903 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse,
9904 exception);
9905 break;
9906 }
9907 case 125: /* InverseFourierTransformImage */
9908 {
9909 image=InverseFourierTransformImage(image,
9910 argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse,
9911 exception);
9912 break;
9913 }
9914 case 126: /* ColorDecisionList */
9915 {
9916 if (attribute_flag[0] == 0)
9917 argument_list[0].string_reference=(char *) NULL;
9918 (void) ColorDecisionListImage(image,
9919 argument_list[0].string_reference);
9920 break;
9921 }
9922 case 127: /* AutoGamma */
9923 {
9924 if (attribute_flag[0] != 0)
9925 channel=(ChannelType) argument_list[0].long_reference;
9926 (void) AutoGammaImageChannel(image,channel);
9927 break;
9928 }
9929 case 128: /* AutoLevel */
9930 {
9931 if (attribute_flag[0] != 0)
9932 channel=(ChannelType) argument_list[0].long_reference;
9933 (void) AutoLevelImageChannel(image,channel);
9934 break;
9935 }
9936 }
9937 if (next != (Image *) NULL)
9938 (void) CatchImageException(next);
9939 if (region_image != (Image *) NULL)
9940 {
9941 /*
9942 Composite region.
9943 */
9944 status=CompositeImage(region_image,CopyCompositeOp,image,
9945 region_info.x,region_info.y);
9946 (void) CatchImageException(region_image);
9947 image=DestroyImage(image);
9948 image=region_image;
9949 }
9950 if (image != (Image *) NULL)
9951 {
9952 number_images++;
9953 if (next && (next != image))
9954 {
9955 image->next=next->next;
9956 DeleteImageFromRegistry(*pv,next);
9957 }
9958 sv_setiv(*pv,(IV) image);
9959 next=image;
9960 }
9961 if (*pv)
9962 pv++;
9963 }
9964
9965 PerlException:
9966 if (reference_vector)
9967 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
9968 InheritPerlException(exception,perl_exception);
9969 exception=DestroyExceptionInfo(exception);
9970 sv_setiv(perl_exception,(IV) number_images);
9971 SvPOK_on(perl_exception);
9972 ST(0)=sv_2mortal(perl_exception);
9973 XSRETURN(1);
9974 }
9975
9976#
9977###############################################################################
9978# #
9979# #
9980# #
9981# M o n t a g e #
9982# #
9983# #
9984# #
9985###############################################################################
9986#
9987#
9988void
9989Montage(ref,...)
9990 Image::Magick ref=NO_INIT
9991 ALIAS:
9992 MontageImage = 1
9993 montage = 2
9994 montageimage = 3
9995 PPCODE:
9996 {
9997 AV
9998 *av;
9999
10000 char
10001 *attribute;
10002
10003 ExceptionInfo
10004 *exception;
10005
10006 HV
10007 *hv;
10008
10009 Image
10010 *image,
10011 *next;
10012
10013 long
10014 sp;
10015
10016 MagickPixelPacket
10017 transparent_color;
10018
10019 MontageInfo
10020 *montage_info;
10021
10022 register long
10023 i;
10024
10025 struct PackageInfo
10026 *info;
10027
10028 SV
10029 *av_reference,
10030 *perl_exception,
10031 *reference,
10032 *rv,
10033 *sv;
10034
10035 exception=AcquireExceptionInfo();
10036 perl_exception=newSVpv("",0);
10037 attribute=NULL;
10038 if (sv_isobject(ST(0)) == 0)
10039 {
10040 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10041 PackageName);
10042 goto PerlException;
10043 }
10044 reference=SvRV(ST(0));
10045 hv=SvSTASH(reference);
10046 av=newAV();
10047 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10048 SvREFCNT_dec(av);
10049 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10050 if (image == (Image *) NULL)
10051 {
10052 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10053 PackageName);
10054 goto PerlException;
10055 }
10056 /*
10057 Get options.
10058 */
10059 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10060 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
10061 (void) QueryMagickColor("none",&transparent_color,exception);
10062 for (i=2; i < items; i+=2)
10063 {
10064 attribute=(char *) SvPV(ST(i-1),na);
10065 switch (*attribute)
10066 {
10067 case 'B':
10068 case 'b':
10069 {
10070 if (LocaleCompare(attribute,"background") == 0)
10071 {
10072 (void) QueryColorDatabase(SvPV(ST(i),na),
10073 &montage_info->background_color,exception);
10074 for (next=image; next; next=next->next)
10075 next->background_color=montage_info->background_color;
10076 break;
10077 }
10078 if (LocaleCompare(attribute,"border") == 0)
10079 {
10080 montage_info->border_width=SvIV(ST(i));
10081 break;
10082 }
10083 if (LocaleCompare(attribute,"bordercolor") == 0)
10084 {
10085 (void) QueryColorDatabase(SvPV(ST(i),na),
10086 &montage_info->border_color,exception);
10087 for (next=image; next; next=next->next)
10088 next->border_color=montage_info->border_color;
10089 break;
10090 }
10091 if (LocaleCompare(attribute,"borderwidth") == 0)
10092 {
10093 montage_info->border_width=SvIV(ST(i));
10094 break;
10095 }
10096 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10097 attribute);
10098 break;
10099 }
10100 case 'C':
10101 case 'c':
10102 {
10103 if (LocaleCompare(attribute,"compose") == 0)
10104 {
10105 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10106 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
10107 if (sp < 0)
10108 {
10109 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10110 SvPV(ST(i),na));
10111 break;
10112 }
10113 for (next=image; next; next=next->next)
10114 next->compose=(CompositeOperator) sp;
10115 break;
10116 }
10117 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10118 attribute);
10119 break;
10120 }
10121 case 'F':
10122 case 'f':
10123 {
10124 if (LocaleCompare(attribute,"fill") == 0)
10125 {
10126 (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->fill,
10127 exception);
10128 break;
10129 }
10130 if (LocaleCompare(attribute,"font") == 0)
10131 {
10132 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
10133 break;
10134 }
10135 if (LocaleCompare(attribute,"frame") == 0)
10136 {
10137 char
10138 *p;
10139
10140 p=SvPV(ST(i),na);
10141 if (IsGeometry(p) == MagickFalse)
10142 {
10143 ThrowPerlException(exception,OptionError,"MissingGeometry",
10144 p);
10145 break;
10146 }
10147 (void) CloneString(&montage_info->frame,p);
10148 if (*p == '\0')
10149 montage_info->frame=(char *) NULL;
10150 break;
10151 }
10152 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10153 attribute);
10154 break;
10155 }
10156 case 'G':
10157 case 'g':
10158 {
10159 if (LocaleCompare(attribute,"geometry") == 0)
10160 {
10161 char
10162 *p;
10163
10164 p=SvPV(ST(i),na);
10165 if (IsGeometry(p) == MagickFalse)
10166 {
10167 ThrowPerlException(exception,OptionError,"MissingGeometry",
10168 p);
10169 break;
10170 }
10171 (void) CloneString(&montage_info->geometry,p);
10172 if (*p == '\0')
10173 montage_info->geometry=(char *) NULL;
10174 break;
10175 }
10176 if (LocaleCompare(attribute,"gravity") == 0)
10177 {
10178 long
10179 in;
10180
10181 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10182 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
10183 if (in < 0)
10184 {
10185 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10186 SvPV(ST(i),na));
10187 return;
10188 }
10189 montage_info->gravity=(GravityType) in;
10190 for (next=image; next; next=next->next)
10191 next->gravity=(GravityType) in;
10192 break;
10193 }
10194 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10195 attribute);
10196 break;
10197 }
10198 case 'L':
10199 case 'l':
10200 {
10201 if (LocaleCompare(attribute,"label") == 0)
10202 {
10203 for (next=image; next; next=next->next)
10204 (void) SetImageProperty(next,"label",InterpretImageProperties(
10205 info ? info->image_info : (ImageInfo *) NULL,next,
10206 SvPV(ST(i),na)));
10207 break;
10208 }
10209 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10210 attribute);
10211 break;
10212 }
10213 case 'M':
10214 case 'm':
10215 {
10216 if (LocaleCompare(attribute,"mattecolor") == 0)
10217 {
10218 (void) QueryColorDatabase(SvPV(ST(i),na),
10219 &montage_info->matte_color,exception);
10220 for (next=image; next; next=next->next)
10221 next->matte_color=montage_info->matte_color;
10222 break;
10223 }
10224 if (LocaleCompare(attribute,"mode") == 0)
10225 {
10226 long
10227 in;
10228
10229 in=!SvPOK(ST(i)) ? SvIV(ST(i)) :
10230 ParseMagickOption(MagickModeOptions,MagickFalse,SvPV(ST(i),na));
10231 switch (in)
10232 {
10233 default:
10234 {
10235 ThrowPerlException(exception,OptionError,
10236 "UnrecognizedModeType",SvPV(ST(i),na));
10237 break;
10238 }
10239 case FrameMode:
10240 {
10241 (void) CloneString(&montage_info->frame,"15x15+3+3");
10242 montage_info->shadow=MagickTrue;
10243 break;
10244 }
10245 case UnframeMode:
10246 {
10247 montage_info->frame=(char *) NULL;
10248 montage_info->shadow=MagickFalse;
10249 montage_info->border_width=0;
10250 break;
10251 }
10252 case ConcatenateMode:
10253 {
10254 montage_info->frame=(char *) NULL;
10255 montage_info->shadow=MagickFalse;
10256 (void) CloneString(&montage_info->geometry,"+0+0");
10257 montage_info->border_width=0;
10258 }
10259 }
10260 break;
10261 }
10262 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10263 attribute);
10264 break;
10265 }
10266 case 'P':
10267 case 'p':
10268 {
10269 if (LocaleCompare(attribute,"pointsize") == 0)
10270 {
10271 montage_info->pointsize=SvIV(ST(i));
10272 break;
10273 }
10274 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10275 attribute);
10276 break;
10277 }
10278 case 'S':
10279 case 's':
10280 {
10281 if (LocaleCompare(attribute,"shadow") == 0)
10282 {
10283 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
10284 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
10285 if (sp < 0)
10286 {
10287 ThrowPerlException(exception,OptionError,"UnrecognizedType",
10288 SvPV(ST(i),na));
10289 break;
10290 }
10291 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
10292 break;
10293 }
10294 if (LocaleCompare(attribute,"stroke") == 0)
10295 {
10296 (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->stroke,
10297 exception);
10298 break;
10299 }
10300 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10301 attribute);
10302 break;
10303 }
10304 case 'T':
10305 case 't':
10306 {
10307 if (LocaleCompare(attribute,"texture") == 0)
10308 {
10309 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
10310 break;
10311 }
10312 if (LocaleCompare(attribute,"tile") == 0)
10313 {
10314 char *p=SvPV(ST(i),na);
10315 if (IsGeometry(p) == MagickFalse)
10316 {
10317 ThrowPerlException(exception,OptionError,"MissingGeometry",
10318 p);
10319 break;
10320 }
10321 (void) CloneString(&montage_info->tile,p);
10322 if (*p == '\0')
10323 montage_info->tile=(char *) NULL;
10324 break;
10325 }
10326 if (LocaleCompare(attribute,"title") == 0)
10327 {
10328 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
10329 break;
10330 }
10331 if (LocaleCompare(attribute,"transparent") == 0)
10332 {
10333 MagickPixelPacket
10334 transparent_color;
10335
10336 QueryMagickColor(SvPV(ST(i),na),&transparent_color,exception);
10337 for (next=image; next; next=next->next)
10338 (void) TransparentPaintImage(next,&transparent_color,
10339 TransparentOpacity,MagickFalse);
10340 break;
10341 }
10342 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10343 attribute);
10344 break;
10345 }
10346 default:
10347 {
10348 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10349 attribute);
10350 break;
10351 }
10352 }
10353 }
10354 image=MontageImageList(info->image_info,montage_info,image,exception);
10355 montage_info=DestroyMontageInfo(montage_info);
10356 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10357 goto PerlException;
10358 if (transparent_color.opacity != TransparentOpacity)
10359 for (next=image; next; next=next->next)
10360 (void) TransparentPaintImage(next,&transparent_color,
10361 TransparentOpacity,MagickFalse);
10362 for ( ; image; image=image->next)
10363 {
10364 AddImageToRegistry(image);
10365 rv=newRV(sv);
10366 av_push(av,sv_bless(rv,hv));
10367 SvREFCNT_dec(sv);
10368 }
10369 exception=DestroyExceptionInfo(exception);
10370 ST(0)=av_reference;
10371 SvREFCNT_dec(perl_exception);
10372 XSRETURN(1);
10373
10374 PerlException:
10375 InheritPerlException(exception,perl_exception);
10376 exception=DestroyExceptionInfo(exception);
10377 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10378 SvPOK_on(perl_exception);
10379 ST(0)=sv_2mortal(perl_exception);
10380 XSRETURN(1);
10381 }
10382
10383#
10384###############################################################################
10385# #
10386# #
10387# #
10388# M o r p h #
10389# #
10390# #
10391# #
10392###############################################################################
10393#
10394#
10395void
10396Morph(ref,...)
10397 Image::Magick ref=NO_INIT
10398 ALIAS:
10399 MorphImage = 1
10400 morph = 2
10401 morphimage = 3
10402 PPCODE:
10403 {
10404 AV
10405 *av;
10406
10407 char
10408 *attribute;
10409
10410 ExceptionInfo
10411 *exception;
10412
10413 HV
10414 *hv;
10415
10416 Image
10417 *image;
10418
10419 long
10420 number_frames;
10421
10422 register long
10423 i;
10424
10425 struct PackageInfo
10426 *info;
10427
10428 SV
10429 *av_reference,
10430 *perl_exception,
10431 *reference,
10432 *rv,
10433 *sv;
10434
10435 exception=AcquireExceptionInfo();
10436 perl_exception=newSVpv("",0);
10437 av=NULL;
10438 attribute=NULL;
10439 if (sv_isobject(ST(0)) == 0)
10440 {
10441 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10442 PackageName);
10443 goto PerlException;
10444 }
10445 reference=SvRV(ST(0));
10446 hv=SvSTASH(reference);
10447 av=newAV();
10448 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10449 SvREFCNT_dec(av);
10450 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10451 if (image == (Image *) NULL)
10452 {
10453 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10454 PackageName);
10455 goto PerlException;
10456 }
10457 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10458 /*
10459 Get attribute.
10460 */
10461 number_frames=30;
10462 for (i=2; i < items; i+=2)
10463 {
10464 attribute=(char *) SvPV(ST(i-1),na);
10465 switch (*attribute)
10466 {
10467 case 'F':
10468 case 'f':
10469 {
10470 if (LocaleCompare(attribute,"frames") == 0)
10471 {
10472 number_frames=SvIV(ST(i));
10473 break;
10474 }
10475 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10476 attribute);
10477 break;
10478 }
10479 default:
10480 {
10481 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
10482 attribute);
10483 break;
10484 }
10485 }
10486 }
10487 image=MorphImages(image,number_frames,exception);
10488 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10489 goto PerlException;
10490 for ( ; image; image=image->next)
10491 {
10492 AddImageToRegistry(image);
10493 rv=newRV(sv);
10494 av_push(av,sv_bless(rv,hv));
10495 SvREFCNT_dec(sv);
10496 }
10497 exception=DestroyExceptionInfo(exception);
10498 ST(0)=av_reference;
10499 SvREFCNT_dec(perl_exception); /* can't return warning messages */
10500 XSRETURN(1);
10501
10502 PerlException:
10503 InheritPerlException(exception,perl_exception);
10504 exception=DestroyExceptionInfo(exception);
10505 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10506 SvPOK_on(perl_exception);
10507 ST(0)=sv_2mortal(perl_exception);
10508 XSRETURN(1);
10509 }
10510
10511#
10512###############################################################################
10513# #
10514# #
10515# #
10516# M o s a i c #
10517# #
10518# #
10519# #
10520###############################################################################
10521#
10522#
10523void
10524Mosaic(ref)
10525 Image::Magick ref=NO_INIT
10526 ALIAS:
10527 MosaicImage = 1
10528 mosaic = 2
10529 mosaicimage = 3
10530 PPCODE:
10531 {
10532 AV
10533 *av;
10534
10535 ExceptionInfo
10536 *exception;
10537
10538 HV
10539 *hv;
10540
10541 Image
10542 *image;
10543
10544 struct PackageInfo
10545 *info;
10546
10547 SV
10548 *perl_exception,
10549 *reference,
10550 *rv,
10551 *sv;
10552
10553 exception=AcquireExceptionInfo();
10554 perl_exception=newSVpv("",0);
10555 if (sv_isobject(ST(0)) == 0)
10556 {
10557 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10558 PackageName);
10559 goto PerlException;
10560 }
10561 reference=SvRV(ST(0));
10562 hv=SvSTASH(reference);
10563 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10564 if (image == (Image *) NULL)
10565 {
10566 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10567 PackageName);
10568 goto PerlException;
10569 }
10570 image=MergeImageLayers(image,MosaicLayer,exception);
10571 /*
10572 Create blessed Perl array for the returned image.
10573 */
10574 av=newAV();
10575 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10576 SvREFCNT_dec(av);
10577 AddImageToRegistry(image);
10578 rv=newRV(sv);
10579 av_push(av,sv_bless(rv,hv));
10580 SvREFCNT_dec(sv);
10581 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10582 (void) CopyMagickString(image->filename,info->image_info->filename,
10583 MaxTextExtent);
10584 SetImageInfo(info->image_info,MagickFalse,&image->exception);
10585 exception=DestroyExceptionInfo(exception);
10586 SvREFCNT_dec(perl_exception);
10587 XSRETURN(1);
10588
10589 PerlException:
10590 InheritPerlException(exception,perl_exception);
10591 exception=DestroyExceptionInfo(exception);
10592 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10593 SvPOK_on(perl_exception); /* return messages in string context */
10594 ST(0)=sv_2mortal(perl_exception);
10595 XSRETURN(1);
10596 }
10597
10598#
10599###############################################################################
10600# #
10601# #
10602# #
10603# P i n g #
10604# #
10605# #
10606# #
10607###############################################################################
10608#
10609#
10610void
10611Ping(ref,...)
10612 Image::Magick ref=NO_INIT
10613 ALIAS:
10614 PingImage = 1
10615 ping = 2
10616 pingimage = 3
10617 PPCODE:
10618 {
10619 AV
10620 *av;
10621
10622 char
10623 **keep,
10624 **list;
10625
10626 ExceptionInfo
10627 *exception;
10628
10629 HV
10630 *hv;
10631
10632 Image
10633 *image,
10634 *next;
10635
10636 int
10637 n;
10638
10639 long
10640 ac;
10641
10642 MagickBooleanType
10643 status;
10644
10645 register char
10646 **p;
10647
10648 register long
10649 i;
10650
10651 STRLEN
10652 *length;
10653
10654 struct PackageInfo
10655 *info,
10656 *package_info;
10657
10658 SV
10659 *perl_exception,
10660 *reference;
10661
10662 unsigned long
10663 count;
10664
10665 exception=AcquireExceptionInfo();
10666 perl_exception=newSVpv("",0);
10667 package_info=(struct PackageInfo *) NULL;
10668 ac=(items < 2) ? 1 : items-1;
10669 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
10670 keep=list;
10671 length=(STRLEN *) NULL;
10672 if (list == (char **) NULL)
10673 {
10674 ThrowPerlException(exception,ResourceLimitError,
10675 "MemoryAllocationFailed",PackageName);
10676 goto PerlException;
10677 }
10678 keep=list;
10679 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
10680 if (length == (STRLEN *) NULL)
10681 {
10682 ThrowPerlException(exception,ResourceLimitError,
10683 "MemoryAllocationFailed",PackageName);
10684 goto PerlException;
10685 }
10686 if (sv_isobject(ST(0)) == 0)
10687 {
10688 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10689 PackageName);
10690 goto PerlException;
10691 }
10692 reference=SvRV(ST(0));
10693 hv=SvSTASH(reference);
10694 if (SvTYPE(reference) != SVt_PVAV)
10695 {
10696 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10697 PackageName);
10698 goto PerlException;
10699 }
10700 av=(AV *) reference;
10701 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
10702 exception);
10703 package_info=ClonePackageInfo(info,exception);
10704 n=1;
10705 if (items <= 1)
10706 *list=(char *) (*package_info->image_info->filename ?
10707 package_info->image_info->filename : "XC:black");
10708 else
10709 for (n=0, i=0; i < ac; i++)
10710 {
10711 list[n]=(char *) SvPV(ST(i+1),length[n]);
10712 if ((items >= 3) && strEQcase(list[n],"blob"))
10713 {
10714 void
10715 *blob;
10716
10717 i++;
10718 blob=(void *) (SvPV(ST(i+1),length[n]));
10719 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
10720 }
10721 if ((items >= 3) && strEQcase(list[n],"filename"))
10722 continue;
10723 if ((items >= 3) && strEQcase(list[n],"file"))
10724 {
10725 FILE
10726 *file;
10727
10728 PerlIO
10729 *io_info;
10730
10731 i++;
10732 io_info=IoIFP(sv_2io(ST(i+1)));
10733 if (io_info == (PerlIO *) NULL)
10734 {
10735 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
10736 PackageName);
10737 continue;
10738 }
10739 file=PerlIO_findFILE(io_info);
10740 if (file == (FILE *) NULL)
10741 {
10742 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
10743 PackageName);
10744 continue;
10745 }
10746 SetImageInfoFile(package_info->image_info,file);
10747 }
10748 if ((items >= 3) && strEQcase(list[n],"magick"))
10749 continue;
10750 n++;
10751 }
10752 list[n]=(char *) NULL;
10753 keep=list;
10754 status=ExpandFilenames(&n,&list);
10755 if (status == MagickFalse)
10756 {
10757 ThrowPerlException(exception,ResourceLimitError,
10758 "MemoryAllocationFailed",PackageName);
10759 goto PerlException;
10760 }
10761 count=0;
10762 for (i=0; i < n; i++)
10763 {
10764 (void) CopyMagickString(package_info->image_info->filename,list[i],
10765 MaxTextExtent);
10766 image=PingImage(package_info->image_info,exception);
10767 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
10768 break;
10769 if ((package_info->image_info->file != (FILE *) NULL) ||
10770 (package_info->image_info->blob != (void *) NULL))
10771 DisassociateImageStream(image);
10772 count+=GetImageListLength(image);
10773 EXTEND(sp,4*count);
10774 for (next=image; next; next=next->next)
10775 {
10776 PUSHs(sv_2mortal(newSViv(next->columns)));
10777 PUSHs(sv_2mortal(newSViv(next->rows)));
10778 PUSHs(sv_2mortal(newSViv((unsigned long) GetBlobSize(next))));
10779 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
10780 }
10781 image=DestroyImageList(image);
10782 }
10783 /*
10784 Free resources.
10785 */
10786 for (i=0; i < n; i++)
10787 if (list[i] != (char *) NULL)
10788 for (p=keep; list[i] != *p++; )
10789 if (*p == NULL)
10790 {
10791 list[i]=(char *) RelinquishMagickMemory(list[i]);
10792 break;
10793 }
10794
10795 PerlException:
10796 if (package_info != (struct PackageInfo *) NULL)
10797 DestroyPackageInfo(package_info);
10798 if (list && (list != keep))
10799 list=(char **) RelinquishMagickMemory(list);
10800 if (keep)
10801 keep=(char **) RelinquishMagickMemory(keep);
10802 if (length)
10803 length=(STRLEN *) RelinquishMagickMemory(length);
10804 InheritPerlException(exception,perl_exception);
10805 exception=DestroyExceptionInfo(exception);
10806 SvREFCNT_dec(perl_exception); /* throw away all errors */
10807 }
10808
10809#
10810###############################################################################
10811# #
10812# #
10813# #
10814# P r e v i e w #
10815# #
10816# #
10817# #
10818###############################################################################
10819#
10820#
10821void
10822Preview(ref,...)
10823 Image::Magick ref=NO_INIT
10824 ALIAS:
10825 PreviewImage = 1
10826 preview = 2
10827 previewimage = 3
10828 PPCODE:
10829 {
10830 AV
10831 *av;
10832
10833 ExceptionInfo
10834 *exception;
10835
10836 HV
10837 *hv;
10838
10839 Image
10840 *image,
10841 *preview_image;
10842
10843 PreviewType
10844 preview_type;
10845
10846 struct PackageInfo
10847 *info;
10848
10849 SV
10850 *av_reference,
10851 *perl_exception,
10852 *reference,
10853 *rv,
10854 *sv;
10855
10856 exception=AcquireExceptionInfo();
10857 perl_exception=newSVpv("",0);
10858 av=NULL;
10859 if (sv_isobject(ST(0)) == 0)
10860 {
10861 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
10862 PackageName);
10863 goto PerlException;
10864 }
10865 reference=SvRV(ST(0));
10866 hv=SvSTASH(reference);
10867 av=newAV();
10868 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
10869 SvREFCNT_dec(av);
10870 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
10871 if (image == (Image *) NULL)
10872 {
10873 ThrowPerlException(exception,OptionError,"NoImagesDefined",
10874 PackageName);
10875 goto PerlException;
10876 }
10877 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
10878 preview_type=GammaPreview;
10879 if (items > 1)
10880 preview_type=(PreviewType)
10881 ParseMagickOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
10882 for ( ; image; image=image->next)
10883 {
10884 preview_image=PreviewImage(image,preview_type,exception);
10885 if (preview_image == (Image *) NULL)
10886 goto PerlException;
10887 AddImageToRegistry(preview_image);
10888 rv=newRV(sv);
10889 av_push(av,sv_bless(rv,hv));
10890 SvREFCNT_dec(sv);
10891 }
10892 exception=DestroyExceptionInfo(exception);
10893 ST(0)=av_reference;
10894 SvREFCNT_dec(perl_exception); /* can't return warning messages */
10895 XSRETURN(1);
10896
10897 PerlException:
10898 InheritPerlException(exception,perl_exception);
10899 exception=DestroyExceptionInfo(exception);
10900 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
10901 SvPOK_on(perl_exception);
10902 ST(0)=sv_2mortal(perl_exception);
10903 XSRETURN(1);
10904 }
10905
10906#
10907###############################################################################
10908# #
10909# #
10910# #
10911# Q u e r y C o l o r #
10912# #
10913# #
10914# #
10915###############################################################################
10916#
10917#
10918void
10919QueryColor(ref,...)
10920 Image::Magick ref=NO_INIT
10921 ALIAS:
10922 querycolor = 1
10923 PPCODE:
10924 {
10925 char
10926 *name;
10927
10928 ExceptionInfo
10929 *exception;
10930
10931 MagickPixelPacket
10932 color;
10933
10934 register long
10935 i;
10936
10937 SV
10938 *perl_exception;
10939
10940 exception=AcquireExceptionInfo();
10941 perl_exception=newSVpv("",0);
10942 if (items == 1)
10943 {
10944 const ColorInfo
10945 **colorlist;
10946
10947 unsigned long
10948 colors;
10949
10950 colorlist=GetColorInfoList("*",&colors,exception);
10951 EXTEND(sp,colors);
10952 for (i=0; i < (long) colors; i++)
10953 {
10954 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
10955 }
10956 colorlist=(const ColorInfo **)
10957 RelinquishMagickMemory((ColorInfo **) colorlist);
10958 goto PerlException;
10959 }
10960 EXTEND(sp,5*items);
10961 for (i=1; i < items; i++)
10962 {
10963 name=(char *) SvPV(ST(i),na);
10964 if (QueryMagickColor(name,&color,exception) == MagickFalse)
10965 {
10966 PUSHs(&sv_undef);
10967 continue;
10968 }
10969 PUSHs(sv_2mortal(newSViv((unsigned long) (color.red+0.5))));
10970 PUSHs(sv_2mortal(newSViv((unsigned long) (color.green+0.5))));
10971 PUSHs(sv_2mortal(newSViv((unsigned long) (color.blue+0.5))));
10972 if (color.matte != MagickFalse)
10973 PUSHs(sv_2mortal(newSViv((unsigned long) (color.opacity+0.5))));
10974 if (color.colorspace == CMYKColorspace)
10975 PUSHs(sv_2mortal(newSViv((unsigned long) (color.index+0.5))));
10976 }
10977
10978 PerlException:
10979 InheritPerlException(exception,perl_exception);
10980 exception=DestroyExceptionInfo(exception);
10981 SvREFCNT_dec(perl_exception);
10982 }
10983
10984#
10985###############################################################################
10986# #
10987# #
10988# #
10989# Q u e r y C o l o r N a m e #
10990# #
10991# #
10992# #
10993###############################################################################
10994#
10995#
10996void
10997QueryColorname(ref,...)
10998 Image::Magick ref=NO_INIT
10999 ALIAS:
11000 querycolorname = 1
11001 PPCODE:
11002 {
11003 AV
11004 *av;
11005
11006 char
11007 message[MaxTextExtent];
11008
11009 ExceptionInfo
11010 *exception;
11011
11012 Image
11013 *image;
11014
11015 PixelPacket
11016 target_color;
11017
11018 register long
11019 i;
11020
11021 struct PackageInfo
11022 *info;
11023
11024 SV
11025 *perl_exception,
11026 *reference; /* reference is the SV* of ref=SvIV(reference) */
11027
11028 exception=AcquireExceptionInfo();
11029 perl_exception=newSVpv("",0);
11030 reference=SvRV(ST(0));
11031 av=(AV *) reference;
11032 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11033 exception);
11034 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11035 if (image == (Image *) NULL)
11036 {
11037 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11038 PackageName);
11039 goto PerlException;
11040 }
11041 EXTEND(sp,items);
11042 for (i=1; i < items; i++)
11043 {
11044 (void) QueryColorDatabase(SvPV(ST(i),na),&target_color,exception);
11045 (void) QueryColorname(image,&target_color,SVGCompliance,message,
11046 exception);
11047 PUSHs(sv_2mortal(newSVpv(message,0)));
11048 }
11049
11050 PerlException:
11051 InheritPerlException(exception,perl_exception);
11052 exception=DestroyExceptionInfo(exception);
11053 SvREFCNT_dec(perl_exception);
11054 }
11055
11056#
11057###############################################################################
11058# #
11059# #
11060# #
11061# Q u e r y F o n t #
11062# #
11063# #
11064# #
11065###############################################################################
11066#
11067#
11068void
11069QueryFont(ref,...)
11070 Image::Magick ref=NO_INIT
11071 ALIAS:
11072 queryfont = 1
11073 PPCODE:
11074 {
11075 char
11076 *name,
11077 message[MaxTextExtent];
11078
11079 ExceptionInfo
11080 *exception;
11081
11082 register long
11083 i;
11084
11085 SV
11086 *perl_exception;
11087
11088 volatile const TypeInfo
11089 *type_info;
11090
11091 exception=AcquireExceptionInfo();
11092 perl_exception=newSVpv("",0);
11093 if (items == 1)
11094 {
11095 const TypeInfo
11096 **typelist;
11097
11098 unsigned long
11099 types;
11100
11101 typelist=GetTypeInfoList("*",&types,exception);
11102 EXTEND(sp,types);
11103 for (i=0; i < (long) types; i++)
11104 {
11105 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
11106 }
11107 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
11108 typelist);
11109 goto PerlException;
11110 }
11111 EXTEND(sp,10*items);
11112 for (i=1; i < items; i++)
11113 {
11114 name=(char *) SvPV(ST(i),na);
11115 type_info=GetTypeInfo(name,exception);
11116 if (type_info == (TypeInfo *) NULL)
11117 {
11118 PUSHs(&sv_undef);
11119 continue;
11120 }
11121 if (type_info->name == (char *) NULL)
11122 PUSHs(&sv_undef);
11123 else
11124 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
11125 if (type_info->description == (char *) NULL)
11126 PUSHs(&sv_undef);
11127 else
11128 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
11129 if (type_info->family == (char *) NULL)
11130 PUSHs(&sv_undef);
11131 else
11132 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
11133 if (type_info->style == UndefinedStyle)
11134 PUSHs(&sv_undef);
11135 else
11136 PUSHs(sv_2mortal(newSVpv(MagickOptionToMnemonic(MagickStyleOptions,
11137 type_info->style),0)));
11138 if (type_info->stretch == UndefinedStretch)
11139 PUSHs(&sv_undef);
11140 else
11141 PUSHs(sv_2mortal(newSVpv(MagickOptionToMnemonic(MagickStretchOptions,
11142 type_info->stretch),0)));
11143 (void) FormatMagickString(message,MaxTextExtent,"%lu",type_info->weight);
11144 PUSHs(sv_2mortal(newSVpv(message,0)));
11145 if (type_info->encoding == (char *) NULL)
11146 PUSHs(&sv_undef);
11147 else
11148 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
11149 if (type_info->foundry == (char *) NULL)
11150 PUSHs(&sv_undef);
11151 else
11152 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
11153 if (type_info->format == (char *) NULL)
11154 PUSHs(&sv_undef);
11155 else
11156 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
11157 if (type_info->metrics == (char *) NULL)
11158 PUSHs(&sv_undef);
11159 else
11160 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
11161 if (type_info->glyphs == (char *) NULL)
11162 PUSHs(&sv_undef);
11163 else
11164 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
11165 }
11166
11167 PerlException:
11168 InheritPerlException(exception,perl_exception);
11169 exception=DestroyExceptionInfo(exception);
11170 SvREFCNT_dec(perl_exception);
11171 }
11172
11173#
11174###############################################################################
11175# #
11176# #
11177# #
11178# Q u e r y F o n t M e t r i c s #
11179# #
11180# #
11181# #
11182###############################################################################
11183#
11184#
11185void
11186QueryFontMetrics(ref,...)
11187 Image::Magick ref=NO_INIT
11188 ALIAS:
11189 queryfontmetrics = 1
11190 PPCODE:
11191 {
11192 AffineMatrix
11193 affine,
11194 current;
11195
11196 AV
11197 *av;
11198
11199 char
11200 *attribute;
11201
11202 double
11203 x,
11204 y;
11205
11206 DrawInfo
11207 *draw_info;
11208
11209 ExceptionInfo
11210 *exception;
11211
11212 GeometryInfo
11213 geometry_info;
11214
11215 Image
11216 *image;
11217
11218 long
11219 type;
11220
11221 MagickBooleanType
11222 status;
11223
11224 MagickStatusType
11225 flags;
11226
11227 register long
11228 i;
11229
11230 struct PackageInfo
11231 *info,
11232 *package_info;
11233
11234 SV
11235 *perl_exception,
11236 *reference; /* reference is the SV* of ref=SvIV(reference) */
11237
11238 TypeMetric
11239 metrics;
11240
11241 exception=AcquireExceptionInfo();
11242 package_info=(struct PackageInfo *) NULL;
11243 perl_exception=newSVpv("",0);
11244 reference=SvRV(ST(0));
11245 av=(AV *) reference;
11246 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11247 exception);
11248 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11249 if (image == (Image *) NULL)
11250 {
11251 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11252 PackageName);
11253 goto PerlException;
11254 }
11255 package_info=ClonePackageInfo(info,exception);
11256 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
11257 CloneString(&draw_info->text,"");
11258 current=draw_info->affine;
11259 GetAffineMatrix(&affine);
11260 x=0.0;
11261 y=0.0;
11262 EXTEND(sp,7*items);
11263 for (i=2; i < items; i+=2)
11264 {
11265 attribute=(char *) SvPV(ST(i-1),na);
11266 switch (*attribute)
11267 {
11268 case 'A':
11269 case 'a':
11270 {
11271 if (LocaleCompare(attribute,"antialias") == 0)
11272 {
11273 type=ParseMagickOption(MagickBooleanOptions,MagickFalse,
11274 SvPV(ST(i),na));
11275 if (type < 0)
11276 {
11277 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11278 SvPV(ST(i),na));
11279 break;
11280 }
11281 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
11282 break;
11283 }
11284 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11285 attribute);
11286 break;
11287 }
11288 case 'd':
11289 case 'D':
11290 {
11291 if (LocaleCompare(attribute,"density") == 0)
11292 {
11293 CloneString(&draw_info->density,SvPV(ST(i),na));
11294 break;
11295 }
11296 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11297 attribute);
11298 break;
11299 }
11300 case 'e':
11301 case 'E':
11302 {
11303 if (LocaleCompare(attribute,"encoding") == 0)
11304 {
11305 CloneString(&draw_info->encoding,SvPV(ST(i),na));
11306 break;
11307 }
11308 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11309 attribute);
11310 break;
11311 }
11312 case 'f':
11313 case 'F':
11314 {
11315 if (LocaleCompare(attribute,"family") == 0)
11316 {
11317 CloneString(&draw_info->family,SvPV(ST(i),na));
11318 break;
11319 }
11320 if (LocaleCompare(attribute,"fill") == 0)
11321 {
11322 if (info)
11323 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->fill,
11324 &image->exception);
11325 break;
11326 }
11327 if (LocaleCompare(attribute,"font") == 0)
11328 {
11329 CloneString(&draw_info->font,SvPV(ST(i),na));
11330 break;
11331 }
11332 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11333 attribute);
11334 break;
11335 }
11336 case 'g':
11337 case 'G':
11338 {
11339 if (LocaleCompare(attribute,"geometry") == 0)
11340 {
11341 CloneString(&draw_info->geometry,SvPV(ST(i),na));
11342 break;
11343 }
11344 if (LocaleCompare(attribute,"gravity") == 0)
11345 {
11346 draw_info->gravity=(GravityType) ParseMagickOption(
11347 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11348 break;
11349 }
11350 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11351 attribute);
11352 break;
11353 }
11354 case 'i':
11355 case 'I':
11356 {
11357 if (LocaleCompare(attribute,"interword-spacing") == 0)
11358 {
11359 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11360 draw_info->interword_spacing=geometry_info.rho;
11361 break;
11362 }
11363 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11364 attribute);
11365 break;
11366 }
11367 case 'k':
11368 case 'K':
11369 {
11370 if (LocaleCompare(attribute,"kerning") == 0)
11371 {
11372 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11373 draw_info->kerning=geometry_info.rho;
11374 break;
11375 }
11376 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11377 attribute);
11378 break;
11379 }
11380 case 'p':
11381 case 'P':
11382 {
11383 if (LocaleCompare(attribute,"pointsize") == 0)
11384 {
11385 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11386 draw_info->pointsize=geometry_info.rho;
11387 break;
11388 }
11389 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11390 attribute);
11391 break;
11392 }
11393 case 'r':
11394 case 'R':
11395 {
11396 if (LocaleCompare(attribute,"rotate") == 0)
11397 {
11398 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11399 affine.rx=geometry_info.rho;
11400 affine.ry=geometry_info.sigma;
11401 if ((flags & SigmaValue) == 0)
11402 affine.ry=affine.rx;
11403 break;
11404 }
11405 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11406 attribute);
11407 break;
11408 }
11409 case 's':
11410 case 'S':
11411 {
11412 if (LocaleCompare(attribute,"scale") == 0)
11413 {
11414 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11415 affine.sx=geometry_info.rho;
11416 affine.sy=geometry_info.sigma;
11417 if ((flags & SigmaValue) == 0)
11418 affine.sy=affine.sx;
11419 break;
11420 }
11421 if (LocaleCompare(attribute,"skew") == 0)
11422 {
11423 double
11424 x_angle,
11425 y_angle;
11426
11427 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11428 x_angle=geometry_info.rho;
11429 y_angle=geometry_info.sigma;
11430 if ((flags & SigmaValue) == 0)
11431 y_angle=x_angle;
11432 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
11433 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
11434 break;
11435 }
11436 if (LocaleCompare(attribute,"stroke") == 0)
11437 {
11438 if (info)
11439 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->stroke,
11440 &image->exception);
11441 break;
11442 }
11443 if (LocaleCompare(attribute,"style") == 0)
11444 {
11445 type=ParseMagickOption(MagickStyleOptions,MagickFalse,
11446 SvPV(ST(i),na));
11447 if (type < 0)
11448 {
11449 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11450 SvPV(ST(i),na));
11451 break;
11452 }
11453 draw_info->style=(StyleType) type;
11454 break;
11455 }
11456 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11457 attribute);
11458 break;
11459 }
11460 case 't':
11461 case 'T':
11462 {
11463 if (LocaleCompare(attribute,"text") == 0)
11464 {
11465 CloneString(&draw_info->text,SvPV(ST(i),na));
11466 break;
11467 }
11468 if (LocaleCompare(attribute,"translate") == 0)
11469 {
11470 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11471 affine.tx=geometry_info.rho;
11472 affine.ty=geometry_info.sigma;
11473 if ((flags & SigmaValue) == 0)
11474 affine.ty=affine.tx;
11475 break;
11476 }
11477 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11478 attribute);
11479 break;
11480 }
11481 case 'w':
11482 case 'W':
11483 {
11484 if (LocaleCompare(attribute,"weight") == 0)
11485 {
11486 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11487 draw_info->weight=(unsigned long) geometry_info.rho;
11488 break;
11489 }
11490 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11491 attribute);
11492 break;
11493 }
11494 case 'x':
11495 case 'X':
11496 {
11497 if (LocaleCompare(attribute,"x") == 0)
11498 {
11499 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11500 x=geometry_info.rho;
11501 break;
11502 }
11503 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11504 attribute);
11505 break;
11506 }
11507 case 'y':
11508 case 'Y':
11509 {
11510 if (LocaleCompare(attribute,"y") == 0)
11511 {
11512 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11513 y=geometry_info.rho;
11514 break;
11515 }
11516 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11517 attribute);
11518 break;
11519 }
11520 default:
11521 {
11522 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11523 attribute);
11524 break;
11525 }
11526 }
11527 }
11528 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
11529 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
11530 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
11531 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
11532 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
11533 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
11534 if (draw_info->geometry == (char *) NULL)
11535 {
11536 draw_info->geometry=AcquireString((char *) NULL);
11537 (void) FormatMagickString(draw_info->geometry,MaxTextExtent,"%g,%g",
11538 x,y);
11539 }
11540 status=GetTypeMetrics(image,draw_info,&metrics);
11541 (void) CatchImageException(image);
11542 if (status == MagickFalse)
11543 PUSHs(&sv_undef);
11544 else
11545 {
11546 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
11547 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
11548 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
11549 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
11550 PUSHs(sv_2mortal(newSVnv(metrics.width)));
11551 PUSHs(sv_2mortal(newSVnv(metrics.height)));
11552 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
11553 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
11554 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
11555 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
11556 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
11557 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
11558 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
11559 }
11560 draw_info=DestroyDrawInfo(draw_info);
11561
11562 PerlException:
11563 if (package_info != (struct PackageInfo *) NULL)
11564 DestroyPackageInfo(package_info);
11565 InheritPerlException(exception,perl_exception);
11566 exception=DestroyExceptionInfo(exception);
11567 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11568 }
11569
11570#
11571###############################################################################
11572# #
11573# #
11574# #
11575# 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 #
11576# #
11577# #
11578# #
11579###############################################################################
11580#
11581#
11582void
11583QueryMultilineFontMetrics(ref,...)
11584 Image::Magick ref=NO_INIT
11585 ALIAS:
11586 querymultilinefontmetrics = 1
11587 PPCODE:
11588 {
11589 AffineMatrix
11590 affine,
11591 current;
11592
11593 AV
11594 *av;
11595
11596 char
11597 *attribute;
11598
11599 double
11600 x,
11601 y;
11602
11603 DrawInfo
11604 *draw_info;
11605
11606 ExceptionInfo
11607 *exception;
11608
11609 GeometryInfo
11610 geometry_info;
11611
11612 Image
11613 *image;
11614
11615 long
11616 type;
11617
11618 MagickBooleanType
11619 status;
11620
11621 MagickStatusType
11622 flags;
11623
11624 register long
11625 i;
11626
11627 struct PackageInfo
11628 *info,
11629 *package_info;
11630
11631 SV
11632 *perl_exception,
11633 *reference; /* reference is the SV* of ref=SvIV(reference) */
11634
11635 TypeMetric
11636 metrics;
11637
11638 exception=AcquireExceptionInfo();
11639 package_info=(struct PackageInfo *) NULL;
11640 perl_exception=newSVpv("",0);
11641 reference=SvRV(ST(0));
11642 av=(AV *) reference;
11643 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11644 exception);
11645 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11646 if (image == (Image *) NULL)
11647 {
11648 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11649 PackageName);
11650 goto PerlException;
11651 }
11652 package_info=ClonePackageInfo(info,exception);
11653 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
11654 CloneString(&draw_info->text,"");
11655 current=draw_info->affine;
11656 GetAffineMatrix(&affine);
11657 x=0.0;
11658 y=0.0;
11659 EXTEND(sp,7*items);
11660 for (i=2; i < items; i+=2)
11661 {
11662 attribute=(char *) SvPV(ST(i-1),na);
11663 switch (*attribute)
11664 {
11665 case 'A':
11666 case 'a':
11667 {
11668 if (LocaleCompare(attribute,"antialias") == 0)
11669 {
11670 type=ParseMagickOption(MagickBooleanOptions,MagickFalse,
11671 SvPV(ST(i),na));
11672 if (type < 0)
11673 {
11674 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11675 SvPV(ST(i),na));
11676 break;
11677 }
11678 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
11679 break;
11680 }
11681 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11682 attribute);
11683 break;
11684 }
11685 case 'd':
11686 case 'D':
11687 {
11688 if (LocaleCompare(attribute,"density") == 0)
11689 {
11690 CloneString(&draw_info->density,SvPV(ST(i),na));
11691 break;
11692 }
11693 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11694 attribute);
11695 break;
11696 }
11697 case 'e':
11698 case 'E':
11699 {
11700 if (LocaleCompare(attribute,"encoding") == 0)
11701 {
11702 CloneString(&draw_info->encoding,SvPV(ST(i),na));
11703 break;
11704 }
11705 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11706 attribute);
11707 break;
11708 }
11709 case 'f':
11710 case 'F':
11711 {
11712 if (LocaleCompare(attribute,"family") == 0)
11713 {
11714 CloneString(&draw_info->family,SvPV(ST(i),na));
11715 break;
11716 }
11717 if (LocaleCompare(attribute,"fill") == 0)
11718 {
11719 if (info)
11720 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->fill,
11721 &image->exception);
11722 break;
11723 }
11724 if (LocaleCompare(attribute,"font") == 0)
11725 {
11726 CloneString(&draw_info->font,SvPV(ST(i),na));
11727 break;
11728 }
11729 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11730 attribute);
11731 break;
11732 }
11733 case 'g':
11734 case 'G':
11735 {
11736 if (LocaleCompare(attribute,"geometry") == 0)
11737 {
11738 CloneString(&draw_info->geometry,SvPV(ST(i),na));
11739 break;
11740 }
11741 if (LocaleCompare(attribute,"gravity") == 0)
11742 {
11743 draw_info->gravity=(GravityType) ParseMagickOption(
11744 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11745 break;
11746 }
11747 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11748 attribute);
11749 break;
11750 }
11751 case 'p':
11752 case 'P':
11753 {
11754 if (LocaleCompare(attribute,"pointsize") == 0)
11755 {
11756 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11757 draw_info->pointsize=geometry_info.rho;
11758 break;
11759 }
11760 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11761 attribute);
11762 break;
11763 }
11764 case 'r':
11765 case 'R':
11766 {
11767 if (LocaleCompare(attribute,"rotate") == 0)
11768 {
11769 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11770 affine.rx=geometry_info.rho;
11771 affine.ry=geometry_info.sigma;
11772 if ((flags & SigmaValue) == 0)
11773 affine.ry=affine.rx;
11774 break;
11775 }
11776 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11777 attribute);
11778 break;
11779 }
11780 case 's':
11781 case 'S':
11782 {
11783 if (LocaleCompare(attribute,"scale") == 0)
11784 {
11785 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11786 affine.sx=geometry_info.rho;
11787 affine.sy=geometry_info.sigma;
11788 if ((flags & SigmaValue) == 0)
11789 affine.sy=affine.sx;
11790 break;
11791 }
11792 if (LocaleCompare(attribute,"skew") == 0)
11793 {
11794 double
11795 x_angle,
11796 y_angle;
11797
11798 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11799 x_angle=geometry_info.rho;
11800 y_angle=geometry_info.sigma;
11801 if ((flags & SigmaValue) == 0)
11802 y_angle=x_angle;
11803 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
11804 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
11805 break;
11806 }
11807 if (LocaleCompare(attribute,"stroke") == 0)
11808 {
11809 if (info)
11810 (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->stroke,
11811 &image->exception);
11812 break;
11813 }
11814 if (LocaleCompare(attribute,"style") == 0)
11815 {
11816 type=ParseMagickOption(MagickStyleOptions,MagickFalse,
11817 SvPV(ST(i),na));
11818 if (type < 0)
11819 {
11820 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11821 SvPV(ST(i),na));
11822 break;
11823 }
11824 draw_info->style=(StyleType) type;
11825 break;
11826 }
11827 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11828 attribute);
11829 break;
11830 }
11831 case 't':
11832 case 'T':
11833 {
11834 if (LocaleCompare(attribute,"text") == 0)
11835 {
11836 CloneString(&draw_info->text,SvPV(ST(i),na));
11837 break;
11838 }
11839 if (LocaleCompare(attribute,"translate") == 0)
11840 {
11841 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11842 affine.tx=geometry_info.rho;
11843 affine.ty=geometry_info.sigma;
11844 if ((flags & SigmaValue) == 0)
11845 affine.ty=affine.tx;
11846 break;
11847 }
11848 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11849 attribute);
11850 break;
11851 }
11852 case 'w':
11853 case 'W':
11854 {
11855 if (LocaleCompare(attribute,"weight") == 0)
11856 {
11857 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11858 draw_info->weight=(unsigned long) geometry_info.rho;
11859 break;
11860 }
11861 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11862 attribute);
11863 break;
11864 }
11865 case 'x':
11866 case 'X':
11867 {
11868 if (LocaleCompare(attribute,"x") == 0)
11869 {
11870 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11871 x=geometry_info.rho;
11872 break;
11873 }
11874 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11875 attribute);
11876 break;
11877 }
11878 case 'y':
11879 case 'Y':
11880 {
11881 if (LocaleCompare(attribute,"y") == 0)
11882 {
11883 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
11884 y=geometry_info.rho;
11885 break;
11886 }
11887 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11888 attribute);
11889 break;
11890 }
11891 default:
11892 {
11893 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11894 attribute);
11895 break;
11896 }
11897 }
11898 }
11899 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
11900 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
11901 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
11902 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
11903 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
11904 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
11905 if (draw_info->geometry == (char *) NULL)
11906 {
11907 draw_info->geometry=AcquireString((char *) NULL);
11908 (void) FormatMagickString(draw_info->geometry,MaxTextExtent,"%g,%g",
11909 x,y);
11910 }
11911 status=GetMultilineTypeMetrics(image,draw_info,&metrics);
11912 (void) CatchImageException(image);
11913 if (status == MagickFalse)
11914 PUSHs(&sv_undef);
11915 else
11916 {
11917 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
11918 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
11919 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
11920 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
11921 PUSHs(sv_2mortal(newSVnv(metrics.width)));
11922 PUSHs(sv_2mortal(newSVnv(metrics.height)));
11923 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
11924 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
11925 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
11926 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
11927 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
11928 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
11929 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
11930 }
11931 draw_info=DestroyDrawInfo(draw_info);
11932
11933 PerlException:
11934 if (package_info != (struct PackageInfo *) NULL)
11935 DestroyPackageInfo(package_info);
11936 InheritPerlException(exception,perl_exception);
11937 exception=DestroyExceptionInfo(exception);
11938 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11939 }
11940
11941#
11942###############################################################################
11943# #
11944# #
11945# #
11946# Q u e r y F o r m a t #
11947# #
11948# #
11949# #
11950###############################################################################
11951#
11952#
11953void
11954QueryFormat(ref,...)
11955 Image::Magick ref=NO_INIT
11956 ALIAS:
11957 queryformat = 1
11958 PPCODE:
11959 {
11960 char
11961 *name;
11962
11963 ExceptionInfo
11964 *exception;
11965
11966 register long
11967 i;
11968
11969 SV
11970 *perl_exception;
11971
11972 volatile const MagickInfo
11973 *magick_info;
11974
11975 exception=AcquireExceptionInfo();
11976 perl_exception=newSVpv("",0);
11977 if (items == 1)
11978 {
11979 char
11980 format[MaxTextExtent];
11981
11982 const MagickInfo
11983 **format_list;
11984
11985 unsigned long
11986 types;
11987
11988 format_list=GetMagickInfoList("*",&types,exception);
11989 EXTEND(sp,types);
11990 for (i=0; i < (long) types; i++)
11991 {
11992 (void) CopyMagickString(format,format_list[i]->name,MaxTextExtent);
11993 LocaleLower(format);
11994 PUSHs(sv_2mortal(newSVpv(format,0)));
11995 }
11996 format_list=(const MagickInfo **)
11997 RelinquishMagickMemory((MagickInfo *) format_list);
11998 goto PerlException;
11999 }
12000 EXTEND(sp,8*items);
12001 for (i=1; i < items; i++)
12002 {
12003 name=(char *) SvPV(ST(i),na);
12004 magick_info=GetMagickInfo(name,exception);
12005 if (magick_info == (const MagickInfo *) NULL)
12006 {
12007 PUSHs(&sv_undef);
12008 continue;
12009 }
12010 PUSHs(sv_2mortal(newSViv(magick_info->adjoin)));
12011 PUSHs(sv_2mortal(newSViv(magick_info->blob_support)));
12012 PUSHs(sv_2mortal(newSViv(magick_info->raw)));
12013 PUSHs(sv_2mortal(newSViv((long) magick_info->decoder)));
12014 PUSHs(sv_2mortal(newSViv((long) magick_info->encoder)));
12015 if (magick_info->description == (char *) NULL)
12016 PUSHs(&sv_undef);
12017 else
12018 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
12019 if (magick_info->module == (char *) NULL)
12020 PUSHs(&sv_undef);
12021 else
12022 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
12023 }
12024
12025 PerlException:
12026 InheritPerlException(exception,perl_exception);
12027 exception=DestroyExceptionInfo(exception);
12028 SvREFCNT_dec(perl_exception);
12029 }
12030
12031#
12032###############################################################################
12033# #
12034# #
12035# #
12036# Q u e r y O p t i o n #
12037# #
12038# #
12039# #
12040###############################################################################
12041#
12042#
12043void
12044QueryOption(ref,...)
12045 Image::Magick ref=NO_INIT
12046 ALIAS:
12047 queryoption = 1
12048 PPCODE:
12049 {
12050 char
12051 **options;
12052
12053 ExceptionInfo
12054 *exception;
12055
12056 long
12057 j,
12058 option;
12059
12060 register long
12061 i;
12062
12063 SV
12064 *perl_exception;
12065
12066 exception=AcquireExceptionInfo();
12067 perl_exception=newSVpv("",0);
12068 EXTEND(sp,8*items);
12069 for (i=1; i < items; i++)
12070 {
12071 option=ParseMagickOption(MagickListOptions,MagickFalse,(char *)
12072 SvPV(ST(i),na));
12073 options=GetMagickOptions((MagickOption) option);
12074 if (options == (char **) NULL)
12075 PUSHs(&sv_undef);
12076 else
12077 {
12078 for (j=0; options[j] != (char *) NULL; j++)
12079 PUSHs(sv_2mortal(newSVpv(options[j],0)));
12080 options=DestroyStringList(options);
12081 }
12082 }
12083
12084 PerlException:
12085 InheritPerlException(exception,perl_exception);
12086 exception=DestroyExceptionInfo(exception);
12087 SvREFCNT_dec(perl_exception);
12088 }
12089
12090#
12091###############################################################################
12092# #
12093# #
12094# #
12095# R e a d #
12096# #
12097# #
12098# #
12099###############################################################################
12100#
12101#
12102void
12103Read(ref,...)
12104 Image::Magick ref=NO_INIT
12105 ALIAS:
12106 ReadImage = 1
12107 read = 2
12108 readimage = 3
12109 PPCODE:
12110 {
12111 AV
12112 *av;
12113
12114 char
12115 **keep,
12116 **list;
12117
12118 ExceptionInfo
12119 *exception;
12120
12121 HV
12122 *hv;
12123
12124 Image
12125 *image;
12126
12127 int
12128 n;
12129
12130 long
12131 ac,
12132 number_images;
12133
12134 MagickBooleanType
12135 status;
12136
12137 register char
12138 **p;
12139
12140 register long
12141 i;
12142
12143 STRLEN
12144 *length;
12145
12146 struct PackageInfo
12147 *info,
12148 *package_info;
12149
12150 SV
12151 *perl_exception, /* Perl variable for storing messages */
12152 *reference,
12153 *rv,
12154 *sv;
12155
12156 exception=AcquireExceptionInfo();
12157 perl_exception=newSVpv("",0);
12158 package_info=(struct PackageInfo *) NULL;
12159 number_images=0;
12160 ac=(items < 2) ? 1 : items-1;
12161 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12162 keep=list;
12163 length=(STRLEN *) NULL;
12164 if (list == (char **) NULL)
12165 {
12166 ThrowPerlException(exception,ResourceLimitError,
12167 "MemoryAllocationFailed",PackageName);
12168 goto PerlException;
12169 }
12170 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12171 if (length == (STRLEN *) NULL)
12172 {
12173 ThrowPerlException(exception,ResourceLimitError,
12174 "MemoryAllocationFailed",PackageName);
12175 goto PerlException;
12176 }
12177 if (sv_isobject(ST(0)) == 0)
12178 {
12179 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12180 PackageName);
12181 goto PerlException;
12182 }
12183 reference=SvRV(ST(0));
12184 hv=SvSTASH(reference);
12185 if (SvTYPE(reference) != SVt_PVAV)
12186 {
12187 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12188 PackageName);
12189 goto PerlException;
12190 }
12191 av=(AV *) reference;
12192 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12193 exception);
12194 package_info=ClonePackageInfo(info,exception);
12195 n=1;
12196 if (items <= 1)
12197 *list=(char *) (*package_info->image_info->filename ?
12198 package_info->image_info->filename : "XC:black");
12199 else
12200 for (n=0, i=0; i < ac; i++)
12201 {
12202 list[n]=(char *) SvPV(ST(i+1),length[n]);
12203 if ((items >= 3) && strEQcase(list[n],"blob"))
12204 {
12205 void
12206 *blob;
12207
12208 i++;
12209 blob=(void *) (SvPV(ST(i+1),length[n]));
12210 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12211 }
12212 if ((items >= 3) && strEQcase(list[n],"filename"))
12213 continue;
12214 if ((items >= 3) && strEQcase(list[n],"file"))
12215 {
12216 FILE
12217 *file;
12218
12219 PerlIO
12220 *io_info;
12221
12222 i++;
12223 io_info=IoIFP(sv_2io(ST(i+1)));
12224 if (io_info == (PerlIO *) NULL)
12225 {
12226 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12227 PackageName);
12228 continue;
12229 }
12230 file=PerlIO_findFILE(io_info);
12231 if (file == (FILE *) NULL)
12232 {
12233 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12234 PackageName);
12235 continue;
12236 }
12237 SetImageInfoFile(package_info->image_info,file);
12238 }
12239 if ((items >= 3) && strEQcase(list[n],"magick"))
12240 continue;
12241 n++;
12242 }
12243 list[n]=(char *) NULL;
12244 keep=list;
12245 status=ExpandFilenames(&n,&list);
12246 if (status == MagickFalse)
12247 {
12248 ThrowPerlException(exception,ResourceLimitError,
12249 "MemoryAllocationFailed",PackageName);
12250 goto PerlException;
12251 }
12252 number_images=0;
12253 for (i=0; i < n; i++)
12254 {
12255 if ((package_info->image_info->file != (FILE *) NULL) ||
12256 (package_info->image_info->blob != (void *) NULL))
12257 {
12258 image=ReadImages(package_info->image_info,exception);
12259 if (image != (Image *) NULL)
12260 DisassociateImageStream(image);
12261 }
12262 else
12263 {
12264 (void) CopyMagickString(package_info->image_info->filename,list[i],
12265 MaxTextExtent);
12266 image=ReadImages(package_info->image_info,exception);
12267 }
12268 if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
12269 break;
12270 for ( ; image; image=image->next)
12271 {
12272 AddImageToRegistry(image);
12273 rv=newRV(sv);
12274 av_push(av,sv_bless(rv,hv));
12275 SvREFCNT_dec(sv);
12276 number_images++;
12277 }
12278 }
12279 /*
12280 Free resources.
12281 */
12282 for (i=0; i < n; i++)
12283 if (list[i] != (char *) NULL)
12284 for (p=keep; list[i] != *p++; )
12285 if (*p == (char *) NULL)
12286 {
12287 list[i]=(char *) RelinquishMagickMemory(list[i]);
12288 break;
12289 }
12290
12291 PerlException:
12292 if (package_info != (struct PackageInfo *) NULL)
12293 DestroyPackageInfo(package_info);
12294 if (list && (list != keep))
12295 list=(char **) RelinquishMagickMemory(list);
12296 if (keep)
12297 keep=(char **) RelinquishMagickMemory(keep);
12298 if (length)
12299 length=(STRLEN *) RelinquishMagickMemory(length);
12300 InheritPerlException(exception,perl_exception);
12301 exception=DestroyExceptionInfo(exception);
12302 sv_setiv(perl_exception,(IV) number_images);
12303 SvPOK_on(perl_exception);
12304 ST(0)=sv_2mortal(perl_exception);
12305 XSRETURN(1);
12306 }
12307
12308#
12309###############################################################################
12310# #
12311# #
12312# #
12313# R e m o t e #
12314# #
12315# #
12316# #
12317###############################################################################
12318#
12319#
12320void
12321Remote(ref,...)
12322 Image::Magick ref=NO_INIT
12323 ALIAS:
12324 RemoteCommand = 1
12325 remote = 2
12326 remoteCommand = 3
12327 PPCODE:
12328 {
12329 AV
12330 *av;
12331
12332 ExceptionInfo
12333 *exception;
12334
12335 register long
12336 i;
12337
12338 SV
12339 *perl_exception,
12340 *reference;
12341
12342 struct PackageInfo
12343 *info;
12344
12345 exception=AcquireExceptionInfo();
12346 perl_exception=newSVpv("",0);
12347 reference=SvRV(ST(0));
12348 av=(AV *) reference;
12349 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12350 exception);
12351 for (i=1; i < items; i++)
12352 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
12353 SvPV(ST(i),na),exception);
12354 InheritPerlException(exception,perl_exception);
12355 exception=DestroyExceptionInfo(exception);
12356 SvREFCNT_dec(perl_exception); /* throw away all errors */
12357 }
12358
12359#
12360###############################################################################
12361# #
12362# #
12363# #
12364# S e t #
12365# #
12366# #
12367# #
12368###############################################################################
12369#
12370#
12371void
12372Set(ref,...)
12373 Image::Magick ref=NO_INIT
12374 ALIAS:
12375 SetAttributes = 1
12376 SetAttribute = 2
12377 set = 3
12378 setattributes = 4
12379 setattribute = 5
12380 PPCODE:
12381 {
12382 ExceptionInfo
12383 *exception;
12384
12385 Image
12386 *image;
12387
12388 register long
12389 i;
12390
12391 struct PackageInfo
12392 *info;
12393
12394 SV
12395 *perl_exception,
12396 *reference; /* reference is the SV* of ref=SvIV(reference) */
12397
12398 exception=AcquireExceptionInfo();
12399 perl_exception=newSVpv("",0);
12400 if (sv_isobject(ST(0)) == 0)
12401 {
12402 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12403 PackageName);
12404 goto PerlException;
12405 }
12406 reference=SvRV(ST(0));
12407 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12408 if (items == 2)
12409 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
12410 else
12411 for (i=2; i < items; i+=2)
12412 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
12413
12414 PerlException:
12415 InheritPerlException(exception,perl_exception);
12416 exception=DestroyExceptionInfo(exception);
12417 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
12418 SvPOK_on(perl_exception);
12419 ST(0)=sv_2mortal(perl_exception);
12420 XSRETURN(1);
12421 }
12422
12423#
12424###############################################################################
12425# #
12426# #
12427# #
12428# S e t P i x e l #
12429# #
12430# #
12431# #
12432###############################################################################
12433#
12434#
12435void
12436SetPixel(ref,...)
12437 Image::Magick ref=NO_INIT
12438 ALIAS:
12439 setpixel = 1
12440 setPixel = 2
12441 PPCODE:
12442 {
12443 AV
12444 *av;
12445
12446 char
12447 *attribute;
12448
12449 ChannelType
12450 channel;
12451
12452 ExceptionInfo
12453 *exception;
12454
12455 Image
12456 *image;
12457
12458 long
12459 option;
12460
12461 MagickBooleanType
12462 normalize;
12463
12464 RectangleInfo
12465 region;
12466
12467 register IndexPacket
12468 *indexes;
12469
12470 register long
12471 i;
12472
12473 register PixelPacket
12474 *q;
12475
12476 struct PackageInfo
12477 *info;
12478
12479 SV
12480 *perl_exception,
12481 *reference; /* reference is the SV* of ref=SvIV(reference) */
12482
12483 exception=AcquireExceptionInfo();
12484 perl_exception=newSVpv("",0);
12485 reference=SvRV(ST(0));
12486 av=(AV *) reference;
12487 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12488 exception);
12489 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12490 if (image == (Image *) NULL)
12491 {
12492 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12493 PackageName);
12494 goto PerlException;
12495 }
12496 av=(AV *) NULL;
12497 channel=DefaultChannels;
12498 normalize=MagickTrue;
12499 region.x=0;
12500 region.y=0;
12501 region.width=image->columns;
12502 region.height=1;
12503 if (items == 1)
12504 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
12505 for (i=2; i < items; i+=2)
12506 {
12507 attribute=(char *) SvPV(ST(i-1),na);
12508 switch (*attribute)
12509 {
12510 case 'C':
12511 case 'c':
12512 {
12513 if (LocaleCompare(attribute,"channel") == 0)
12514 {
12515 long
12516 option;
12517
12518 option=ParseChannelOption(SvPV(ST(i),na));
12519 if (option < 0)
12520 {
12521 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12522 SvPV(ST(i),na));
12523 return;
12524 }
12525 channel=(ChannelType) option;
12526 break;
12527 }
12528 if (LocaleCompare(attribute,"color") == 0)
12529 {
12530 if (SvTYPE(ST(i)) != SVt_RV)
12531 {
12532 char
12533 message[MaxTextExtent];
12534
12535 (void) FormatMagickString(message,MaxTextExtent,
12536 "invalid %.60s value",attribute);
12537 ThrowPerlException(exception,OptionError,message,
12538 SvPV(ST(i),na));
12539 }
12540 av=(AV *) SvRV(ST(i));
12541 break;
12542 }
12543 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12544 attribute);
12545 break;
12546 }
12547 case 'g':
12548 case 'G':
12549 {
12550 if (LocaleCompare(attribute,"geometry") == 0)
12551 {
12552 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
12553 break;
12554 }
12555 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12556 attribute);
12557 break;
12558 }
12559 case 'N':
12560 case 'n':
12561 {
12562 if (LocaleCompare(attribute,"normalize") == 0)
12563 {
12564 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
12565 SvPV(ST(i),na));
12566 if (option < 0)
12567 {
12568 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12569 SvPV(ST(i),na));
12570 break;
12571 }
12572 normalize=option != 0 ? MagickTrue : MagickFalse;
12573 break;
12574 }
12575 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12576 attribute);
12577 break;
12578 }
12579 case 'x':
12580 case 'X':
12581 {
12582 if (LocaleCompare(attribute,"x") == 0)
12583 {
12584 region.x=SvIV(ST(i));
12585 break;
12586 }
12587 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12588 attribute);
12589 break;
12590 }
12591 case 'y':
12592 case 'Y':
12593 {
12594 if (LocaleCompare(attribute,"y") == 0)
12595 {
12596 region.y=SvIV(ST(i));
12597 break;
12598 }
12599 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12600 attribute);
12601 break;
12602 }
12603 default:
12604 {
12605 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12606 attribute);
12607 break;
12608 }
12609 }
12610 }
12611 (void) SetImageStorageClass(image,DirectClass);
12612 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
12613 if ((q == (PixelPacket *) NULL) || (av == (AV *) NULL))
12614 PUSHs(&sv_undef);
12615 else
12616 {
12617 double
12618 scale;
12619
12620 register long
12621 i;
12622
12623 i=0;
12624 indexes=GetAuthenticIndexQueue(image);
12625 scale=1.0;
12626 if (normalize != MagickFalse)
12627 scale=QuantumRange;
12628 if (((channel & RedChannel) != 0) && (i <= av_len(av)))
12629 {
12630 q->red=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12631 i++;
12632 }
12633 if (((channel & GreenChannel) != 0) && (i <= av_len(av)))
12634 {
12635 q->green=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12636 i++;
12637 }
12638 if (((channel & BlueChannel) != 0) && (i <= av_len(av)))
12639 {
12640 q->blue=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12641 i++;
12642 }
12643 if ((((channel & IndexChannel) != 0) &&
12644 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
12645 {
12646 *indexes=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12647 i++;
12648 }
12649 if (((channel & OpacityChannel) != 0) && (i <= av_len(av)))
12650 {
12651 q->opacity=RoundToQuantum(QuantumRange*SvNV(*(av_fetch(av,i,0))));
12652 i++;
12653 }
12654 (void) SyncAuthenticPixels(image,exception);
12655 }
12656
12657 PerlException:
12658 InheritPerlException(exception,perl_exception);
12659 exception=DestroyExceptionInfo(exception);
12660 SvREFCNT_dec(perl_exception);
12661 }
12662
12663#
12664###############################################################################
12665# #
12666# #
12667# #
12668# S t a t i s t i c s #
12669# #
12670# #
12671# #
12672###############################################################################
12673#
12674#
12675void
12676Statistics(ref,...)
12677 Image::Magick ref=NO_INIT
12678 ALIAS:
12679 StatisticsImage = 1
12680 statistics = 2
12681 statisticsimage = 3
12682 PPCODE:
12683 {
12684 AV
12685 *av;
12686
12687 char
12688 message[MaxTextExtent];
12689
12690 ChannelStatistics
12691 *channel_statistics;
12692
12693 double
12694 scale;
12695
12696 ExceptionInfo
12697 *exception;
12698
12699 HV
12700 *hv;
12701
12702 Image
12703 *image;
12704
12705 ssize_t
12706 count;
12707
12708 struct PackageInfo
12709 *info;
12710
12711 SV
12712 *av_reference,
12713 *perl_exception,
12714 *reference;
12715
12716 exception=AcquireExceptionInfo();
12717 perl_exception=newSVpv("",0);
12718 av=NULL;
12719 if (sv_isobject(ST(0)) == 0)
12720 {
12721 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12722 PackageName);
12723 goto PerlException;
12724 }
12725 reference=SvRV(ST(0));
12726 hv=SvSTASH(reference);
12727 av=newAV();
12728 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12729 SvREFCNT_dec(av);
12730 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12731 if (image == (Image *) NULL)
12732 {
12733 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12734 PackageName);
12735 goto PerlException;
12736 }
12737 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12738 count=0;
12739 for ( ; image; image=image->next)
12740 {
12741 channel_statistics=GetImageChannelStatistics(image,&image->exception);
12742 if (channel_statistics == (ChannelStatistics *) NULL)
12743 continue;
12744 count++;
12745 EXTEND(sp,25*count);
12746 scale=(double) QuantumRange;
12747 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12748 channel_statistics[RedChannel].depth);
12749 PUSHs(sv_2mortal(newSVpv(message,0)));
12750 (void) FormatMagickString(message,MaxTextExtent,"%g",
12751 channel_statistics[RedChannel].minima/scale);
12752 PUSHs(sv_2mortal(newSVpv(message,0)));
12753 (void) FormatMagickString(message,MaxTextExtent,"%g",
12754 channel_statistics[RedChannel].maxima/scale);
12755 PUSHs(sv_2mortal(newSVpv(message,0)));
12756 (void) FormatMagickString(message,MaxTextExtent,"%g",
12757 channel_statistics[RedChannel].mean/scale);
12758 PUSHs(sv_2mortal(newSVpv(message,0)));
12759 (void) FormatMagickString(message,MaxTextExtent,"%g",
12760 channel_statistics[RedChannel].standard_deviation/scale);
12761 PUSHs(sv_2mortal(newSVpv(message,0)));
12762 (void) FormatMagickString(message,MaxTextExtent,"%g",
12763 channel_statistics[RedChannel].kurtosis);
12764 PUSHs(sv_2mortal(newSVpv(message,0)));
12765 (void) FormatMagickString(message,MaxTextExtent,"%g",
12766 channel_statistics[RedChannel].skewness);
12767 PUSHs(sv_2mortal(newSVpv(message,0)));
12768 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12769 channel_statistics[GreenChannel].depth);
12770 PUSHs(sv_2mortal(newSVpv(message,0)));
12771 (void) FormatMagickString(message,MaxTextExtent,"%g",
12772 channel_statistics[GreenChannel].minima/scale);
12773 PUSHs(sv_2mortal(newSVpv(message,0)));
12774 (void) FormatMagickString(message,MaxTextExtent,"%g",
12775 channel_statistics[GreenChannel].maxima/scale);
12776 PUSHs(sv_2mortal(newSVpv(message,0)));
12777 (void) FormatMagickString(message,MaxTextExtent,"%g",
12778 channel_statistics[GreenChannel].mean/scale);
12779 PUSHs(sv_2mortal(newSVpv(message,0)));
12780 (void) FormatMagickString(message,MaxTextExtent,"%g",
12781 channel_statistics[GreenChannel].standard_deviation/scale);
12782 PUSHs(sv_2mortal(newSVpv(message,0)));
12783 (void) FormatMagickString(message,MaxTextExtent,"%g",
12784 channel_statistics[GreenChannel].kurtosis);
12785 PUSHs(sv_2mortal(newSVpv(message,0)));
12786 (void) FormatMagickString(message,MaxTextExtent,"%g",
12787 channel_statistics[GreenChannel].skewness);
12788 PUSHs(sv_2mortal(newSVpv(message,0)));
12789 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12790 channel_statistics[BlueChannel].depth);
12791 PUSHs(sv_2mortal(newSVpv(message,0)));
12792 (void) FormatMagickString(message,MaxTextExtent,"%g",
12793 channel_statistics[BlueChannel].minima/scale);
12794 PUSHs(sv_2mortal(newSVpv(message,0)));
12795 (void) FormatMagickString(message,MaxTextExtent,"%g",
12796 channel_statistics[BlueChannel].maxima/scale);
12797 PUSHs(sv_2mortal(newSVpv(message,0)));
12798 (void) FormatMagickString(message,MaxTextExtent,"%g",
12799 channel_statistics[BlueChannel].mean/scale);
12800 PUSHs(sv_2mortal(newSVpv(message,0)));
12801 (void) FormatMagickString(message,MaxTextExtent,"%g",
12802 channel_statistics[BlueChannel].standard_deviation/scale);
12803 PUSHs(sv_2mortal(newSVpv(message,0)));
12804 (void) FormatMagickString(message,MaxTextExtent,"%g",
12805 channel_statistics[BlueChannel].kurtosis);
12806 PUSHs(sv_2mortal(newSVpv(message,0)));
12807 (void) FormatMagickString(message,MaxTextExtent,"%g",
12808 channel_statistics[BlueChannel].skewness);
12809 PUSHs(sv_2mortal(newSVpv(message,0)));
12810 if (image->colorspace == CMYKColorspace)
12811 {
12812 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12813 channel_statistics[BlackChannel].depth);
12814 PUSHs(sv_2mortal(newSVpv(message,0)));
12815 (void) FormatMagickString(message,MaxTextExtent,"%g",
12816 channel_statistics[BlackChannel].minima/scale);
12817 PUSHs(sv_2mortal(newSVpv(message,0)));
12818 (void) FormatMagickString(message,MaxTextExtent,"%g",
12819 channel_statistics[BlackChannel].maxima/scale);
12820 PUSHs(sv_2mortal(newSVpv(message,0)));
12821 (void) FormatMagickString(message,MaxTextExtent,"%g",
12822 channel_statistics[BlackChannel].mean/scale);
12823 PUSHs(sv_2mortal(newSVpv(message,0)));
12824 (void) FormatMagickString(message,MaxTextExtent,"%g",
12825 channel_statistics[BlackChannel].standard_deviation/scale);
12826 PUSHs(sv_2mortal(newSVpv(message,0)));
12827 (void) FormatMagickString(message,MaxTextExtent,"%g",
12828 channel_statistics[BlackChannel].kurtosis);
12829 PUSHs(sv_2mortal(newSVpv(message,0)));
12830 (void) FormatMagickString(message,MaxTextExtent,"%g",
12831 channel_statistics[BlackChannel].skewness);
12832 PUSHs(sv_2mortal(newSVpv(message,0)));
12833 }
12834 if (image->matte != MagickFalse)
12835 {
12836 (void) FormatMagickString(message,MaxTextExtent,"%lu",
12837 channel_statistics[OpacityChannel].depth);
12838 PUSHs(sv_2mortal(newSVpv(message,0)));
12839 (void) FormatMagickString(message,MaxTextExtent,"%g",
12840 channel_statistics[OpacityChannel].minima/scale);
12841 PUSHs(sv_2mortal(newSVpv(message,0)));
12842 (void) FormatMagickString(message,MaxTextExtent,"%g",
12843 channel_statistics[OpacityChannel].maxima/scale);
12844 PUSHs(sv_2mortal(newSVpv(message,0)));
12845 (void) FormatMagickString(message,MaxTextExtent,"%g",
12846 channel_statistics[OpacityChannel].mean/scale);
12847 PUSHs(sv_2mortal(newSVpv(message,0)));
12848 (void) FormatMagickString(message,MaxTextExtent,"%g",
12849 channel_statistics[OpacityChannel].standard_deviation/scale);
12850 PUSHs(sv_2mortal(newSVpv(message,0)));
12851 (void) FormatMagickString(message,MaxTextExtent,"%g",
12852 channel_statistics[OpacityChannel].kurtosis);
12853 PUSHs(sv_2mortal(newSVpv(message,0)));
12854 (void) FormatMagickString(message,MaxTextExtent,"%g",
12855 channel_statistics[OpacityChannel].skewness);
12856 PUSHs(sv_2mortal(newSVpv(message,0)));
12857 }
12858 channel_statistics=(ChannelStatistics *)
12859 RelinquishMagickMemory(channel_statistics);
12860 }
12861
12862 PerlException:
12863 InheritPerlException(exception,perl_exception);
12864 exception=DestroyExceptionInfo(exception);
12865 SvREFCNT_dec(perl_exception);
12866 }
12867
12868#
12869###############################################################################
12870# #
12871# #
12872# #
12873# S y n c A u t h e n t i c P i x e l s #
12874# #
12875# #
12876# #
12877###############################################################################
12878#
12879#
12880void
12881SyncAuthenticPixels(ref,...)
12882 Image::Magick ref = NO_INIT
12883 ALIAS:
12884 Syncauthenticpixels = 1
12885 SyncImagePixels = 2
12886 syncimagepixels = 3
12887 CODE:
12888 {
12889 ExceptionInfo
12890 *exception;
12891
12892 Image
12893 *image;
12894
12895 MagickBooleanType
12896 status;
12897
12898 struct PackageInfo
12899 *info;
12900
12901 SV
12902 *perl_exception,
12903 *reference;
12904
12905 exception=AcquireExceptionInfo();
12906 perl_exception=newSVpv("",0);
12907
12908 if (sv_isobject(ST(0)) == 0)
12909 {
12910 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12911 PackageName);
12912 goto PerlException;
12913 }
12914
12915 reference=SvRV(ST(0));
12916 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12917 if (image == (Image *) NULL)
12918 {
12919 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12920 PackageName);
12921 goto PerlException;
12922 }
12923
12924 status=SyncAuthenticPixels(image,exception);
12925 if (status != MagickFalse)
12926 return;
12927 InheritException(exception,&image->exception);
12928
12929 PerlException:
12930 InheritPerlException(exception,perl_exception);
12931 exception=DestroyExceptionInfo(exception);
12932 SvREFCNT_dec(perl_exception); /* throw away all errors */
12933 }
12934
12935#
12936###############################################################################
12937# #
12938# #
12939# #
12940# T r a n s f o r m #
12941# #
12942# #
12943# #
12944###############################################################################
12945#
12946#
12947void
12948Transform(ref,...)
12949 Image::Magick ref=NO_INIT
12950 ALIAS:
12951 TransformImage = 1
12952 transform = 2
12953 transformimage = 3
12954 PPCODE:
12955 {
12956 AV
12957 *av;
12958
12959 char
12960 *attribute,
12961 *crop_geometry,
12962 *geometry;
12963
12964 ExceptionInfo
12965 *exception;
12966
12967 HV
12968 *hv;
12969
12970 Image
12971 *clone,
12972 *image;
12973
12974 register long
12975 i;
12976
12977 struct PackageInfo
12978 *info;
12979
12980 SV
12981 *av_reference,
12982 *perl_exception,
12983 *reference,
12984 *rv,
12985 *sv;
12986
12987 exception=AcquireExceptionInfo();
12988 perl_exception=newSVpv("",0);
12989 av=NULL;
12990 attribute=NULL;
12991 if (sv_isobject(ST(0)) == 0)
12992 {
12993 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12994 PackageName);
12995 goto PerlException;
12996 }
12997 reference=SvRV(ST(0));
12998 hv=SvSTASH(reference);
12999 av=newAV();
13000 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
13001 SvREFCNT_dec(av);
13002 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13003 if (image == (Image *) NULL)
13004 {
13005 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13006 PackageName);
13007 goto PerlException;
13008 }
13009 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
13010 /*
13011 Get attribute.
13012 */
13013 crop_geometry=(char *) NULL;
13014 geometry=(char *) NULL;
13015 for (i=2; i < items; i+=2)
13016 {
13017 attribute=(char *) SvPV(ST(i-1),na);
13018 switch (*attribute)
13019 {
13020 case 'c':
13021 case 'C':
13022 {
13023 if (LocaleCompare(attribute,"crop") == 0)
13024 {
13025 crop_geometry=SvPV(ST(i),na);
13026 break;
13027 }
13028 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13029 attribute);
13030 break;
13031 }
13032 case 'g':
13033 case 'G':
13034 {
13035 if (LocaleCompare(attribute,"geometry") == 0)
13036 {
13037 geometry=SvPV(ST(i),na);
13038 break;
13039 }
13040 if (LocaleCompare(attribute,"gravity") == 0)
13041 {
13042 Image
13043 *next;
13044
13045 long
13046 in;
13047
13048 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
13049 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13050 if (in < 0)
13051 {
13052 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13053 SvPV(ST(i),na));
13054 return;
13055 }
13056 for (next=image; next; next=next->next)
13057 next->gravity=(GravityType) in;
13058 break;
13059 }
13060 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13061 attribute);
13062 break;
13063 }
13064 default:
13065 {
13066 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13067 attribute);
13068 break;
13069 }
13070 }
13071 }
13072 for ( ; image; image=image->next)
13073 {
13074 clone=CloneImage(image,0,0,MagickTrue,exception);
13075 if ((clone == (Image *) NULL) || (exception->severity >= ErrorException))
13076 goto PerlException;
13077 TransformImage(&clone,crop_geometry,geometry);
13078 for ( ; clone; clone=clone->next)
13079 {
13080 AddImageToRegistry(clone);
13081 rv=newRV(sv);
13082 av_push(av,sv_bless(rv,hv));
13083 SvREFCNT_dec(sv);
13084 }
13085 }
13086 exception=DestroyExceptionInfo(exception);
13087 ST(0)=av_reference;
13088 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13089 XSRETURN(1);
13090
13091 PerlException:
13092 InheritPerlException(exception,perl_exception);
13093 exception=DestroyExceptionInfo(exception);
13094 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
13095 SvPOK_on(perl_exception);
13096 ST(0)=sv_2mortal(perl_exception);
13097 XSRETURN(1);
13098 }
13099
13100#
13101###############################################################################
13102# #
13103# #
13104# #
13105# W r i t e #
13106# #
13107# #
13108# #
13109###############################################################################
13110#
13111#
13112void
13113Write(ref,...)
13114 Image::Magick ref=NO_INIT
13115 ALIAS:
13116 WriteImage = 1
13117 write = 2
13118 writeimage = 3
13119 PPCODE:
13120 {
13121 char
13122 filename[MaxTextExtent];
13123
13124 ExceptionInfo
13125 *exception;
13126
13127 Image
13128 *image,
13129 *next;
13130
13131 long
13132 number_images,
13133 scene;
13134
13135 register long
13136 i;
13137
13138 struct PackageInfo
13139 *info,
13140 *package_info;
13141
13142 SV
13143 *perl_exception,
13144 *reference;
13145
13146 exception=AcquireExceptionInfo();
13147 perl_exception=newSVpv("",0);
13148 number_images=0;
13149 package_info=(struct PackageInfo *) NULL;
13150 if (sv_isobject(ST(0)) == 0)
13151 {
13152 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13153 PackageName);
13154 goto PerlException;
13155 }
13156 reference=SvRV(ST(0));
13157 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13158 if (image == (Image *) NULL)
13159 {
13160 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13161 PackageName);
13162 goto PerlException;
13163 }
13164 package_info=ClonePackageInfo(info,exception);
13165 if (items == 2)
13166 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
13167 else
13168 if (items > 2)
13169 for (i=2; i < items; i+=2)
13170 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
13171 exception);
13172 (void) CopyMagickString(filename,package_info->image_info->filename,
13173 MaxTextExtent);
13174 scene=0;
13175 for (next=image; next; next=next->next)
13176 {
13177 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
13178 next->scene=scene++;
13179 }
13180 SetImageInfo(package_info->image_info,MagickTrue,&image->exception);
13181 for (next=image; next; next=next->next)
13182 {
13183 (void) WriteImage(package_info->image_info,next);
13184 if (next->exception.severity >= ErrorException)
13185 InheritException(exception,&next->exception);
13186 GetImageException(next,exception);
13187 number_images++;
13188 if (package_info->image_info->adjoin)
13189 break;
13190 }
13191
13192 PerlException:
13193 if (package_info != (struct PackageInfo *) NULL)
13194 DestroyPackageInfo(package_info);
13195 InheritPerlException(exception,perl_exception);
13196 exception=DestroyExceptionInfo(exception);
13197 sv_setiv(perl_exception,(IV) number_images);
13198 SvPOK_on(perl_exception);
13199 ST(0)=sv_2mortal(perl_exception);
13200 XSRETURN(1);
13201 }