1 /*
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 % Cristy %
23 % February 1997 %
24 % %
25 % %
26 % Copyright 1999-2020 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 % https://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(__cplusplus) || defined(c_plusplus)
52 extern "C" {
53 #endif
54
55 #define PERL_NO_GET_CONTEXT
56 #include <MagickCore/MagickCore.h>
57 #include "EXTERN.h"
58 #include "perl.h"
59 #include "XSUB.h"
60 #include <math.h>
61 #undef tainted
62
63 #if defined(__cplusplus) || defined(c_plusplus)
64 }
65 #endif
66
67 /*
68 Define declarations.
69 */
70 #ifndef aTHX_
71 #define aTHX_
72 #define pTHX_
73 #define dTHX
74 #endif
75 #define DegreesToRadians(x) (MagickPI*(x)/180.0)
76 #define EndOf(array) (&array[NumberOf(array)])
77 #define MagickPI 3.14159265358979323846264338327950288419716939937510
78 #define MaxArguments 34
79 #ifndef na
80 #define na PL_na
81 #endif
82 #define NumberOf(array) (sizeof(array)/sizeof(*array))
83 #define PackageName "Image::Magick"
84 #if PERL_VERSION <= 6
85 #define PerlIO FILE
86 #define PerlIO_importFILE(f, fl) (f)
87 #define PerlIO_findFILE(f) NULL
88 #endif
89 #ifndef sv_undef
90 #define sv_undef PL_sv_undef
91 #endif
92
93 #define AddImageToRegistry(sv,image) \
94 { \
95 if (magick_registry != (SplayTreeInfo *) NULL) \
96 { \
97 (void) AddValueToSplayTree(magick_registry,image,image); \
98 (sv)=newSViv(PTR2IV(image)); \
99 } \
100 }
101
102 #define DeleteImageFromRegistry(reference,image) \
103 { \
104 if (magick_registry != (SplayTreeInfo *) NULL) \
105 { \
106 if (GetImageReferenceCount(image) == 1) \
107 (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
108 image=DestroyImage(image); \
109 sv_setiv(reference,0); \
110 } \
111 }
112
113 #define InheritPerlException(exception,perl_exception) \
114 { \
115 char \
116 message[MagickPathExtent]; \
117 \
118 if ((exception)->severity != UndefinedException) \
119 { \
120 (void) FormatLocaleString(message,MagickPathExtent,"Exception %d: %s%s%s%s",\
121 (exception)->severity, (exception)->reason ? \
122 GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
123 "Unknown", (exception)->description ? " (" : "", \
124 (exception)->description ? GetLocaleExceptionMessage( \
125 (exception)->severity,(exception)->description) : "", \
126 (exception)->description ? ")" : ""); \
127 if ((perl_exception) != (SV *) NULL) \
128 { \
129 if (SvCUR(perl_exception)) \
130 sv_catpv(perl_exception,"\n"); \
131 sv_catpv(perl_exception,message); \
132 } \
133 } \
134 }
135
136 #define ThrowPerlException(exception,severity,tag,reason) \
137 (void) ThrowMagickException(exception,GetMagickModule(),severity, \
138 tag,"`%s'",reason); \
139
140 /*
141 Typedef and structure declarations.
142 */
143 typedef enum
144 {
145 NullReference = 0,
146 ArrayReference = (~0),
147 RealReference = (~0)-1,
148 FileReference = (~0)-2,
149 ImageReference = (~0)-3,
150 IntegerReference = (~0)-4,
151 StringReference = (~0)-5
152 } MagickReference;
153
154 typedef struct _Arguments
155 {
156 const char
157 *method;
158
159 ssize_t
160 type;
161 } Arguments;
162
163 struct ArgumentList
164 {
165 ssize_t
166 integer_reference;
167
168 double
169 real_reference;
170
171 const char
172 *string_reference;
173
174 Image
175 *image_reference;
176
177 SV
178 *array_reference;
179
180 FILE
181 *file_reference;
182
183 size_t
184 length;
185 };
186
187 struct PackageInfo
188 {
189 ImageInfo
190 *image_info;
191 };
192
193 typedef void
194 *Image__Magick; /* data type for the Image::Magick package */
195
196 /*
197 Static declarations.
198 */
199 static struct
200 Methods
201 {
202 const char
203 *name;
204
205 Arguments
206 arguments[MaxArguments];
207 } Methods[] =
208 {
209 { "Comment", { {"comment", StringReference} } },
210 { "Label", { {"label", StringReference} } },
211 { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
212 {"channel", MagickChannelOptions} } },
213 { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
214 { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
215 {"height", IntegerReference}, {"fill", StringReference},
216 {"bordercolor", StringReference}, {"color", StringReference},
217 {"compose", MagickComposeOptions} } },
218 { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
219 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
220 { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
221 {"height", IntegerReference}, {"x", IntegerReference},
222 {"y", IntegerReference}, {"gravity", MagickGravityOptions} } },
223 { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
224 {"height", IntegerReference}, {"x", IntegerReference},
225 {"y", IntegerReference}, {"fuzz", StringReference},
226 {"gravity", MagickGravityOptions} } },
227 { "Despeckle", { { (const char *) NULL, NullReference } } },
228 { "Edge", { {"radius", RealReference} } },
229 { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
230 {"sigma", RealReference} } },
231 { "Enhance", { { (const char *) NULL, NullReference } } },
232 { "Flip", { { (const char *) NULL, NullReference } } },
233 { "Flop", { { (const char *) NULL, NullReference } } },
234 { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
235 {"height", IntegerReference}, {"inner", IntegerReference},
236 {"outer", IntegerReference}, {"fill", StringReference},
237 {"color", StringReference}, {"compose", MagickComposeOptions} } },
238 { "Implode", { {"amount", RealReference},
239 {"interpolate", MagickInterpolateOptions} } },
240 { "Magnify", { { (const char *) NULL, NullReference } } },
241 { "MedianFilter", { {"geometry", StringReference},
242 {"width", IntegerReference}, {"height", IntegerReference},
243 {"channel", MagickChannelOptions} } },
244 { "Minify", { { (const char *) NULL, NullReference } } },
245 { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
246 { "ReduceNoise", { {"geometry", StringReference},
247 {"width", IntegerReference},{"height", IntegerReference},
248 {"channel", MagickChannelOptions} } },
249 { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
250 {"y", IntegerReference} } },
251 { "Rotate", { {"degrees", RealReference},
252 {"background", StringReference} } },
253 { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
254 {"height", IntegerReference} } },
255 { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
256 {"height", IntegerReference} } },
257 { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
258 {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
259 { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
260 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
261 { "Shear", { {"geometry", StringReference}, {"x", RealReference},
262 {"y", RealReference}, { "fill", StringReference},
263 {"color", StringReference} } },
264 { "Spread", { {"radius", RealReference},
265 {"interpolate", MagickInterpolateOptions} } },
266 { "Swirl", { {"degrees", RealReference},
267 {"interpolate", MagickInterpolateOptions} } },
268 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
269 {"height", IntegerReference}, {"filter", MagickFilterOptions},
270 {"support", StringReference } } },
271 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
272 {"height", IntegerReference}, {"filter", MagickFilterOptions},
273 {"support", RealReference } } },
274 { "Annotate", { {"text", StringReference}, {"font", StringReference},
275 {"pointsize", RealReference}, {"density", StringReference},
276 {"undercolor", StringReference}, {"stroke", StringReference},
277 {"fill", StringReference}, {"geometry", StringReference},
278 {"sans", 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 {"interline-spacing", RealReference},
290 {"interword-spacing", RealReference},
291 {"direction", MagickDirectionOptions},
292 {"decorate", MagickDecorateOptions} } },
293 { "ColorFloodfill", { {"geometry", StringReference},
294 {"x", IntegerReference}, {"y", IntegerReference},
295 {"fill", StringReference}, {"bordercolor", StringReference},
296 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
297 { "Composite", { {"image", ImageReference},
298 {"compose", MagickComposeOptions}, {"geometry", StringReference},
299 {"x", IntegerReference}, {"y", IntegerReference},
300 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
301 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
302 {"color", StringReference}, {"mask", ImageReference},
303 {"channel", MagickChannelOptions},
304 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
305 {"blend", StringReference}, {"clip-to-self", MagickBooleanOptions} } },
306 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
307 { "CycleColormap", { {"display", IntegerReference} } },
308 { "Draw", { {"primitive", MagickPrimitiveOptions},
309 {"points", StringReference}, {"method", MagickMethodOptions},
310 {"stroke", StringReference}, {"fill", StringReference},
311 {"strokewidth", RealReference}, {"font", StringReference},
312 {"bordercolor", StringReference}, {"x", RealReference},
313 {"y", RealReference}, {"translate", StringReference},
314 {"scale", StringReference}, {"rotate", RealReference},
315 {"skewX", RealReference}, {"skewY", RealReference},
316 {"tile", ImageReference}, {"pointsize", RealReference},
317 {"antialias", MagickBooleanOptions}, {"density", StringReference},
318 {"linewidth", RealReference}, {"affine", ArrayReference},
319 {"stroke-dashoffset", RealReference},
320 {"stroke-dasharray", ArrayReference},
321 {"interpolate", MagickInterpolateOptions},
322 {"origin", StringReference}, {"text", StringReference},
323 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
324 {"vector-graphics", StringReference}, {"kerning", RealReference},
325 {"interline-spacing", RealReference},
326 {"interword-spacing", RealReference},
327 {"direction", MagickDirectionOptions} } },
328 { "Equalize", { {"channel", MagickChannelOptions} } },
329 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
330 {"red", RealReference}, {"green", RealReference},
331 {"blue", RealReference} } },
332 { "Map", { {"image", ImageReference},
333 {"dither-method", MagickDitherOptions} } },
334 { "MatteFloodfill", { {"geometry", StringReference},
335 {"x", IntegerReference}, {"y", IntegerReference},
336 {"opacity", StringReference}, {"bordercolor", StringReference},
337 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
338 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
339 {"saturation", RealReference}, {"whiteness", RealReference},
340 {"brightness", RealReference}, {"lightness", RealReference},
341 {"blackness", RealReference} } },
342 { "Negate", { {"gray", MagickBooleanOptions},
343 {"channel", MagickChannelOptions} } },
344 { "Normalize", { {"channel", MagickChannelOptions} } },
345 { "NumberColors", { { (const char *) NULL, NullReference } } },
346 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
347 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
348 {"invert", MagickBooleanOptions} } },
349 { "Quantize", { {"colors", IntegerReference},
350 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
351 {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
352 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
353 {"dither-method", MagickDitherOptions} } },
354 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
355 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
356 { "Segment", { {"geometry", StringReference},
357 {"cluster-threshold", RealReference},
358 {"smoothing-threshold", RealReference},
359 {"colorspace", MagickColorspaceOptions},
360 {"verbose", MagickBooleanOptions} } },
361 { "Signature", { { (const char *) NULL, NullReference } } },
362 { "Solarize", { {"geometry", StringReference},
363 {"threshold", StringReference} } },
364 { "Sync", { { (const char *) NULL, NullReference } } },
365 { "Texture", { {"texture", ImageReference} } },
366 { "Evaluate", { {"value", RealReference},
367 {"operator", MagickEvaluateOptions},
368 {"channel", MagickChannelOptions} } },
369 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
370 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
371 { "Threshold", { {"threshold", StringReference},
372 {"channel", MagickChannelOptions} } },
373 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
374 {"sigma", RealReference} } },
375 { "Trim", { {"fuzz", StringReference} } },
376 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
377 {"wavelength", RealReference},
378 {"interpolate", MagickInterpolateOptions} } },
379 { "Separate", { {"channel", MagickChannelOptions} } },
380 { "Condense", { { (const char *) NULL, NullReference } } },
381 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
382 {"y", IntegerReference} } },
383 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
384 { "Deconstruct", { { (const char *) NULL, NullReference } } },
385 { "GaussianBlur", { {"geometry", StringReference},
386 {"radius", RealReference}, {"sigma", RealReference},
387 {"channel", MagickChannelOptions} } },
388 { "Convolve", { {"coefficients", ArrayReference},
389 {"channel", MagickChannelOptions}, {"bias", StringReference},
390 {"kernel", StringReference} } },
391 { "Profile", { {"name", StringReference}, {"profile", StringReference},
392 { "rendering-intent", MagickIntentOptions},
393 { "black-point-compensation", MagickBooleanOptions} } },
394 { "UnsharpMask", { {"geometry", StringReference},
395 {"radius", RealReference}, {"sigma", RealReference},
396 {"gain", RealReference}, {"threshold", RealReference},
397 {"channel", MagickChannelOptions} } },
398 { "MotionBlur", { {"geometry", StringReference},
399 {"radius", RealReference}, {"sigma", RealReference},
400 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
401 { "OrderedDither", { {"threshold", StringReference},
402 {"channel", MagickChannelOptions} } },
403 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
404 {"height", IntegerReference} } },
405 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
406 {"white-point", RealReference}, {"gamma", RealReference},
407 {"channel", MagickChannelOptions}, {"level", StringReference} } },
408 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
409 { "AffineTransform", { {"affine", ArrayReference},
410 {"translate", StringReference}, {"scale", StringReference},
411 {"rotate", RealReference}, {"skewX", RealReference},
412 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
413 {"background", StringReference} } },
414 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
415 { "AdaptiveThreshold", { {"geometry", StringReference},
416 {"width", IntegerReference}, {"height", IntegerReference},
417 {"bias", RealReference} } },
418 { "Resample", { {"density", StringReference}, {"x", RealReference},
419 {"y", RealReference}, {"filter", MagickFilterOptions},
420 {"support", RealReference } } },
421 { "Describe", { {"file", FileReference} } },
422 { "BlackThreshold", { {"threshold", StringReference},
423 {"channel", MagickChannelOptions} } },
424 { "WhiteThreshold", { {"threshold", StringReference},
425 {"channel", MagickChannelOptions} } },
426 { "RotationalBlur", { {"geometry", StringReference},
427 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
428 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
429 {"height", IntegerReference} } },
430 { "Strip", { { (const char *) NULL, NullReference } } },
431 { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
432 { "Channel", { {"channel", MagickChannelOptions} } },
433 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
434 {"height", IntegerReference}, {"x", IntegerReference},
435 {"y", IntegerReference}, {"fuzz", StringReference},
436 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
437 { "Posterize", { {"levels", IntegerReference},
438 {"dither", MagickBooleanOptions} } },
439 { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
440 {"sigma", RealReference}, {"x", IntegerReference},
441 {"y", IntegerReference} } },
442 { "Identify", { {"file", FileReference}, {"features", StringReference},
443 {"unique", MagickBooleanOptions} } },
444 { "SepiaTone", { {"threshold", RealReference} } },
445 { "SigmoidalContrast", { {"geometry", StringReference},
446 {"contrast", RealReference}, {"mid-point", RealReference},
447 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
448 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
449 {"height", IntegerReference}, {"x", IntegerReference},
450 {"y", IntegerReference}, {"fuzz", StringReference},
451 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
452 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
453 {"sigma", RealReference}, {"x", IntegerReference},
454 {"y", IntegerReference}, {"background", StringReference} } },
455 { "ContrastStretch", { {"levels", StringReference},
456 {"black-point", RealReference},{"white-point", RealReference},
457 {"channel", MagickChannelOptions} } },
458 { "Sans0", { { (const char *) NULL, NullReference } } },
459 { "Sans1", { { (const char *) NULL, NullReference } } },
460 { "AdaptiveSharpen", { {"geometry", StringReference},
461 {"radius", RealReference}, {"sigma", RealReference},
462 {"bias", RealReference}, {"channel", MagickChannelOptions} } },
463 { "Transpose", { { (const char *) NULL, NullReference } } },
464 { "Transverse", { { (const char *) NULL, NullReference } } },
465 { "AutoOrient", { { (const char *) NULL, NullReference } } },
466 { "AdaptiveBlur", { {"geometry", StringReference},
467 {"radius", RealReference}, {"sigma", RealReference},
468 {"channel", MagickChannelOptions} } },
469 { "Sketch", { {"geometry", StringReference},
470 {"radius", RealReference}, {"sigma", RealReference},
471 {"angle", RealReference} } },
472 { "UniqueColors", { { (const char *) NULL, NullReference } } },
473 { "AdaptiveResize", { {"geometry", StringReference},
474 {"width", IntegerReference}, {"height", IntegerReference},
475 {"filter", MagickFilterOptions}, {"support", StringReference },
476 {"blur", RealReference } } },
477 { "ClipMask", { {"mask", ImageReference} } },
478 { "LinearStretch", { {"levels", StringReference},
479 {"black-point", RealReference},{"white-point", RealReference} } },
480 { "ColorMatrix", { {"matrix", ArrayReference} } },
481 { "Mask", { {"mask", ImageReference} } },
482 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
483 {"font", StringReference}, {"stroke", StringReference},
484 {"fill", StringReference}, {"strokewidth", RealReference},
485 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
486 {"background", StringReference},
487 {"interpolate", MagickInterpolateOptions} } },
488 { "FloodfillPaint", { {"geometry", StringReference},
489 {"x", IntegerReference}, {"y", IntegerReference},
490 {"fill", StringReference}, {"bordercolor", StringReference},
491 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
492 {"invert", MagickBooleanOptions} } },
493 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
494 {"virtual-pixel", MagickVirtualPixelOptions},
495 {"best-fit", MagickBooleanOptions} } },
496 { "Clut", { {"image", ImageReference},
497 {"interpolate", MagickInterpolateOptions},
498 {"channel", MagickChannelOptions} } },
499 { "LiquidRescale", { {"geometry", StringReference},
500 {"width", IntegerReference}, {"height", IntegerReference},
501 {"delta-x", RealReference}, {"rigidity", RealReference } } },
502 { "Encipher", { {"passphrase", StringReference} } },
503 { "Decipher", { {"passphrase", StringReference} } },
504 { "Deskew", { {"geometry", StringReference},
505 {"threshold", StringReference} } },
506 { "Remap", { {"image", ImageReference},
507 {"dither-method", MagickDitherOptions} } },
508 { "SparseColor", { {"points", ArrayReference},
509 {"method", MagickSparseColorOptions},
510 {"virtual-pixel", MagickVirtualPixelOptions},
511 {"channel", MagickChannelOptions} } },
512 { "Function", { {"parameters", ArrayReference},
513 {"function", MagickFunctionOptions},
514 {"virtual-pixel", MagickVirtualPixelOptions} } },
515 { "SelectiveBlur", { {"geometry", StringReference},
516 {"radius", RealReference}, {"sigma", RealReference},
517 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
518 { "HaldClut", { {"image", ImageReference},
519 {"channel", MagickChannelOptions} } },
520 { "BlueShift", { {"factor", StringReference} } },
521 { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
522 { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
523 { "ColorDecisionList", {
524 {"color-correction-collection", StringReference} } },
525 { "AutoGamma", { {"channel", MagickChannelOptions} } },
526 { "AutoLevel", { {"channel", MagickChannelOptions} } },
527 { "LevelColors", { {"invert", MagickBooleanOptions},
528 {"black-point", StringReference}, {"white-point", StringReference},
529 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
530 { "Clamp", { {"channel", MagickChannelOptions} } },
531 { "BrightnessContrast", { {"levels", StringReference},
532 {"brightness", RealReference},{"contrast", RealReference},
533 {"channel", MagickChannelOptions} } },
534 { "Morphology", { {"kernel", StringReference},
535 {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
536 {"iterations", IntegerReference} } },
537 { "Mode", { {"geometry", StringReference},
538 {"width", IntegerReference},{"height", IntegerReference},
539 {"channel", MagickChannelOptions} } },
540 { "Statistic", { {"geometry", StringReference},
541 {"width", IntegerReference},{"height", IntegerReference},
542 {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
543 { "Perceptible", { {"epsilon", RealReference},
544 {"channel", MagickChannelOptions} } },
545 { "Poly", { {"terms", ArrayReference},
546 {"channel", MagickChannelOptions} } },
547 { "Grayscale", { {"method", MagickNoiseOptions} } },
548 { "CannyEdge", { {"geometry", StringReference},
549 {"radius", RealReference}, {"sigma", RealReference},
550 {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
551 { "HoughLine", { {"geometry", StringReference},
552 {"width", IntegerReference}, {"height", IntegerReference},
553 {"threshold", IntegerReference} } },
554 { "MeanShift", { {"geometry", StringReference},
555 {"width", IntegerReference}, {"height", IntegerReference},
556 {"distance", RealReference} } },
557 { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
558 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
559 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
560 { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
561 {"width", IntegerReference}, {"height", IntegerReference},
562 {"x", IntegerReference}, {"y", IntegerReference},
563 {"gravity", MagickGravityOptions}, {"offset", StringReference},
564 {"dx", IntegerReference}, {"dy", IntegerReference} } },
565 { "Color", { {"color", StringReference} } },
566 { "WaveletDenoise", { {"geometry", StringReference},
567 {"threshold", RealReference}, {"softness", RealReference},
568 {"channel", MagickChannelOptions} } },
569 { "Colorspace", { {"colorspace", MagickColorspaceOptions} } },
570 { "AutoThreshold", { {"method", MagickAutoThresholdOptions} } },
571 { "RangeThreshold", { {"geometry", StringReference},
572 {"low-black", RealReference}, {"low-white", RealReference},
573 {"high-white", RealReference}, {"high-black", RealReference},
574 {"channel", MagickChannelOptions} } },
575 { "CLAHE", { {"geometry", StringReference}, {"width", IntegerReference},
576 {"height", IntegerReference}, {"number-bins", IntegerReference},
577 {"clip-limit", RealReference} } },
578 { "Kmeans", { {"geometry", StringReference}, {"colors", IntegerReference},
579 {"iterations", IntegerReference}, {"tolerance", RealReference} } },
580 };
581
582 static SplayTreeInfo
583 *magick_registry = (SplayTreeInfo *) NULL;
584
585 /*
586 Forward declarations.
587 */
588 static Image
589 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
590
591 static ssize_t
592 strEQcase(const char *,const char *);
593
594 /*
595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
596 % %
597 % %
598 % %
599 % C l o n e P a c k a g e I n f o %
600 % %
601 % %
602 % %
603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604 %
605 % ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
606 % a new one.
607 %
608 % The format of the ClonePackageInfo routine is:
609 %
610 % struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
611 % exception)
612 %
613 % A description of each parameter follows:
614 %
615 % o info: a structure of type info.
616 %
617 % o exception: Return any errors or warnings in this structure.
618 %
619 */
ClonePackageInfo(struct PackageInfo * info,ExceptionInfo * exception)620 static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
621 ExceptionInfo *exception)
622 {
623 struct PackageInfo
624 *clone_info;
625
626 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
627 if (clone_info == (struct PackageInfo *) NULL)
628 {
629 ThrowPerlException(exception,ResourceLimitError,
630 "UnableToClonePackageInfo",PackageName);
631 return((struct PackageInfo *) NULL);
632 }
633 if (info == (struct PackageInfo *) NULL)
634 {
635 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
636 return(clone_info);
637 }
638 *clone_info=(*info);
639 clone_info->image_info=CloneImageInfo(info->image_info);
640 return(clone_info);
641 }
642
643 /*
644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645 % %
646 % %
647 % %
648 % c o n s t a n t %
649 % %
650 % %
651 % %
652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
653 %
654 % constant() returns a double value for the specified name.
655 %
656 % The format of the constant routine is:
657 %
658 % double constant(char *name,ssize_t sans)
659 %
660 % A description of each parameter follows:
661 %
662 % o value: Method constant returns a double value for the specified name.
663 %
664 % o name: The name of the constant.
665 %
666 % o sans: This integer value is not used.
667 %
668 */
constant(char * name,ssize_t sans)669 static double constant(char *name,ssize_t sans)
670 {
671 (void) sans;
672 errno=0;
673 switch (*name)
674 {
675 case 'B':
676 {
677 if (strEQ(name,"BlobError"))
678 return(BlobError);
679 if (strEQ(name,"BlobWarning"))
680 return(BlobWarning);
681 break;
682 }
683 case 'C':
684 {
685 if (strEQ(name,"CacheError"))
686 return(CacheError);
687 if (strEQ(name,"CacheWarning"))
688 return(CacheWarning);
689 if (strEQ(name,"CoderError"))
690 return(CoderError);
691 if (strEQ(name,"CoderWarning"))
692 return(CoderWarning);
693 if (strEQ(name,"ConfigureError"))
694 return(ConfigureError);
695 if (strEQ(name,"ConfigureWarning"))
696 return(ConfigureWarning);
697 if (strEQ(name,"CorruptImageError"))
698 return(CorruptImageError);
699 if (strEQ(name,"CorruptImageWarning"))
700 return(CorruptImageWarning);
701 break;
702 }
703 case 'D':
704 {
705 if (strEQ(name,"DelegateError"))
706 return(DelegateError);
707 if (strEQ(name,"DelegateWarning"))
708 return(DelegateWarning);
709 if (strEQ(name,"DrawError"))
710 return(DrawError);
711 if (strEQ(name,"DrawWarning"))
712 return(DrawWarning);
713 break;
714 }
715 case 'E':
716 {
717 if (strEQ(name,"ErrorException"))
718 return(ErrorException);
719 if (strEQ(name,"ExceptionError"))
720 return(CoderError);
721 if (strEQ(name,"ExceptionWarning"))
722 return(CoderWarning);
723 break;
724 }
725 case 'F':
726 {
727 if (strEQ(name,"FatalErrorException"))
728 return(FatalErrorException);
729 if (strEQ(name,"FileOpenError"))
730 return(FileOpenError);
731 if (strEQ(name,"FileOpenWarning"))
732 return(FileOpenWarning);
733 break;
734 }
735 case 'I':
736 {
737 if (strEQ(name,"ImageError"))
738 return(ImageError);
739 if (strEQ(name,"ImageWarning"))
740 return(ImageWarning);
741 break;
742 }
743 case 'M':
744 {
745 if (strEQ(name,"MaxRGB"))
746 return(QuantumRange);
747 if (strEQ(name,"MissingDelegateError"))
748 return(MissingDelegateError);
749 if (strEQ(name,"MissingDelegateWarning"))
750 return(MissingDelegateWarning);
751 if (strEQ(name,"ModuleError"))
752 return(ModuleError);
753 if (strEQ(name,"ModuleWarning"))
754 return(ModuleWarning);
755 break;
756 }
757 case 'O':
758 {
759 if (strEQ(name,"Opaque"))
760 return(OpaqueAlpha);
761 if (strEQ(name,"OptionError"))
762 return(OptionError);
763 if (strEQ(name,"OptionWarning"))
764 return(OptionWarning);
765 break;
766 }
767 case 'Q':
768 {
769 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
770 return(MAGICKCORE_QUANTUM_DEPTH);
771 if (strEQ(name,"QuantumDepth"))
772 return(MAGICKCORE_QUANTUM_DEPTH);
773 if (strEQ(name,"QuantumRange"))
774 return(QuantumRange);
775 break;
776 }
777 case 'R':
778 {
779 if (strEQ(name,"ResourceLimitError"))
780 return(ResourceLimitError);
781 if (strEQ(name,"ResourceLimitWarning"))
782 return(ResourceLimitWarning);
783 if (strEQ(name,"RegistryError"))
784 return(RegistryError);
785 if (strEQ(name,"RegistryWarning"))
786 return(RegistryWarning);
787 break;
788 }
789 case 'S':
790 {
791 if (strEQ(name,"StreamError"))
792 return(StreamError);
793 if (strEQ(name,"StreamWarning"))
794 return(StreamWarning);
795 if (strEQ(name,"Success"))
796 return(0);
797 break;
798 }
799 case 'T':
800 {
801 if (strEQ(name,"Transparent"))
802 return(TransparentAlpha);
803 if (strEQ(name,"TypeError"))
804 return(TypeError);
805 if (strEQ(name,"TypeWarning"))
806 return(TypeWarning);
807 break;
808 }
809 case 'W':
810 {
811 if (strEQ(name,"WarningException"))
812 return(WarningException);
813 break;
814 }
815 case 'X':
816 {
817 if (strEQ(name,"XServerError"))
818 return(XServerError);
819 if (strEQ(name,"XServerWarning"))
820 return(XServerWarning);
821 break;
822 }
823 }
824 errno=EINVAL;
825 return(0);
826 }
827
828 /*
829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
830 % %
831 % %
832 % %
833 % D e s t r o y P a c k a g e I n f o %
834 % %
835 % %
836 % %
837 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
838 %
839 % Method DestroyPackageInfo frees a previously created info structure.
840 %
841 % The format of the DestroyPackageInfo routine is:
842 %
843 % DestroyPackageInfo(struct PackageInfo *info)
844 %
845 % A description of each parameter follows:
846 %
847 % o info: a structure of type info.
848 %
849 */
DestroyPackageInfo(struct PackageInfo * info)850 static void DestroyPackageInfo(struct PackageInfo *info)
851 {
852 info->image_info=DestroyImageInfo(info->image_info);
853 info=(struct PackageInfo *) RelinquishMagickMemory(info);
854 }
855
856 /*
857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
858 % %
859 % %
860 % %
861 % G e t L i s t %
862 % %
863 % %
864 % %
865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
866 %
867 % Method GetList is recursively called by SetupList to traverse the
868 % Image__Magick reference. If building an reference_vector (see SetupList),
869 % *current is the current position in *reference_vector and *last is the final
870 % entry in *reference_vector.
871 %
872 % The format of the GetList routine is:
873 %
874 % GetList(info)
875 %
876 % A description of each parameter follows:
877 %
878 % o info: a structure of type info.
879 %
880 */
GetList(pTHX_ SV * reference,SV *** reference_vector,ssize_t * current,ssize_t * last,ExceptionInfo * exception)881 static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
882 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
883 {
884 Image
885 *image;
886
887 if (reference == (SV *) NULL)
888 return(NULL);
889 switch (SvTYPE(reference))
890 {
891 case SVt_PVAV:
892 {
893 AV
894 *av;
895
896 Image
897 *head,
898 *previous;
899
900 register ssize_t
901 i;
902
903 ssize_t
904 n;
905
906 /*
907 Array of images.
908 */
909 previous=(Image *) NULL;
910 head=(Image *) NULL;
911 av=(AV *) reference;
912 n=av_len(av);
913 for (i=0; i <= n; i++)
914 {
915 SV
916 **rv;
917
918 rv=av_fetch(av,i,0);
919 if (rv && *rv && sv_isobject(*rv))
920 {
921 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
922 exception);
923 if (image == (Image *) NULL)
924 continue;
925 if (image == previous)
926 {
927 image=CloneImage(image,0,0,MagickTrue,exception);
928 if (image == (Image *) NULL)
929 return(NULL);
930 }
931 image->previous=previous;
932 *(previous ? &previous->next : &head)=image;
933 for (previous=image; previous->next; previous=previous->next) ;
934 }
935 }
936 return(head);
937 }
938 case SVt_PVMG:
939 {
940 /*
941 Blessed scalar, one image.
942 */
943 image=INT2PTR(Image *,SvIV(reference));
944 if (image == (Image *) NULL)
945 return(NULL);
946 image->previous=(Image *) NULL;
947 image->next=(Image *) NULL;
948 if (reference_vector)
949 {
950 if (*current == *last)
951 {
952 *last+=256;
953 if (*reference_vector == (SV **) NULL)
954 *reference_vector=(SV **) AcquireQuantumMemory(*last,
955 sizeof(*reference_vector));
956 else
957 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
958 *last,sizeof(*reference_vector));
959 }
960 if (*reference_vector == (SV **) NULL)
961 {
962 ThrowPerlException(exception,ResourceLimitError,
963 "MemoryAllocationFailed",PackageName);
964 return((Image *) NULL);
965 }
966 (*reference_vector)[*current]=reference;
967 (*reference_vector)[++(*current)]=NULL;
968 }
969 return(image);
970 }
971 default:
972 break;
973 }
974 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
975 (double) SvTYPE(reference));
976 return((Image *) NULL);
977 }
978
979 /*
980 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
981 % %
982 % %
983 % %
984 % G e t P a c k a g e I n f o %
985 % %
986 % %
987 % %
988 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
989 %
990 % Method GetPackageInfo looks up or creates an info structure for the given
991 % Image__Magick reference. If it does create a new one, the information in
992 % package_info is used to initialize it.
993 %
994 % The format of the GetPackageInfo routine is:
995 %
996 % struct PackageInfo *GetPackageInfo(void *reference,
997 % struct PackageInfo *package_info,ExceptionInfo *exception)
998 %
999 % A description of each parameter follows:
1000 %
1001 % o info: a structure of type info.
1002 %
1003 % o exception: Return any errors or warnings in this structure.
1004 %
1005 */
GetPackageInfo(pTHX_ void * reference,struct PackageInfo * package_info,ExceptionInfo * exception)1006 static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
1007 struct PackageInfo *package_info,ExceptionInfo *exception)
1008 {
1009 char
1010 message[MagickPathExtent];
1011
1012 struct PackageInfo
1013 *clone_info;
1014
1015 SV
1016 *sv;
1017
1018 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
1019 PackageName,XS_VERSION,reference);
1020 sv=perl_get_sv(message,(TRUE | 0x02));
1021 if (sv == (SV *) NULL)
1022 {
1023 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1024 message);
1025 return(package_info);
1026 }
1027 if (SvREFCNT(sv) == 0)
1028 (void) SvREFCNT_inc(sv);
1029 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1030 return(clone_info);
1031 clone_info=ClonePackageInfo(package_info,exception);
1032 sv_setiv(sv,PTR2IV(clone_info));
1033 return(clone_info);
1034 }
1035
1036 /*
1037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1038 % %
1039 % %
1040 % %
1041 % S e t A t t r i b u t e %
1042 % %
1043 % %
1044 % %
1045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1046 %
1047 % SetAttribute() sets the attribute to the value in sval. This can change
1048 % either or both of image or info.
1049 %
1050 % The format of the SetAttribute routine is:
1051 %
1052 % SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1053 % SV *sval,ExceptionInfo *exception)
1054 %
1055 % A description of each parameter follows:
1056 %
1057 % o list: a list of strings.
1058 %
1059 % o string: a character string.
1060 %
1061 */
1062
SiPrefixToDoubleInterval(const char * string,const double interval)1063 static double SiPrefixToDoubleInterval(const char *string,const double interval)
1064 {
1065 char
1066 *q;
1067
1068 double
1069 value;
1070
1071 value=InterpretSiPrefixValue(string,&q);
1072 if (*q == '%')
1073 value*=interval/100.0;
1074 return(value);
1075 }
1076
StringToDouble(const char * string,char ** sentinal)1077 static inline double StringToDouble(const char *string,char **sentinal)
1078 {
1079 return(InterpretLocaleValue(string,sentinal));
1080 }
1081
StringToDoubleInterval(const char * string,const double interval)1082 static double StringToDoubleInterval(const char *string,const double interval)
1083 {
1084 char
1085 *q;
1086
1087 double
1088 value;
1089
1090 value=InterpretLocaleValue(string,&q);
1091 if (*q == '%')
1092 value*=interval/100.0;
1093 return(value);
1094 }
1095
StringToLong(const char * value)1096 static inline ssize_t StringToLong(const char *value)
1097 {
1098 return(strtol(value,(char **) NULL,10));
1099 }
1100
SetAttribute(pTHX_ struct PackageInfo * info,Image * image,const char * attribute,SV * sval,ExceptionInfo * exception)1101 static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1102 const char *attribute,SV *sval,ExceptionInfo *exception)
1103 {
1104 GeometryInfo
1105 geometry_info;
1106
1107 long
1108 x,
1109 y;
1110
1111 PixelInfo
1112 pixel;
1113
1114 MagickStatusType
1115 flags;
1116
1117 PixelInfo
1118 *color,
1119 target_color;
1120
1121 ssize_t
1122 sp;
1123
1124 switch (*attribute)
1125 {
1126 case 'A':
1127 case 'a':
1128 {
1129 if (LocaleCompare(attribute,"adjoin") == 0)
1130 {
1131 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1132 SvPV(sval,na)) : SvIV(sval);
1133 if (sp < 0)
1134 {
1135 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1136 SvPV(sval,na));
1137 break;
1138 }
1139 if (info)
1140 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1141 break;
1142 }
1143 if (LocaleCompare(attribute,"alpha") == 0)
1144 {
1145 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1146 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1147 if (sp < 0)
1148 {
1149 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1150 SvPV(sval,na));
1151 break;
1152 }
1153 for ( ; image; image=image->next)
1154 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1155 exception);
1156 break;
1157 }
1158 if (LocaleCompare(attribute,"antialias") == 0)
1159 {
1160 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1161 SvPV(sval,na)) : SvIV(sval);
1162 if (sp < 0)
1163 {
1164 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1165 SvPV(sval,na));
1166 break;
1167 }
1168 if (info)
1169 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1170 break;
1171 }
1172 if (LocaleCompare(attribute,"area-limit") == 0)
1173 {
1174 MagickSizeType
1175 limit;
1176
1177 limit=MagickResourceInfinity;
1178 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1179 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1180 100.0);
1181 (void) SetMagickResourceLimit(AreaResource,limit);
1182 break;
1183 }
1184 if (LocaleCompare(attribute,"attenuate") == 0)
1185 {
1186 if (info)
1187 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1188 break;
1189 }
1190 if (LocaleCompare(attribute,"authenticate") == 0)
1191 {
1192 if (info)
1193 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1194 break;
1195 }
1196 if (info)
1197 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1198 for ( ; image; image=image->next)
1199 {
1200 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1201 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1202 }
1203 break;
1204 }
1205 case 'B':
1206 case 'b':
1207 {
1208 if (LocaleCompare(attribute,"background") == 0)
1209 {
1210 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1211 exception);
1212 if (info)
1213 info->image_info->background_color=target_color;
1214 for ( ; image; image=image->next)
1215 image->background_color=target_color;
1216 break;
1217 }
1218 if (LocaleCompare(attribute,"blue-primary") == 0)
1219 {
1220 for ( ; image; image=image->next)
1221 {
1222 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1223 image->chromaticity.blue_primary.x=geometry_info.rho;
1224 image->chromaticity.blue_primary.y=geometry_info.sigma;
1225 if ((flags & SigmaValue) == 0)
1226 image->chromaticity.blue_primary.y=
1227 image->chromaticity.blue_primary.x;
1228 }
1229 break;
1230 }
1231 if (LocaleCompare(attribute,"bordercolor") == 0)
1232 {
1233 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1234 exception);
1235 if (info)
1236 info->image_info->border_color=target_color;
1237 for ( ; image; image=image->next)
1238 image->border_color=target_color;
1239 break;
1240 }
1241 if (info)
1242 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1243 for ( ; image; image=image->next)
1244 {
1245 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1246 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1247 }
1248 break;
1249 }
1250 case 'C':
1251 case 'c':
1252 {
1253 if (LocaleCompare(attribute,"cache-threshold") == 0)
1254 {
1255 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1256 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1257 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1258 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1259 break;
1260 }
1261 if (LocaleCompare(attribute,"clip-mask") == 0)
1262 {
1263 Image
1264 *clip_mask;
1265
1266 clip_mask=(Image *) NULL;
1267 if (SvPOK(sval))
1268 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1269 for ( ; image; image=image->next)
1270 SetImageMask(image,ReadPixelMask,clip_mask,exception);
1271 break;
1272 }
1273 if (LocaleNCompare(attribute,"colormap",8) == 0)
1274 {
1275 for ( ; image; image=image->next)
1276 {
1277 int
1278 items;
1279
1280 long
1281 i;
1282
1283 if (image->storage_class == DirectClass)
1284 continue;
1285 i=0;
1286 items=sscanf(attribute,"%*[^[][%ld",&i);
1287 (void) items;
1288 if (i > (ssize_t) image->colors)
1289 i%=image->colors;
1290 if ((strchr(SvPV(sval,na),',') == 0) ||
1291 (strchr(SvPV(sval,na),')') != 0))
1292 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1293 image->colormap+i,exception);
1294 else
1295 {
1296 color=image->colormap+i;
1297 pixel.red=color->red;
1298 pixel.green=color->green;
1299 pixel.blue=color->blue;
1300 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1301 pixel.red=geometry_info.rho;
1302 pixel.green=geometry_info.sigma;
1303 pixel.blue=geometry_info.xi;
1304 color->red=ClampToQuantum(pixel.red);
1305 color->green=ClampToQuantum(pixel.green);
1306 color->blue=ClampToQuantum(pixel.blue);
1307 }
1308 }
1309 break;
1310 }
1311 if (LocaleCompare(attribute,"colorspace") == 0)
1312 {
1313 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1314 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1315 if (sp < 0)
1316 {
1317 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1318 SvPV(sval,na));
1319 break;
1320 }
1321 for ( ; image; image=image->next)
1322 (void) SetImageColorspace(image,(ColorspaceType) sp,exception);
1323 break;
1324 }
1325 if (LocaleCompare(attribute,"comment") == 0)
1326 {
1327 for ( ; image; image=image->next)
1328 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1329 info ? info->image_info : (ImageInfo *) NULL,image,
1330 SvPV(sval,na),exception),exception);
1331 break;
1332 }
1333 if (LocaleCompare(attribute,"compression") == 0)
1334 {
1335 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1336 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1337 if (sp < 0)
1338 {
1339 ThrowPerlException(exception,OptionError,
1340 "UnrecognizedImageCompression",SvPV(sval,na));
1341 break;
1342 }
1343 if (info)
1344 info->image_info->compression=(CompressionType) sp;
1345 for ( ; image; image=image->next)
1346 image->compression=(CompressionType) sp;
1347 break;
1348 }
1349 if (info)
1350 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1351 for ( ; image; image=image->next)
1352 {
1353 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1354 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1355 }
1356 break;
1357 }
1358 case 'D':
1359 case 'd':
1360 {
1361 if (LocaleCompare(attribute,"debug") == 0)
1362 {
1363 SetLogEventMask(SvPV(sval,na));
1364 break;
1365 }
1366 if (LocaleCompare(attribute,"delay") == 0)
1367 {
1368 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1369 for ( ; image; image=image->next)
1370 {
1371 image->delay=(size_t) floor(geometry_info.rho+0.5);
1372 if ((flags & SigmaValue) != 0)
1373 image->ticks_per_second=(ssize_t)
1374 floor(geometry_info.sigma+0.5);
1375 }
1376 break;
1377 }
1378 if (LocaleCompare(attribute,"disk-limit") == 0)
1379 {
1380 MagickSizeType
1381 limit;
1382
1383 limit=MagickResourceInfinity;
1384 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1385 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1386 100.0);
1387 (void) SetMagickResourceLimit(DiskResource,limit);
1388 break;
1389 }
1390 if (LocaleCompare(attribute,"density") == 0)
1391 {
1392 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1393 {
1394 ThrowPerlException(exception,OptionError,"MissingGeometry",
1395 SvPV(sval,na));
1396 break;
1397 }
1398 if (info)
1399 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1400 for ( ; image; image=image->next)
1401 {
1402 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1403 image->resolution.x=geometry_info.rho;
1404 image->resolution.y=geometry_info.sigma;
1405 if ((flags & SigmaValue) == 0)
1406 image->resolution.y=image->resolution.x;
1407 }
1408 break;
1409 }
1410 if (LocaleCompare(attribute,"depth") == 0)
1411 {
1412 if (info)
1413 info->image_info->depth=SvIV(sval);
1414 for ( ; image; image=image->next)
1415 (void) SetImageDepth(image,SvIV(sval),exception);
1416 break;
1417 }
1418 if (LocaleCompare(attribute,"dispose") == 0)
1419 {
1420 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1421 SvPV(sval,na)) : SvIV(sval);
1422 if (sp < 0)
1423 {
1424 ThrowPerlException(exception,OptionError,
1425 "UnrecognizedDisposeMethod",SvPV(sval,na));
1426 break;
1427 }
1428 for ( ; image; image=image->next)
1429 image->dispose=(DisposeType) sp;
1430 break;
1431 }
1432 if (LocaleCompare(attribute,"dither") == 0)
1433 {
1434 if (info)
1435 {
1436 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1437 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1438 if (sp < 0)
1439 {
1440 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1441 SvPV(sval,na));
1442 break;
1443 }
1444 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1445 }
1446 break;
1447 }
1448 if (LocaleCompare(attribute,"display") == 0)
1449 {
1450 display:
1451 if (info)
1452 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1453 break;
1454 }
1455 if (info)
1456 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1457 for ( ; image; image=image->next)
1458 {
1459 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1460 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1461 }
1462 break;
1463 }
1464 case 'E':
1465 case 'e':
1466 {
1467 if (LocaleCompare(attribute,"endian") == 0)
1468 {
1469 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1470 SvPV(sval,na)) : SvIV(sval);
1471 if (sp < 0)
1472 {
1473 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1474 SvPV(sval,na));
1475 break;
1476 }
1477 if (info)
1478 info->image_info->endian=(EndianType) sp;
1479 for ( ; image; image=image->next)
1480 image->endian=(EndianType) sp;
1481 break;
1482 }
1483 if (LocaleCompare(attribute,"extract") == 0)
1484 {
1485 /*
1486 Set image extract geometry.
1487 */
1488 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1489 break;
1490 }
1491 if (info)
1492 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1493 for ( ; image; image=image->next)
1494 {
1495 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1496 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1497 }
1498 break;
1499 }
1500 case 'F':
1501 case 'f':
1502 {
1503 if (LocaleCompare(attribute,"filename") == 0)
1504 {
1505 if (info)
1506 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
1507 MagickPathExtent);
1508 for ( ; image; image=image->next)
1509 (void) CopyMagickString(image->filename,SvPV(sval,na),
1510 MagickPathExtent);
1511 break;
1512 }
1513 if (LocaleCompare(attribute,"file") == 0)
1514 {
1515 FILE
1516 *file;
1517
1518 PerlIO
1519 *io_info;
1520
1521 if (info == (struct PackageInfo *) NULL)
1522 break;
1523 io_info=IoIFP(sv_2io(sval));
1524 if (io_info == (PerlIO *) NULL)
1525 {
1526 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1527 PackageName);
1528 break;
1529 }
1530 file=PerlIO_findFILE(io_info);
1531 if (file == (FILE *) NULL)
1532 {
1533 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1534 PackageName);
1535 break;
1536 }
1537 SetImageInfoFile(info->image_info,file);
1538 break;
1539 }
1540 if (LocaleCompare(attribute,"fill") == 0)
1541 {
1542 if (info)
1543 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1544 break;
1545 }
1546 if (LocaleCompare(attribute,"font") == 0)
1547 {
1548 if (info)
1549 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1550 break;
1551 }
1552 if (LocaleCompare(attribute,"foreground") == 0)
1553 break;
1554 if (LocaleCompare(attribute,"fuzz") == 0)
1555 {
1556 if (info)
1557 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1558 QuantumRange+1.0);
1559 for ( ; image; image=image->next)
1560 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1561 QuantumRange+1.0);
1562 break;
1563 }
1564 if (info)
1565 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1566 for ( ; image; image=image->next)
1567 {
1568 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1569 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1570 }
1571 break;
1572 }
1573 case 'G':
1574 case 'g':
1575 {
1576 if (LocaleCompare(attribute,"gamma") == 0)
1577 {
1578 for ( ; image; image=image->next)
1579 image->gamma=SvNV(sval);
1580 break;
1581 }
1582 if (LocaleCompare(attribute,"gravity") == 0)
1583 {
1584 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1585 SvPV(sval,na)) : SvIV(sval);
1586 if (sp < 0)
1587 {
1588 ThrowPerlException(exception,OptionError,
1589 "UnrecognizedGravityType",SvPV(sval,na));
1590 break;
1591 }
1592 if (info)
1593 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1594 for ( ; image; image=image->next)
1595 image->gravity=(GravityType) sp;
1596 break;
1597 }
1598 if (LocaleCompare(attribute,"green-primary") == 0)
1599 {
1600 for ( ; image; image=image->next)
1601 {
1602 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1603 image->chromaticity.green_primary.x=geometry_info.rho;
1604 image->chromaticity.green_primary.y=geometry_info.sigma;
1605 if ((flags & SigmaValue) == 0)
1606 image->chromaticity.green_primary.y=
1607 image->chromaticity.green_primary.x;
1608 }
1609 break;
1610 }
1611 if (info)
1612 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1613 for ( ; image; image=image->next)
1614 {
1615 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1616 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1617 }
1618 break;
1619 }
1620 case 'I':
1621 case 'i':
1622 {
1623 if (LocaleNCompare(attribute,"index",5) == 0)
1624 {
1625 int
1626 items;
1627
1628 long
1629 index;
1630
1631 register Quantum
1632 *q;
1633
1634 CacheView
1635 *image_view;
1636
1637 for ( ; image; image=image->next)
1638 {
1639 if (image->storage_class != PseudoClass)
1640 continue;
1641 x=0;
1642 y=0;
1643 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1644 (void) items;
1645 image_view=AcquireAuthenticCacheView(image,exception);
1646 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1647 if (q != (Quantum *) NULL)
1648 {
1649 items=sscanf(SvPV(sval,na),"%ld",&index);
1650 if ((index >= 0) && (index < (ssize_t) image->colors))
1651 SetPixelIndex(image,index,q);
1652 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1653 }
1654 image_view=DestroyCacheView(image_view);
1655 }
1656 break;
1657 }
1658 if (LocaleCompare(attribute,"iterations") == 0)
1659 {
1660 iterations:
1661 for ( ; image; image=image->next)
1662 image->iterations=SvIV(sval);
1663 break;
1664 }
1665 if (LocaleCompare(attribute,"interlace") == 0)
1666 {
1667 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1668 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1669 if (sp < 0)
1670 {
1671 ThrowPerlException(exception,OptionError,
1672 "UnrecognizedInterlaceType",SvPV(sval,na));
1673 break;
1674 }
1675 if (info)
1676 info->image_info->interlace=(InterlaceType) sp;
1677 for ( ; image; image=image->next)
1678 image->interlace=(InterlaceType) sp;
1679 break;
1680 }
1681 if (info)
1682 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1683 for ( ; image; image=image->next)
1684 {
1685 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1686 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1687 }
1688 break;
1689 }
1690 case 'L':
1691 case 'l':
1692 {
1693 if (LocaleCompare(attribute,"label") == 0)
1694 {
1695 for ( ; image; image=image->next)
1696 (void) SetImageProperty(image,"label",InterpretImageProperties(
1697 info ? info->image_info : (ImageInfo *) NULL,image,
1698 SvPV(sval,na),exception),exception);
1699 break;
1700 }
1701 if (LocaleCompare(attribute,"loop") == 0)
1702 goto iterations;
1703 if (info)
1704 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1705 for ( ; image; image=image->next)
1706 {
1707 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1708 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1709 }
1710 break;
1711 }
1712 case 'M':
1713 case 'm':
1714 {
1715 if (LocaleCompare(attribute,"magick") == 0)
1716 {
1717 if (info)
1718 (void) FormatLocaleString(info->image_info->filename,
1719 MagickPathExtent,"%s:",SvPV(sval,na));
1720 for ( ; image; image=image->next)
1721 (void) CopyMagickString(image->magick,SvPV(sval,na),
1722 MagickPathExtent);
1723 break;
1724 }
1725 if (LocaleCompare(attribute,"map-limit") == 0)
1726 {
1727 MagickSizeType
1728 limit;
1729
1730 limit=MagickResourceInfinity;
1731 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1732 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1733 100.0);
1734 (void) SetMagickResourceLimit(MapResource,limit);
1735 break;
1736 }
1737 if (LocaleCompare(attribute,"mask") == 0)
1738 {
1739 Image
1740 *mask;
1741
1742 mask=(Image *) NULL;
1743 if (SvPOK(sval))
1744 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1745 for ( ; image; image=image->next)
1746 SetImageMask(image,ReadPixelMask,mask,exception);
1747 break;
1748 }
1749 if (LocaleCompare(attribute,"mattecolor") == 0)
1750 {
1751 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1752 exception);
1753 if (info)
1754 info->image_info->alpha_color=target_color;
1755 for ( ; image; image=image->next)
1756 image->alpha_color=target_color;
1757 break;
1758 }
1759 if (LocaleCompare(attribute,"matte") == 0)
1760 {
1761 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1762 SvPV(sval,na)) : SvIV(sval);
1763 if (sp < 0)
1764 {
1765 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1766 SvPV(sval,na));
1767 break;
1768 }
1769 for ( ; image; image=image->next)
1770 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1771 break;
1772 }
1773 if (LocaleCompare(attribute,"memory-limit") == 0)
1774 {
1775 MagickSizeType
1776 limit;
1777
1778 limit=MagickResourceInfinity;
1779 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1780 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1781 100.0);
1782 (void) SetMagickResourceLimit(MemoryResource,limit);
1783 break;
1784 }
1785 if (LocaleCompare(attribute,"monochrome") == 0)
1786 {
1787 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1788 SvPV(sval,na)) : SvIV(sval);
1789 if (sp < 0)
1790 {
1791 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1792 SvPV(sval,na));
1793 break;
1794 }
1795 if (info)
1796 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1797 for ( ; image; image=image->next)
1798 (void) SetImageType(image,BilevelType,exception);
1799 break;
1800 }
1801 if (info)
1802 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1803 for ( ; image; image=image->next)
1804 {
1805 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1806 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1807 }
1808 break;
1809 }
1810 case 'O':
1811 case 'o':
1812 {
1813 if (LocaleCompare(attribute,"option") == 0)
1814 {
1815 if (info)
1816 DefineImageOption(info->image_info,SvPV(sval,na));
1817 break;
1818 }
1819 if (LocaleCompare(attribute,"orientation") == 0)
1820 {
1821 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1822 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1823 if (sp < 0)
1824 {
1825 ThrowPerlException(exception,OptionError,
1826 "UnrecognizedOrientationType",SvPV(sval,na));
1827 break;
1828 }
1829 if (info)
1830 info->image_info->orientation=(OrientationType) sp;
1831 for ( ; image; image=image->next)
1832 image->orientation=(OrientationType) sp;
1833 break;
1834 }
1835 if (info)
1836 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1837 for ( ; image; image=image->next)
1838 {
1839 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1840 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1841 }
1842 break;
1843 }
1844 case 'P':
1845 case 'p':
1846 {
1847 if (LocaleCompare(attribute,"page") == 0)
1848 {
1849 char
1850 *geometry;
1851
1852 geometry=GetPageGeometry(SvPV(sval,na));
1853 if (info)
1854 (void) CloneString(&info->image_info->page,geometry);
1855 for ( ; image; image=image->next)
1856 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1857 geometry=(char *) RelinquishMagickMemory(geometry);
1858 break;
1859 }
1860 if (LocaleNCompare(attribute,"pixel",5) == 0)
1861 {
1862 int
1863 items;
1864
1865 PixelInfo
1866 pixel;
1867
1868 register Quantum
1869 *q;
1870
1871 CacheView
1872 *image_view;
1873
1874 for ( ; image; image=image->next)
1875 {
1876 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1877 break;
1878 x=0;
1879 y=0;
1880 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1881 (void) items;
1882 image_view=AcquireVirtualCacheView(image,exception);
1883 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1884 if (q != (Quantum *) NULL)
1885 {
1886 if ((strchr(SvPV(sval,na),',') == 0) ||
1887 (strchr(SvPV(sval,na),')') != 0))
1888 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1889 &pixel,exception);
1890 else
1891 {
1892 GetPixelInfo(image,&pixel);
1893 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1894 pixel.red=geometry_info.rho;
1895 if ((flags & SigmaValue) != 0)
1896 pixel.green=geometry_info.sigma;
1897 if ((flags & XiValue) != 0)
1898 pixel.blue=geometry_info.xi;
1899 if ((flags & PsiValue) != 0)
1900 pixel.alpha=geometry_info.psi;
1901 if ((flags & ChiValue) != 0)
1902 pixel.black=geometry_info.chi;
1903 }
1904 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1905 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1906 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1907 if (image->colorspace == CMYKColorspace)
1908 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1909 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1910 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1911 }
1912 image_view=DestroyCacheView(image_view);
1913 }
1914 break;
1915 }
1916 if (LocaleCompare(attribute,"pointsize") == 0)
1917 {
1918 if (info)
1919 {
1920 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1921 info->image_info->pointsize=geometry_info.rho;
1922 }
1923 break;
1924 }
1925 if (info)
1926 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1927 for ( ; image; image=image->next)
1928 {
1929 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1930 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1931 }
1932 break;
1933 }
1934 case 'Q':
1935 case 'q':
1936 {
1937 if (LocaleCompare(attribute,"quality") == 0)
1938 {
1939 if (info)
1940 info->image_info->quality=SvIV(sval);
1941 for ( ; image; image=image->next)
1942 image->quality=SvIV(sval);
1943 break;
1944 }
1945 if (info)
1946 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1947 for ( ; image; image=image->next)
1948 {
1949 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1950 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1951 }
1952 break;
1953 }
1954 case 'R':
1955 case 'r':
1956 {
1957 if (LocaleCompare(attribute,"read-mask") == 0)
1958 {
1959 Image
1960 *mask;
1961
1962 mask=(Image *) NULL;
1963 if (SvPOK(sval))
1964 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1965 for ( ; image; image=image->next)
1966 SetImageMask(image,ReadPixelMask,mask,exception);
1967 break;
1968 }
1969 if (LocaleCompare(attribute,"red-primary") == 0)
1970 {
1971 for ( ; image; image=image->next)
1972 {
1973 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1974 image->chromaticity.red_primary.x=geometry_info.rho;
1975 image->chromaticity.red_primary.y=geometry_info.sigma;
1976 if ((flags & SigmaValue) == 0)
1977 image->chromaticity.red_primary.y=
1978 image->chromaticity.red_primary.x;
1979 }
1980 break;
1981 }
1982 if (LocaleCompare(attribute,"render") == 0)
1983 {
1984 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1985 SvPV(sval,na)) : SvIV(sval);
1986 if (sp < 0)
1987 {
1988 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1989 SvPV(sval,na));
1990 break;
1991 }
1992 for ( ; image; image=image->next)
1993 image->rendering_intent=(RenderingIntent) sp;
1994 break;
1995 }
1996 if (LocaleCompare(attribute,"repage") == 0)
1997 {
1998 RectangleInfo
1999 geometry;
2000
2001 for ( ; image; image=image->next)
2002 {
2003 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
2004 if ((flags & WidthValue) != 0)
2005 {
2006 if ((flags & HeightValue) == 0)
2007 geometry.height=geometry.width;
2008 image->page.width=geometry.width;
2009 image->page.height=geometry.height;
2010 }
2011 if ((flags & AspectValue) != 0)
2012 {
2013 if ((flags & XValue) != 0)
2014 image->page.x+=geometry.x;
2015 if ((flags & YValue) != 0)
2016 image->page.y+=geometry.y;
2017 }
2018 else
2019 {
2020 if ((flags & XValue) != 0)
2021 {
2022 image->page.x=geometry.x;
2023 if (((flags & WidthValue) != 0) && (geometry.x > 0))
2024 image->page.width=image->columns+geometry.x;
2025 }
2026 if ((flags & YValue) != 0)
2027 {
2028 image->page.y=geometry.y;
2029 if (((flags & HeightValue) != 0) && (geometry.y > 0))
2030 image->page.height=image->rows+geometry.y;
2031 }
2032 }
2033 }
2034 break;
2035 }
2036 if (info)
2037 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2038 for ( ; image; image=image->next)
2039 {
2040 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2041 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2042 }
2043 break;
2044 }
2045 case 'S':
2046 case 's':
2047 {
2048 if (LocaleCompare(attribute,"sampling-factor") == 0)
2049 {
2050 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2051 {
2052 ThrowPerlException(exception,OptionError,"MissingGeometry",
2053 SvPV(sval,na));
2054 break;
2055 }
2056 if (info)
2057 (void) CloneString(&info->image_info->sampling_factor,
2058 SvPV(sval,na));
2059 break;
2060 }
2061 if (LocaleCompare(attribute,"scene") == 0)
2062 {
2063 for ( ; image; image=image->next)
2064 image->scene=SvIV(sval);
2065 break;
2066 }
2067 if (LocaleCompare(attribute,"server") == 0)
2068 goto display;
2069 if (LocaleCompare(attribute,"size") == 0)
2070 {
2071 if (info)
2072 {
2073 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2074 {
2075 ThrowPerlException(exception,OptionError,"MissingGeometry",
2076 SvPV(sval,na));
2077 break;
2078 }
2079 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2080 }
2081 break;
2082 }
2083 if (LocaleCompare(attribute,"stroke") == 0)
2084 {
2085 if (info)
2086 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2087 break;
2088 }
2089 if (info)
2090 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2091 for ( ; image; image=image->next)
2092 {
2093 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2094 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2095 }
2096 break;
2097 }
2098 case 'T':
2099 case 't':
2100 {
2101 if (LocaleCompare(attribute,"texture") == 0)
2102 {
2103 if (info)
2104 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2105 break;
2106 }
2107 if (LocaleCompare(attribute,"thread-limit") == 0)
2108 {
2109 MagickSizeType
2110 limit;
2111
2112 limit=MagickResourceInfinity;
2113 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2114 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2115 100.0);
2116 (void) SetMagickResourceLimit(ThreadResource,limit);
2117 break;
2118 }
2119 if (LocaleCompare(attribute,"tile-offset") == 0)
2120 {
2121 char
2122 *geometry;
2123
2124 geometry=GetPageGeometry(SvPV(sval,na));
2125 if (info)
2126 (void) CloneString(&info->image_info->page,geometry);
2127 for ( ; image; image=image->next)
2128 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2129 exception);
2130 geometry=(char *) RelinquishMagickMemory(geometry);
2131 break;
2132 }
2133 if (LocaleCompare(attribute,"time-limit") == 0)
2134 {
2135 MagickSizeType
2136 limit;
2137
2138 limit=MagickResourceInfinity;
2139 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2140 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2141 100.0);
2142 (void) SetMagickResourceLimit(TimeResource,limit);
2143 break;
2144 }
2145 if (LocaleCompare(attribute,"transparent-color") == 0)
2146 {
2147 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2148 exception);
2149 if (info)
2150 info->image_info->transparent_color=target_color;
2151 for ( ; image; image=image->next)
2152 image->transparent_color=target_color;
2153 break;
2154 }
2155 if (LocaleCompare(attribute,"type") == 0)
2156 {
2157 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2158 SvPV(sval,na)) : SvIV(sval);
2159 if (sp < 0)
2160 {
2161 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2162 SvPV(sval,na));
2163 break;
2164 }
2165 if (info)
2166 info->image_info->type=(ImageType) sp;
2167 for ( ; image; image=image->next)
2168 SetImageType(image,(ImageType) sp,exception);
2169 break;
2170 }
2171 if (info)
2172 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2173 for ( ; image; image=image->next)
2174 {
2175 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2176 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2177 }
2178 break;
2179 }
2180 case 'U':
2181 case 'u':
2182 {
2183 if (LocaleCompare(attribute,"units") == 0)
2184 {
2185 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2186 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2187 if (sp < 0)
2188 {
2189 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2190 SvPV(sval,na));
2191 break;
2192 }
2193 if (info)
2194 info->image_info->units=(ResolutionType) sp;
2195 for ( ; image; image=image->next)
2196 {
2197 ResolutionType
2198 units;
2199
2200 units=(ResolutionType) sp;
2201 if (image->units != units)
2202 switch (image->units)
2203 {
2204 case UndefinedResolution:
2205 case PixelsPerInchResolution:
2206 {
2207 if (units == PixelsPerCentimeterResolution)
2208 {
2209 image->resolution.x*=2.54;
2210 image->resolution.y*=2.54;
2211 }
2212 break;
2213 }
2214 case PixelsPerCentimeterResolution:
2215 {
2216 if (units == PixelsPerInchResolution)
2217 {
2218 image->resolution.x/=2.54;
2219 image->resolution.y/=2.54;
2220 }
2221 break;
2222 }
2223 }
2224 image->units=units;
2225 }
2226 break;
2227 }
2228 if (info)
2229 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2230 for ( ; image; image=image->next)
2231 {
2232 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2233 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2234 }
2235 break;
2236 }
2237 case 'V':
2238 case 'v':
2239 {
2240 if (LocaleCompare(attribute,"verbose") == 0)
2241 {
2242 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2243 SvPV(sval,na)) : SvIV(sval);
2244 if (sp < 0)
2245 {
2246 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2247 SvPV(sval,na));
2248 break;
2249 }
2250 if (info)
2251 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2252 break;
2253 }
2254 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2255 {
2256 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2257 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2258 if (sp < 0)
2259 {
2260 ThrowPerlException(exception,OptionError,
2261 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2262 break;
2263 }
2264 for ( ; image; image=image->next)
2265 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2266 break;
2267 }
2268 if (info)
2269 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2270 for ( ; image; image=image->next)
2271 {
2272 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2273 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2274 }
2275 break;
2276 }
2277 case 'W':
2278 case 'w':
2279 {
2280 if (LocaleCompare(attribute,"white-point") == 0)
2281 {
2282 for ( ; image; image=image->next)
2283 {
2284 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2285 image->chromaticity.white_point.x=geometry_info.rho;
2286 image->chromaticity.white_point.y=geometry_info.sigma;
2287 if ((flags & SigmaValue) == 0)
2288 image->chromaticity.white_point.y=
2289 image->chromaticity.white_point.x;
2290 }
2291 break;
2292 }
2293 if (LocaleCompare(attribute,"write-mask") == 0)
2294 {
2295 Image
2296 *mask;
2297
2298 mask=(Image *) NULL;
2299 if (SvPOK(sval))
2300 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2301 for ( ; image; image=image->next)
2302 SetImageMask(image,WritePixelMask,mask,exception);
2303 break;
2304 }
2305 if (info)
2306 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2307 for ( ; image; image=image->next)
2308 {
2309 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2310 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2311 }
2312 break;
2313 }
2314 default:
2315 {
2316 if (info)
2317 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2318 for ( ; image; image=image->next)
2319 {
2320 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2321 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2322 }
2323 break;
2324 }
2325 }
2326 }
2327
2328 /*
2329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2330 % %
2331 % %
2332 % %
2333 % S e t u p L i s t %
2334 % %
2335 % %
2336 % %
2337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2338 %
2339 % Method SetupList returns the list of all the images linked by their
2340 % image->next and image->previous link lists for use with ImageMagick. If
2341 % info is non-NULL, an info structure is returned in *info. If
2342 % reference_vector is non-NULL,an array of SV* are returned in
2343 % *reference_vector. Reference_vector is used when the images are going to be
2344 % replaced with new Image*'s.
2345 %
2346 % The format of the SetupList routine is:
2347 %
2348 % Image *SetupList(SV *reference,struct PackageInfo **info,
2349 % SV ***reference_vector,ExceptionInfo *exception)
2350 %
2351 % A description of each parameter follows:
2352 %
2353 % o list: a list of strings.
2354 %
2355 % o string: a character string.
2356 %
2357 % o exception: Return any errors or warnings in this structure.
2358 %
2359 */
SetupList(pTHX_ SV * reference,struct PackageInfo ** info,SV *** reference_vector,ExceptionInfo * exception)2360 static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2361 SV ***reference_vector,ExceptionInfo *exception)
2362 {
2363 Image
2364 *image;
2365
2366 ssize_t
2367 current,
2368 last;
2369
2370 if (reference_vector)
2371 *reference_vector=NULL;
2372 if (info)
2373 *info=NULL;
2374 current=0;
2375 last=0;
2376 image=GetList(aTHX_ reference,reference_vector,¤t,&last,exception);
2377 if (info && (SvTYPE(reference) == SVt_PVAV))
2378 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2379 exception);
2380 return(image);
2381 }
2382
2383 /*
2384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2385 % %
2386 % %
2387 % %
2388 % s t r E Q c a s e %
2389 % %
2390 % %
2391 % %
2392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2393 %
2394 % strEQcase() compares two strings and returns 0 if they are the
2395 % same or if the second string runs out first. The comparison is case
2396 % insensitive.
2397 %
2398 % The format of the strEQcase routine is:
2399 %
2400 % ssize_t strEQcase(const char *p,const char *q)
2401 %
2402 % A description of each parameter follows:
2403 %
2404 % o p: a character string.
2405 %
2406 % o q: a character string.
2407 %
2408 %
2409 */
strEQcase(const char * p,const char * q)2410 static ssize_t strEQcase(const char *p,const char *q)
2411 {
2412 char
2413 c;
2414
2415 register ssize_t
2416 i;
2417
2418 for (i=0 ; (c=(*q)) != 0; i++)
2419 {
2420 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2421 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2422 return(0);
2423 p++;
2424 q++;
2425 }
2426 return(((*q == 0) && (*p == 0)) ? i : 0);
2427 }
2428
2429 /*
2430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2431 % %
2432 % %
2433 % %
2434 % I m a g e : : M a g i c k %
2435 % %
2436 % %
2437 % %
2438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2439 %
2440 %
2441 */
2442 MODULE = Image::Magick PACKAGE = Image::Magick
2443
2444 PROTOTYPES: ENABLE
2445
2446 BOOT:
2447 MagickCoreGenesis("PerlMagick",MagickFalse);
2448 SetWarningHandler(NULL);
2449 SetErrorHandler(NULL);
2450 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2451 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2452
2453 void
UNLOAD()2454 UNLOAD()
2455 PPCODE:
2456 {
2457 if (magick_registry != (SplayTreeInfo *) NULL)
2458 magick_registry=DestroySplayTree(magick_registry);
2459 MagickCoreTerminus();
2460 }
2461
2462 double
constant(name,argument)2463 constant(name,argument)
2464 char *name
2465 ssize_t argument
2466
2467 #
2468 ###############################################################################
2469 # #
2470 # #
2471 # #
2472 # A n i m a t e #
2473 # #
2474 # #
2475 # #
2476 ###############################################################################
2477 #
2478 #
2479 void
2480 Animate(ref,...)
2481 Image::Magick ref=NO_INIT
2482 ALIAS:
2483 AnimateImage = 1
2484 animate = 2
2485 animateimage = 3
2486 PPCODE:
2487 {
2488 ExceptionInfo
2489 *exception;
2490
2491 Image
2492 *image;
2493
2494 register ssize_t
2495 i;
2496
2497 struct PackageInfo
2498 *info,
2499 *package_info;
2500
2501 SV
2502 *perl_exception,
2503 *reference;
2504
2505 PERL_UNUSED_VAR(ref);
2506 PERL_UNUSED_VAR(ix);
2507 exception=AcquireExceptionInfo();
2508 perl_exception=newSVpv("",0);
2509 package_info=(struct PackageInfo *) NULL;
2510 if (sv_isobject(ST(0)) == 0)
2511 {
2512 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2513 PackageName);
2514 goto PerlException;
2515 }
2516 reference=SvRV(ST(0));
2517 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2518 if (image == (Image *) NULL)
2519 {
2520 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2521 PackageName);
2522 goto PerlException;
2523 }
2524 package_info=ClonePackageInfo(info,exception);
2525 if (items == 2)
2526 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2527 else
2528 if (items > 2)
2529 for (i=2; i < items; i+=2)
2530 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2531 exception);
2532 (void) AnimateImages(package_info->image_info,image,exception);
2533 (void) CatchImageException(image);
2534
2535 PerlException:
2536 if (package_info != (struct PackageInfo *) NULL)
2537 DestroyPackageInfo(package_info);
2538 InheritPerlException(exception,perl_exception);
2539 exception=DestroyExceptionInfo(exception);
2540 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2541 SvPOK_on(perl_exception);
2542 ST(0)=sv_2mortal(perl_exception);
2543 XSRETURN(1);
2544 }
2545
2546 #
2547 ###############################################################################
2548 # #
2549 # #
2550 # #
2551 # A p p e n d #
2552 # #
2553 # #
2554 # #
2555 ###############################################################################
2556 #
2557 #
2558 void
Append(ref,...)2559 Append(ref,...)
2560 Image::Magick ref=NO_INIT
2561 ALIAS:
2562 AppendImage = 1
2563 append = 2
2564 appendimage = 3
2565 PPCODE:
2566 {
2567 AV
2568 *av;
2569
2570 char
2571 *attribute;
2572
2573 ExceptionInfo
2574 *exception;
2575
2576 HV
2577 *hv;
2578
2579 Image
2580 *image;
2581
2582 register ssize_t
2583 i;
2584
2585 ssize_t
2586 stack;
2587
2588 struct PackageInfo
2589 *info;
2590
2591 SV
2592 *av_reference,
2593 *perl_exception,
2594 *reference,
2595 *rv,
2596 *sv;
2597
2598 PERL_UNUSED_VAR(ref);
2599 PERL_UNUSED_VAR(ix);
2600 exception=AcquireExceptionInfo();
2601 perl_exception=newSVpv("",0);
2602 sv=NULL;
2603 attribute=NULL;
2604 av=NULL;
2605 if (sv_isobject(ST(0)) == 0)
2606 {
2607 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2608 PackageName);
2609 goto PerlException;
2610 }
2611 reference=SvRV(ST(0));
2612 hv=SvSTASH(reference);
2613 av=newAV();
2614 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2615 SvREFCNT_dec(av);
2616 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2617 if (image == (Image *) NULL)
2618 {
2619 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2620 PackageName);
2621 goto PerlException;
2622 }
2623 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2624 /*
2625 Get options.
2626 */
2627 stack=MagickTrue;
2628 for (i=2; i < items; i+=2)
2629 {
2630 attribute=(char *) SvPV(ST(i-1),na);
2631 switch (*attribute)
2632 {
2633 case 'S':
2634 case 's':
2635 {
2636 if (LocaleCompare(attribute,"stack") == 0)
2637 {
2638 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2639 SvPV(ST(i),na));
2640 if (stack < 0)
2641 {
2642 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2643 SvPV(ST(i),na));
2644 return;
2645 }
2646 break;
2647 }
2648 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2649 attribute);
2650 break;
2651 }
2652 default:
2653 {
2654 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2655 attribute);
2656 break;
2657 }
2658 }
2659 }
2660 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2661 if (image == (Image *) NULL)
2662 goto PerlException;
2663 for ( ; image; image=image->next)
2664 {
2665 AddImageToRegistry(sv,image);
2666 rv=newRV(sv);
2667 av_push(av,sv_bless(rv,hv));
2668 SvREFCNT_dec(sv);
2669 }
2670 exception=DestroyExceptionInfo(exception);
2671 ST(0)=av_reference;
2672 SvREFCNT_dec(perl_exception);
2673 XSRETURN(1);
2674
2675 PerlException:
2676 InheritPerlException(exception,perl_exception);
2677 exception=DestroyExceptionInfo(exception);
2678 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2679 SvPOK_on(perl_exception);
2680 ST(0)=sv_2mortal(perl_exception);
2681 XSRETURN(1);
2682 }
2683
2684 #
2685 ###############################################################################
2686 # #
2687 # #
2688 # #
2689 # A v e r a g e #
2690 # #
2691 # #
2692 # #
2693 ###############################################################################
2694 #
2695 #
2696 void
Average(ref)2697 Average(ref)
2698 Image::Magick ref=NO_INIT
2699 ALIAS:
2700 AverageImage = 1
2701 average = 2
2702 averageimage = 3
2703 PPCODE:
2704 {
2705 AV
2706 *av;
2707
2708 char
2709 *p;
2710
2711 ExceptionInfo
2712 *exception;
2713
2714 HV
2715 *hv;
2716
2717 Image
2718 *image;
2719
2720 struct PackageInfo
2721 *info;
2722
2723 SV
2724 *perl_exception,
2725 *reference,
2726 *rv,
2727 *sv;
2728
2729 PERL_UNUSED_VAR(ref);
2730 PERL_UNUSED_VAR(ix);
2731 exception=AcquireExceptionInfo();
2732 perl_exception=newSVpv("",0);
2733 sv=NULL;
2734 if (sv_isobject(ST(0)) == 0)
2735 {
2736 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2737 PackageName);
2738 goto PerlException;
2739 }
2740 reference=SvRV(ST(0));
2741 hv=SvSTASH(reference);
2742 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2743 if (image == (Image *) NULL)
2744 {
2745 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2746 PackageName);
2747 goto PerlException;
2748 }
2749 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2750 if (image == (Image *) NULL)
2751 goto PerlException;
2752 /*
2753 Create blessed Perl array for the returned image.
2754 */
2755 av=newAV();
2756 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2757 SvREFCNT_dec(av);
2758 AddImageToRegistry(sv,image);
2759 rv=newRV(sv);
2760 av_push(av,sv_bless(rv,hv));
2761 SvREFCNT_dec(sv);
2762 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2763 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2764 "average-%.*s",(int) (MagickPathExtent-9),
2765 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2766 (void) CopyMagickString(image->filename,info->image_info->filename,
2767 MagickPathExtent);
2768 SetImageInfo(info->image_info,0,exception);
2769 exception=DestroyExceptionInfo(exception);
2770 SvREFCNT_dec(perl_exception);
2771 XSRETURN(1);
2772
2773 PerlException:
2774 InheritPerlException(exception,perl_exception);
2775 exception=DestroyExceptionInfo(exception);
2776 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2777 SvPOK_on(perl_exception);
2778 ST(0)=sv_2mortal(perl_exception);
2779 XSRETURN(1);
2780 }
2781
2782 #
2783 ###############################################################################
2784 # #
2785 # #
2786 # #
2787 # B l o b T o I m a g e #
2788 # #
2789 # #
2790 # #
2791 ###############################################################################
2792 #
2793 #
2794 void
BlobToImage(ref,...)2795 BlobToImage(ref,...)
2796 Image::Magick ref=NO_INIT
2797 ALIAS:
2798 BlobToImage = 1
2799 blobtoimage = 2
2800 blobto = 3
2801 PPCODE:
2802 {
2803 AV
2804 *av;
2805
2806 char
2807 **keep,
2808 **list;
2809
2810 ExceptionInfo
2811 *exception;
2812
2813 HV
2814 *hv;
2815
2816 Image
2817 *image;
2818
2819 register char
2820 **p;
2821
2822 register ssize_t
2823 i;
2824
2825 ssize_t
2826 ac,
2827 n,
2828 number_images;
2829
2830 STRLEN
2831 *length;
2832
2833 struct PackageInfo
2834 *info;
2835
2836 SV
2837 *perl_exception,
2838 *reference,
2839 *rv,
2840 *sv;
2841
2842 PERL_UNUSED_VAR(ref);
2843 PERL_UNUSED_VAR(ix);
2844 exception=AcquireExceptionInfo();
2845 perl_exception=newSVpv("",0);
2846 sv=NULL;
2847 number_images=0;
2848 ac=(items < 2) ? 1 : items-1;
2849 length=(STRLEN *) NULL;
2850 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2851 if (list == (char **) NULL)
2852 {
2853 ThrowPerlException(exception,ResourceLimitError,
2854 "MemoryAllocationFailed",PackageName);
2855 goto PerlException;
2856 }
2857 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2858 if (length == (STRLEN *) NULL)
2859 {
2860 ThrowPerlException(exception,ResourceLimitError,
2861 "MemoryAllocationFailed",PackageName);
2862 goto PerlException;
2863 }
2864 if (sv_isobject(ST(0)) == 0)
2865 {
2866 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2867 PackageName);
2868 goto PerlException;
2869 }
2870 reference=SvRV(ST(0));
2871 hv=SvSTASH(reference);
2872 if (SvTYPE(reference) != SVt_PVAV)
2873 {
2874 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2875 PackageName);
2876 goto PerlException;
2877 }
2878 av=(AV *) reference;
2879 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2880 exception);
2881 n=1;
2882 if (items <= 1)
2883 {
2884 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2885 goto PerlException;
2886 }
2887 for (n=0, i=0; i < ac; i++)
2888 {
2889 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2890 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2891 {
2892 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2893 continue;
2894 }
2895 n++;
2896 }
2897 list[n]=(char *) NULL;
2898 keep=list;
2899 for (i=number_images=0; i < n; i++)
2900 {
2901 image=BlobToImage(info->image_info,list[i],length[i],exception);
2902 if (image == (Image *) NULL)
2903 break;
2904 for ( ; image; image=image->next)
2905 {
2906 AddImageToRegistry(sv,image);
2907 rv=newRV(sv);
2908 av_push(av,sv_bless(rv,hv));
2909 SvREFCNT_dec(sv);
2910 number_images++;
2911 }
2912 }
2913 /*
2914 Free resources.
2915 */
2916 for (i=0; i < n; i++)
2917 if (list[i] != (char *) NULL)
2918 for (p=keep; list[i] != *p++; )
2919 if (*p == (char *) NULL)
2920 {
2921 list[i]=(char *) RelinquishMagickMemory(list[i]);
2922 break;
2923 }
2924
2925 PerlException:
2926 if (list)
2927 list=(char **) RelinquishMagickMemory(list);
2928 if (length)
2929 length=(STRLEN *) RelinquishMagickMemory(length);
2930 InheritPerlException(exception,perl_exception);
2931 exception=DestroyExceptionInfo(exception);
2932 sv_setiv(perl_exception,(IV) number_images);
2933 SvPOK_on(perl_exception);
2934 ST(0)=sv_2mortal(perl_exception);
2935 XSRETURN(1);
2936 }
2937
2938 #
2939 ###############################################################################
2940 # #
2941 # #
2942 # #
2943 # C h a n n e l F x #
2944 # #
2945 # #
2946 # #
2947 ###############################################################################
2948 #
2949 #
2950 void
ChannelFx(ref,...)2951 ChannelFx(ref,...)
2952 Image::Magick ref=NO_INIT
2953 ALIAS:
2954 ChannelFxImage = 1
2955 channelfx = 2
2956 channelfximage = 3
2957 PPCODE:
2958 {
2959 AV
2960 *av;
2961
2962 char
2963 *attribute,
2964 expression[MagickPathExtent];
2965
2966 ChannelType
2967 channel,
2968 channel_mask;
2969
2970 ExceptionInfo
2971 *exception;
2972
2973 HV
2974 *hv;
2975
2976 Image
2977 *image;
2978
2979 register ssize_t
2980 i;
2981
2982 struct PackageInfo
2983 *info;
2984
2985 SV
2986 *av_reference,
2987 *perl_exception,
2988 *reference,
2989 *rv,
2990 *sv;
2991
2992 PERL_UNUSED_VAR(ref);
2993 PERL_UNUSED_VAR(ix);
2994 exception=AcquireExceptionInfo();
2995 perl_exception=newSVpv("",0);
2996 sv=NULL;
2997 attribute=NULL;
2998 av=NULL;
2999 if (sv_isobject(ST(0)) == 0)
3000 {
3001 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3002 PackageName);
3003 goto PerlException;
3004 }
3005 reference=SvRV(ST(0));
3006 hv=SvSTASH(reference);
3007 av=newAV();
3008 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3009 SvREFCNT_dec(av);
3010 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3011 if (image == (Image *) NULL)
3012 {
3013 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3014 PackageName);
3015 goto PerlException;
3016 }
3017 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3018 /*
3019 Get options.
3020 */
3021 channel=DefaultChannels;
3022 (void) CopyMagickString(expression,"u",MagickPathExtent);
3023 if (items == 2)
3024 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
3025 else
3026 for (i=2; i < items; i+=2)
3027 {
3028 attribute=(char *) SvPV(ST(i-1),na);
3029 switch (*attribute)
3030 {
3031 case 'C':
3032 case 'c':
3033 {
3034 if (LocaleCompare(attribute,"channel") == 0)
3035 {
3036 ssize_t
3037 option;
3038
3039 option=ParseChannelOption(SvPV(ST(i),na));
3040 if (option < 0)
3041 {
3042 ThrowPerlException(exception,OptionError,
3043 "UnrecognizedType",SvPV(ST(i),na));
3044 return;
3045 }
3046 channel=(ChannelType) option;
3047 break;
3048 }
3049 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3050 attribute);
3051 break;
3052 }
3053 case 'E':
3054 case 'e':
3055 {
3056 if (LocaleCompare(attribute,"expression") == 0)
3057 {
3058 (void) CopyMagickString(expression,SvPV(ST(i),na),
3059 MagickPathExtent);
3060 break;
3061 }
3062 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3063 attribute);
3064 break;
3065 }
3066 default:
3067 {
3068 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3069 attribute);
3070 break;
3071 }
3072 }
3073 }
3074 channel_mask=SetImageChannelMask(image,channel);
3075 image=ChannelFxImage(image,expression,exception);
3076 if (image != (Image *) NULL)
3077 (void) SetImageChannelMask(image,channel_mask);
3078 if (image == (Image *) NULL)
3079 goto PerlException;
3080 for ( ; image; image=image->next)
3081 {
3082 AddImageToRegistry(sv,image);
3083 rv=newRV(sv);
3084 av_push(av,sv_bless(rv,hv));
3085 SvREFCNT_dec(sv);
3086 }
3087 exception=DestroyExceptionInfo(exception);
3088 ST(0)=av_reference;
3089 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3090 XSRETURN(1);
3091
3092 PerlException:
3093 InheritPerlException(exception,perl_exception);
3094 exception=DestroyExceptionInfo(exception);
3095 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3096 SvPOK_on(perl_exception);
3097 ST(0)=sv_2mortal(perl_exception);
3098 XSRETURN(1);
3099 }
3100
3101 #
3102 ###############################################################################
3103 # #
3104 # #
3105 # #
3106 # C l o n e #
3107 # #
3108 # #
3109 # #
3110 ###############################################################################
3111 #
3112 #
3113 void
Clone(ref)3114 Clone(ref)
3115 Image::Magick ref=NO_INIT
3116 ALIAS:
3117 CopyImage = 1
3118 copy = 2
3119 copyimage = 3
3120 CloneImage = 4
3121 clone = 5
3122 cloneimage = 6
3123 Clone = 7
3124 PPCODE:
3125 {
3126 AV
3127 *av;
3128
3129 ExceptionInfo
3130 *exception;
3131
3132 HV
3133 *hv;
3134
3135 Image
3136 *clone,
3137 *image;
3138
3139 struct PackageInfo
3140 *info;
3141
3142 SV
3143 *perl_exception,
3144 *reference,
3145 *rv,
3146 *sv;
3147
3148 PERL_UNUSED_VAR(ref);
3149 PERL_UNUSED_VAR(ix);
3150 exception=AcquireExceptionInfo();
3151 perl_exception=newSVpv("",0);
3152 sv=NULL;
3153 if (sv_isobject(ST(0)) == 0)
3154 {
3155 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3156 PackageName);
3157 goto PerlException;
3158 }
3159 reference=SvRV(ST(0));
3160 hv=SvSTASH(reference);
3161 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3162 if (image == (Image *) NULL)
3163 {
3164 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3165 PackageName);
3166 goto PerlException;
3167 }
3168 /*
3169 Create blessed Perl array for the returned image.
3170 */
3171 av=newAV();
3172 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3173 SvREFCNT_dec(av);
3174 for ( ; image; image=image->next)
3175 {
3176 clone=CloneImage(image,0,0,MagickTrue,exception);
3177 if (clone == (Image *) NULL)
3178 break;
3179 AddImageToRegistry(sv,clone);
3180 rv=newRV(sv);
3181 av_push(av,sv_bless(rv,hv));
3182 SvREFCNT_dec(sv);
3183 }
3184 exception=DestroyExceptionInfo(exception);
3185 SvREFCNT_dec(perl_exception);
3186 XSRETURN(1);
3187
3188 PerlException:
3189 InheritPerlException(exception,perl_exception);
3190 exception=DestroyExceptionInfo(exception);
3191 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3192 SvPOK_on(perl_exception);
3193 ST(0)=sv_2mortal(perl_exception);
3194 XSRETURN(1);
3195 }
3196
3197 #
3198 ###############################################################################
3199 # #
3200 # #
3201 # #
3202 # C L O N E #
3203 # #
3204 # #
3205 # #
3206 ###############################################################################
3207 #
3208 #
3209 void
CLONE(ref,...)3210 CLONE(ref,...)
3211 SV *ref;
3212 CODE:
3213 {
3214 PERL_UNUSED_VAR(ref);
3215 if (magick_registry != (SplayTreeInfo *) NULL)
3216 {
3217 register Image
3218 *p;
3219
3220 ResetSplayTreeIterator(magick_registry);
3221 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3222 while (p != (Image *) NULL)
3223 {
3224 ReferenceImage(p);
3225 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3226 }
3227 }
3228 }
3229
3230 #
3231 ###############################################################################
3232 # #
3233 # #
3234 # #
3235 # C o a l e s c e #
3236 # #
3237 # #
3238 # #
3239 ###############################################################################
3240 #
3241 #
3242 void
Coalesce(ref)3243 Coalesce(ref)
3244 Image::Magick ref=NO_INIT
3245 ALIAS:
3246 CoalesceImage = 1
3247 coalesce = 2
3248 coalesceimage = 3
3249 PPCODE:
3250 {
3251 AV
3252 *av;
3253
3254 ExceptionInfo
3255 *exception;
3256
3257 HV
3258 *hv;
3259
3260 Image
3261 *image;
3262
3263 struct PackageInfo
3264 *info;
3265
3266 SV
3267 *av_reference,
3268 *perl_exception,
3269 *reference,
3270 *rv,
3271 *sv;
3272
3273 PERL_UNUSED_VAR(ref);
3274 PERL_UNUSED_VAR(ix);
3275 exception=AcquireExceptionInfo();
3276 perl_exception=newSVpv("",0);
3277 sv=NULL;
3278 if (sv_isobject(ST(0)) == 0)
3279 {
3280 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3281 PackageName);
3282 goto PerlException;
3283 }
3284 reference=SvRV(ST(0));
3285 hv=SvSTASH(reference);
3286 av=newAV();
3287 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3288 SvREFCNT_dec(av);
3289 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3290 if (image == (Image *) NULL)
3291 {
3292 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3293 PackageName);
3294 goto PerlException;
3295 }
3296 image=CoalesceImages(image,exception);
3297 if (image == (Image *) NULL)
3298 goto PerlException;
3299 for ( ; image; image=image->next)
3300 {
3301 AddImageToRegistry(sv,image);
3302 rv=newRV(sv);
3303 av_push(av,sv_bless(rv,hv));
3304 SvREFCNT_dec(sv);
3305 }
3306 exception=DestroyExceptionInfo(exception);
3307 ST(0)=av_reference;
3308 SvREFCNT_dec(perl_exception);
3309 XSRETURN(1);
3310
3311 PerlException:
3312 InheritPerlException(exception,perl_exception);
3313 exception=DestroyExceptionInfo(exception);
3314 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3315 SvPOK_on(perl_exception);
3316 ST(0)=sv_2mortal(perl_exception);
3317 XSRETURN(1);
3318 }
3319
3320 #
3321 ###############################################################################
3322 # #
3323 # #
3324 # #
3325 # C o m p a r e #
3326 # #
3327 # #
3328 # #
3329 ###############################################################################
3330 #
3331 #
3332 void
Compare(ref,...)3333 Compare(ref,...)
3334 Image::Magick ref=NO_INIT
3335 ALIAS:
3336 CompareImages = 1
3337 compare = 2
3338 compareimage = 3
3339 PPCODE:
3340 {
3341 AV
3342 *av;
3343
3344 char
3345 *attribute;
3346
3347 double
3348 distortion;
3349
3350 ExceptionInfo
3351 *exception;
3352
3353 HV
3354 *hv;
3355
3356 Image
3357 *difference_image,
3358 *image,
3359 *reconstruct_image;
3360
3361 MetricType
3362 metric;
3363
3364 register ssize_t
3365 i;
3366
3367 ssize_t
3368 option;
3369
3370 struct PackageInfo
3371 *info;
3372
3373 SV
3374 *av_reference,
3375 *perl_exception,
3376 *reference,
3377 *rv,
3378 *sv;
3379
3380 PERL_UNUSED_VAR(ref);
3381 PERL_UNUSED_VAR(ix);
3382 exception=AcquireExceptionInfo();
3383 perl_exception=newSVpv("",0);
3384 sv=NULL;
3385 av=NULL;
3386 attribute=NULL;
3387 if (sv_isobject(ST(0)) == 0)
3388 {
3389 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3390 PackageName);
3391 goto PerlException;
3392 }
3393 reference=SvRV(ST(0));
3394 hv=SvSTASH(reference);
3395 av=newAV();
3396 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3397 SvREFCNT_dec(av);
3398 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3399 if (image == (Image *) NULL)
3400 {
3401 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3402 PackageName);
3403 goto PerlException;
3404 }
3405 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3406 /*
3407 Get attribute.
3408 */
3409 reconstruct_image=image;
3410 metric=RootMeanSquaredErrorMetric;
3411 for (i=2; i < items; i+=2)
3412 {
3413 attribute=(char *) SvPV(ST(i-1),na);
3414 switch (*attribute)
3415 {
3416 case 'C':
3417 case 'c':
3418 {
3419 if (LocaleCompare(attribute,"channel") == 0)
3420 {
3421 ssize_t
3422 option;
3423
3424 option=ParseChannelOption(SvPV(ST(i),na));
3425 if (option < 0)
3426 {
3427 ThrowPerlException(exception,OptionError,
3428 "UnrecognizedType",SvPV(ST(i),na));
3429 return;
3430 }
3431 (void) SetPixelChannelMask(image,(ChannelType) option);
3432 break;
3433 }
3434 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3435 attribute);
3436 break;
3437 }
3438 case 'F':
3439 case 'f':
3440 {
3441 if (LocaleCompare(attribute,"fuzz") == 0)
3442 {
3443 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3444 break;
3445 }
3446 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3447 attribute);
3448 break;
3449 }
3450 case 'I':
3451 case 'i':
3452 {
3453 if (LocaleCompare(attribute,"image") == 0)
3454 {
3455 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3456 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3457 break;
3458 }
3459 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3460 attribute);
3461 break;
3462 }
3463 case 'M':
3464 case 'm':
3465 {
3466 if (LocaleCompare(attribute,"metric") == 0)
3467 {
3468 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3469 SvPV(ST(i),na));
3470 if (option < 0)
3471 {
3472 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3473 SvPV(ST(i),na));
3474 break;
3475 }
3476 metric=(MetricType) option;
3477 break;
3478 }
3479 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3480 attribute);
3481 break;
3482 }
3483 default:
3484 {
3485 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3486 attribute);
3487 break;
3488 }
3489 }
3490 }
3491 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3492 exception);
3493 if (difference_image != (Image *) NULL)
3494 {
3495 difference_image->error.mean_error_per_pixel=distortion;
3496 AddImageToRegistry(sv,difference_image);
3497 rv=newRV(sv);
3498 av_push(av,sv_bless(rv,hv));
3499 SvREFCNT_dec(sv);
3500 }
3501 exception=DestroyExceptionInfo(exception);
3502 ST(0)=av_reference;
3503 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3504 XSRETURN(1);
3505
3506 PerlException:
3507 InheritPerlException(exception,perl_exception);
3508 exception=DestroyExceptionInfo(exception);
3509 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3510 SvPOK_on(perl_exception);
3511 ST(0)=sv_2mortal(perl_exception);
3512 XSRETURN(1);
3513 }
3514
3515 #
3516 ###############################################################################
3517 # #
3518 # #
3519 # #
3520 # C o m p l e x I m a g e s #
3521 # #
3522 # #
3523 # #
3524 ###############################################################################
3525 #
3526 #
3527 void
ComplexImages(ref)3528 ComplexImages(ref)
3529 Image::Magick ref=NO_INIT
3530 ALIAS:
3531 ComplexImages = 1
3532 compleximages = 2
3533 PPCODE:
3534 {
3535 AV
3536 *av;
3537
3538 char
3539 *attribute,
3540 *p;
3541
3542 ComplexOperator
3543 op;
3544
3545 ExceptionInfo
3546 *exception;
3547
3548 HV
3549 *hv;
3550
3551 Image
3552 *image;
3553
3554 register ssize_t
3555 i;
3556
3557 struct PackageInfo
3558 *info;
3559
3560 SV
3561 *perl_exception,
3562 *reference,
3563 *rv,
3564 *sv;
3565
3566 PERL_UNUSED_VAR(ref);
3567 PERL_UNUSED_VAR(ix);
3568 exception=AcquireExceptionInfo();
3569 perl_exception=newSVpv("",0);
3570 sv=NULL;
3571 if (sv_isobject(ST(0)) == 0)
3572 {
3573 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3574 PackageName);
3575 goto PerlException;
3576 }
3577 reference=SvRV(ST(0));
3578 hv=SvSTASH(reference);
3579 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3580 if (image == (Image *) NULL)
3581 {
3582 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3583 PackageName);
3584 goto PerlException;
3585 }
3586 op=UndefinedComplexOperator;
3587 if (items == 2)
3588 {
3589 ssize_t
3590 in;
3591
3592 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3593 SvPV(ST(1),na));
3594 if (in < 0)
3595 {
3596 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3597 SvPV(ST(1),na));
3598 return;
3599 }
3600 op=(ComplexOperator) in;
3601 }
3602 else
3603 for (i=2; i < items; i+=2)
3604 {
3605 attribute=(char *) SvPV(ST(i-1),na);
3606 switch (*attribute)
3607 {
3608 case 'O':
3609 case 'o':
3610 {
3611 if (LocaleCompare(attribute,"operator") == 0)
3612 {
3613 ssize_t
3614 in;
3615
3616 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3617 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3618 if (in < 0)
3619 {
3620 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3621 SvPV(ST(i),na));
3622 return;
3623 }
3624 op=(ComplexOperator) in;
3625 break;
3626 }
3627 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3628 attribute);
3629 break;
3630 }
3631 default:
3632 {
3633 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3634 attribute);
3635 break;
3636 }
3637 }
3638 }
3639 image=ComplexImages(image,op,exception);
3640 if (image == (Image *) NULL)
3641 goto PerlException;
3642 /*
3643 Create blessed Perl array for the returned image.
3644 */
3645 av=newAV();
3646 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3647 SvREFCNT_dec(av);
3648 AddImageToRegistry(sv,image);
3649 rv=newRV(sv);
3650 av_push(av,sv_bless(rv,hv));
3651 SvREFCNT_dec(sv);
3652 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3653 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3654 "complex-%.*s",(int) (MagickPathExtent-9),
3655 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3656 (void) CopyMagickString(image->filename,info->image_info->filename,
3657 MagickPathExtent);
3658 SetImageInfo(info->image_info,0,exception);
3659 exception=DestroyExceptionInfo(exception);
3660 SvREFCNT_dec(perl_exception);
3661 XSRETURN(1);
3662
3663 PerlException:
3664 InheritPerlException(exception,perl_exception);
3665 exception=DestroyExceptionInfo(exception);
3666 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3667 SvPOK_on(perl_exception);
3668 ST(0)=sv_2mortal(perl_exception);
3669 XSRETURN(1);
3670 }
3671
3672 #
3673 ###############################################################################
3674 # #
3675 # #
3676 # #
3677 # C o m p a r e L a y e r s #
3678 # #
3679 # #
3680 # #
3681 ###############################################################################
3682 #
3683 #
3684 void
CompareLayers(ref)3685 CompareLayers(ref)
3686 Image::Magick ref=NO_INIT
3687 ALIAS:
3688 CompareImagesLayers = 1
3689 comparelayers = 2
3690 compareimagelayers = 3
3691 PPCODE:
3692 {
3693 AV
3694 *av;
3695
3696 char
3697 *attribute;
3698
3699 ExceptionInfo
3700 *exception;
3701
3702 HV
3703 *hv;
3704
3705 Image
3706 *image;
3707
3708 LayerMethod
3709 method;
3710
3711 register ssize_t
3712 i;
3713
3714 ssize_t
3715 option;
3716
3717 struct PackageInfo
3718 *info;
3719
3720 SV
3721 *av_reference,
3722 *perl_exception,
3723 *reference,
3724 *rv,
3725 *sv;
3726
3727 PERL_UNUSED_VAR(ref);
3728 PERL_UNUSED_VAR(ix);
3729 exception=AcquireExceptionInfo();
3730 perl_exception=newSVpv("",0);
3731 sv=NULL;
3732 if (sv_isobject(ST(0)) == 0)
3733 {
3734 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3735 PackageName);
3736 goto PerlException;
3737 }
3738 reference=SvRV(ST(0));
3739 hv=SvSTASH(reference);
3740 av=newAV();
3741 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3742 SvREFCNT_dec(av);
3743 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3744 if (image == (Image *) NULL)
3745 {
3746 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3747 PackageName);
3748 goto PerlException;
3749 }
3750 method=CompareAnyLayer;
3751 for (i=2; i < items; i+=2)
3752 {
3753 attribute=(char *) SvPV(ST(i-1),na);
3754 switch (*attribute)
3755 {
3756 case 'M':
3757 case 'm':
3758 {
3759 if (LocaleCompare(attribute,"method") == 0)
3760 {
3761 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3762 SvPV(ST(i),na));
3763 if (option < 0)
3764 {
3765 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3766 SvPV(ST(i),na));
3767 break;
3768 }
3769 method=(LayerMethod) option;
3770 break;
3771 }
3772 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3773 attribute);
3774 break;
3775 }
3776 default:
3777 {
3778 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3779 attribute);
3780 break;
3781 }
3782 }
3783 }
3784 image=CompareImagesLayers(image,method,exception);
3785 if (image == (Image *) NULL)
3786 goto PerlException;
3787 for ( ; image; image=image->next)
3788 {
3789 AddImageToRegistry(sv,image);
3790 rv=newRV(sv);
3791 av_push(av,sv_bless(rv,hv));
3792 SvREFCNT_dec(sv);
3793 }
3794 exception=DestroyExceptionInfo(exception);
3795 ST(0)=av_reference;
3796 SvREFCNT_dec(perl_exception);
3797 XSRETURN(1);
3798
3799 PerlException:
3800 InheritPerlException(exception,perl_exception);
3801 exception=DestroyExceptionInfo(exception);
3802 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3803 SvPOK_on(perl_exception);
3804 ST(0)=sv_2mortal(perl_exception);
3805 XSRETURN(1);
3806 }
3807
3808 #
3809 ###############################################################################
3810 # #
3811 # #
3812 # #
3813 # D e s t r o y #
3814 # #
3815 # #
3816 # #
3817 ###############################################################################
3818 #
3819 #
3820 void
DESTROY(ref)3821 DESTROY(ref)
3822 Image::Magick ref=NO_INIT
3823 PPCODE:
3824 {
3825 SV
3826 *reference;
3827
3828 PERL_UNUSED_VAR(ref);
3829 if (sv_isobject(ST(0)) == 0)
3830 croak("ReferenceIsNotMyType");
3831 reference=SvRV(ST(0));
3832 switch (SvTYPE(reference))
3833 {
3834 case SVt_PVAV:
3835 {
3836 char
3837 message[MagickPathExtent];
3838
3839 const SV
3840 *key;
3841
3842 HV
3843 *hv;
3844
3845 GV
3846 **gvp;
3847
3848 struct PackageInfo
3849 *info;
3850
3851 SV
3852 *sv;
3853
3854 /*
3855 Array (AV *) reference
3856 */
3857 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
3858 XS_VERSION,reference);
3859 hv=gv_stashpv(PackageName, FALSE);
3860 if (!hv)
3861 break;
3862 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3863 if (!gvp)
3864 break;
3865 sv=GvSV(*gvp);
3866 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3867 {
3868 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3869 DestroyPackageInfo(info);
3870 }
3871 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3872 (void) key;
3873 break;
3874 }
3875 case SVt_PVMG:
3876 {
3877 Image
3878 *image;
3879
3880 /*
3881 Blessed scalar = (Image *) SvIV(reference)
3882 */
3883 image=INT2PTR(Image *,SvIV(reference));
3884 if (image != (Image *) NULL)
3885 DeleteImageFromRegistry(reference,image);
3886 break;
3887 }
3888 default:
3889 break;
3890 }
3891 }
3892
3893 #
3894 ###############################################################################
3895 # #
3896 # #
3897 # #
3898 # D i s p l a y #
3899 # #
3900 # #
3901 # #
3902 ###############################################################################
3903 #
3904 #
3905 void
Display(ref,...)3906 Display(ref,...)
3907 Image::Magick ref=NO_INIT
3908 ALIAS:
3909 DisplayImage = 1
3910 display = 2
3911 displayimage = 3
3912 PPCODE:
3913 {
3914 ExceptionInfo
3915 *exception;
3916
3917 Image
3918 *image;
3919
3920 register ssize_t
3921 i;
3922
3923 struct PackageInfo
3924 *info,
3925 *package_info;
3926
3927 SV
3928 *perl_exception,
3929 *reference;
3930
3931 PERL_UNUSED_VAR(ref);
3932 PERL_UNUSED_VAR(ix);
3933 exception=AcquireExceptionInfo();
3934 perl_exception=newSVpv("",0);
3935 package_info=(struct PackageInfo *) NULL;
3936 if (sv_isobject(ST(0)) == 0)
3937 {
3938 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3939 PackageName);
3940 goto PerlException;
3941 }
3942 reference=SvRV(ST(0));
3943 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3944 if (image == (Image *) NULL)
3945 {
3946 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3947 PackageName);
3948 goto PerlException;
3949 }
3950 package_info=ClonePackageInfo(info,exception);
3951 if (items == 2)
3952 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3953 else
3954 if (items > 2)
3955 for (i=2; i < items; i+=2)
3956 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3957 exception);
3958 (void) DisplayImages(package_info->image_info,image,exception);
3959 (void) CatchImageException(image);
3960
3961 PerlException:
3962 if (package_info != (struct PackageInfo *) NULL)
3963 DestroyPackageInfo(package_info);
3964 InheritPerlException(exception,perl_exception);
3965 exception=DestroyExceptionInfo(exception);
3966 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3967 SvPOK_on(perl_exception);
3968 ST(0)=sv_2mortal(perl_exception);
3969 XSRETURN(1);
3970 }
3971
3972 #
3973 ###############################################################################
3974 # #
3975 # #
3976 # #
3977 # E v a l u a t e I m a g e s #
3978 # #
3979 # #
3980 # #
3981 ###############################################################################
3982 #
3983 #
3984 void
EvaluateImages(ref)3985 EvaluateImages(ref)
3986 Image::Magick ref=NO_INIT
3987 ALIAS:
3988 EvaluateImages = 1
3989 evaluateimages = 2
3990 PPCODE:
3991 {
3992 AV
3993 *av;
3994
3995 char
3996 *attribute,
3997 *p;
3998
3999 ExceptionInfo
4000 *exception;
4001
4002 HV
4003 *hv;
4004
4005 Image
4006 *image;
4007
4008 MagickEvaluateOperator
4009 op;
4010
4011 register ssize_t
4012 i;
4013
4014 struct PackageInfo
4015 *info;
4016
4017 SV
4018 *perl_exception,
4019 *reference,
4020 *rv,
4021 *sv;
4022
4023 PERL_UNUSED_VAR(ref);
4024 PERL_UNUSED_VAR(ix);
4025 exception=AcquireExceptionInfo();
4026 perl_exception=newSVpv("",0);
4027 sv=NULL;
4028 if (sv_isobject(ST(0)) == 0)
4029 {
4030 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4031 PackageName);
4032 goto PerlException;
4033 }
4034 reference=SvRV(ST(0));
4035 hv=SvSTASH(reference);
4036 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4037 if (image == (Image *) NULL)
4038 {
4039 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4040 PackageName);
4041 goto PerlException;
4042 }
4043 op=MeanEvaluateOperator;
4044 if (items == 2)
4045 {
4046 ssize_t
4047 in;
4048
4049 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
4050 SvPV(ST(1),na));
4051 if (in < 0)
4052 {
4053 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4054 SvPV(ST(1),na));
4055 return;
4056 }
4057 op=(MagickEvaluateOperator) in;
4058 }
4059 else
4060 for (i=2; i < items; i+=2)
4061 {
4062 attribute=(char *) SvPV(ST(i-1),na);
4063 switch (*attribute)
4064 {
4065 case 'O':
4066 case 'o':
4067 {
4068 if (LocaleCompare(attribute,"operator") == 0)
4069 {
4070 ssize_t
4071 in;
4072
4073 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4074 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4075 if (in < 0)
4076 {
4077 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4078 SvPV(ST(i),na));
4079 return;
4080 }
4081 op=(MagickEvaluateOperator) in;
4082 break;
4083 }
4084 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4085 attribute);
4086 break;
4087 }
4088 default:
4089 {
4090 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4091 attribute);
4092 break;
4093 }
4094 }
4095 }
4096 image=EvaluateImages(image,op,exception);
4097 if (image == (Image *) NULL)
4098 goto PerlException;
4099 /*
4100 Create blessed Perl array for the returned image.
4101 */
4102 av=newAV();
4103 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4104 SvREFCNT_dec(av);
4105 AddImageToRegistry(sv,image);
4106 rv=newRV(sv);
4107 av_push(av,sv_bless(rv,hv));
4108 SvREFCNT_dec(sv);
4109 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4110 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4111 "evaluate-%.*s",(int) (MagickPathExtent-9),
4112 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4113 (void) CopyMagickString(image->filename,info->image_info->filename,
4114 MagickPathExtent);
4115 SetImageInfo(info->image_info,0,exception);
4116 exception=DestroyExceptionInfo(exception);
4117 SvREFCNT_dec(perl_exception);
4118 XSRETURN(1);
4119
4120 PerlException:
4121 InheritPerlException(exception,perl_exception);
4122 exception=DestroyExceptionInfo(exception);
4123 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4124 SvPOK_on(perl_exception);
4125 ST(0)=sv_2mortal(perl_exception);
4126 XSRETURN(1);
4127 }
4128
4129 #
4130 ###############################################################################
4131 # #
4132 # #
4133 # #
4134 # F e a t u r e s #
4135 # #
4136 # #
4137 # #
4138 ###############################################################################
4139 #
4140 #
4141 void
Features(ref,...)4142 Features(ref,...)
4143 Image::Magick ref=NO_INIT
4144 ALIAS:
4145 FeaturesImage = 1
4146 features = 2
4147 featuresimage = 3
4148 PPCODE:
4149 {
4150 #define ChannelFeatures(channel,direction) \
4151 { \
4152 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4153 channel_features[channel].angular_second_moment[direction]); \
4154 PUSHs(sv_2mortal(newSVpv(message,0))); \
4155 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4156 channel_features[channel].contrast[direction]); \
4157 PUSHs(sv_2mortal(newSVpv(message,0))); \
4158 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4159 channel_features[channel].contrast[direction]); \
4160 PUSHs(sv_2mortal(newSVpv(message,0))); \
4161 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4162 channel_features[channel].variance_sum_of_squares[direction]); \
4163 PUSHs(sv_2mortal(newSVpv(message,0))); \
4164 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4165 channel_features[channel].inverse_difference_moment[direction]); \
4166 PUSHs(sv_2mortal(newSVpv(message,0))); \
4167 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4168 channel_features[channel].sum_average[direction]); \
4169 PUSHs(sv_2mortal(newSVpv(message,0))); \
4170 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4171 channel_features[channel].sum_variance[direction]); \
4172 PUSHs(sv_2mortal(newSVpv(message,0))); \
4173 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4174 channel_features[channel].sum_entropy[direction]); \
4175 PUSHs(sv_2mortal(newSVpv(message,0))); \
4176 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4177 channel_features[channel].entropy[direction]); \
4178 PUSHs(sv_2mortal(newSVpv(message,0))); \
4179 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4180 channel_features[channel].difference_variance[direction]); \
4181 PUSHs(sv_2mortal(newSVpv(message,0))); \
4182 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4183 channel_features[channel].difference_entropy[direction]); \
4184 PUSHs(sv_2mortal(newSVpv(message,0))); \
4185 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4186 channel_features[channel].measure_of_correlation_1[direction]); \
4187 PUSHs(sv_2mortal(newSVpv(message,0))); \
4188 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4189 channel_features[channel].measure_of_correlation_2[direction]); \
4190 PUSHs(sv_2mortal(newSVpv(message,0))); \
4191 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4192 channel_features[channel].maximum_correlation_coefficient[direction]); \
4193 PUSHs(sv_2mortal(newSVpv(message,0))); \
4194 }
4195
4196 AV
4197 *av;
4198
4199 char
4200 *attribute,
4201 message[MagickPathExtent];
4202
4203 ChannelFeatures
4204 *channel_features;
4205
4206 double
4207 distance;
4208
4209 ExceptionInfo
4210 *exception;
4211
4212 Image
4213 *image;
4214
4215 register ssize_t
4216 i;
4217
4218 ssize_t
4219 count;
4220
4221 struct PackageInfo
4222 *info;
4223
4224 SV
4225 *perl_exception,
4226 *reference;
4227
4228 PERL_UNUSED_VAR(ref);
4229 PERL_UNUSED_VAR(ix);
4230 exception=AcquireExceptionInfo();
4231 perl_exception=newSVpv("",0);
4232 av=NULL;
4233 if (sv_isobject(ST(0)) == 0)
4234 {
4235 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4236 PackageName);
4237 goto PerlException;
4238 }
4239 reference=SvRV(ST(0));
4240 av=newAV();
4241 SvREFCNT_dec(av);
4242 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4243 if (image == (Image *) NULL)
4244 {
4245 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4246 PackageName);
4247 goto PerlException;
4248 }
4249 distance=1.0;
4250 for (i=2; i < items; i+=2)
4251 {
4252 attribute=(char *) SvPV(ST(i-1),na);
4253 switch (*attribute)
4254 {
4255 case 'D':
4256 case 'd':
4257 {
4258 if (LocaleCompare(attribute,"distance") == 0)
4259 {
4260 distance=StringToLong((char *) SvPV(ST(1),na));
4261 break;
4262 }
4263 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4264 attribute);
4265 break;
4266 }
4267 default:
4268 {
4269 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4270 attribute);
4271 break;
4272 }
4273 }
4274 }
4275 count=0;
4276 for ( ; image; image=image->next)
4277 {
4278 register ssize_t
4279 j;
4280
4281 channel_features=GetImageFeatures(image,distance,exception);
4282 if (channel_features == (ChannelFeatures *) NULL)
4283 continue;
4284 count++;
4285 for (j=0; j < 4; j++)
4286 {
4287 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
4288 {
4289 PixelChannel channel=GetPixelChannelChannel(image,i);
4290 PixelTrait traits=GetPixelChannelTraits(image,channel);
4291 if (traits == UndefinedPixelTrait)
4292 continue;
4293 EXTEND(sp,14*(i+1)*count);
4294 ChannelFeatures(channel,j);
4295 }
4296 }
4297 channel_features=(ChannelFeatures *)
4298 RelinquishMagickMemory(channel_features);
4299 }
4300
4301 PerlException:
4302 InheritPerlException(exception,perl_exception);
4303 exception=DestroyExceptionInfo(exception);
4304 SvREFCNT_dec(perl_exception);
4305 }
4306
4307 #
4308 ###############################################################################
4309 # #
4310 # #
4311 # #
4312 # F l a t t e n #
4313 # #
4314 # #
4315 # #
4316 ###############################################################################
4317 #
4318 #
4319 void
Flatten(ref)4320 Flatten(ref)
4321 Image::Magick ref=NO_INIT
4322 ALIAS:
4323 FlattenImage = 1
4324 flatten = 2
4325 flattenimage = 3
4326 PPCODE:
4327 {
4328 AV
4329 *av;
4330
4331 char
4332 *attribute,
4333 *p;
4334
4335 ExceptionInfo
4336 *exception;
4337
4338 HV
4339 *hv;
4340
4341 Image
4342 *image;
4343
4344 PixelInfo
4345 background_color;
4346
4347 register ssize_t
4348 i;
4349
4350 struct PackageInfo
4351 *info;
4352
4353 SV
4354 *perl_exception,
4355 *reference,
4356 *rv,
4357 *sv;
4358
4359 PERL_UNUSED_VAR(ref);
4360 PERL_UNUSED_VAR(ix);
4361 exception=AcquireExceptionInfo();
4362 perl_exception=newSVpv("",0);
4363 sv=NULL;
4364 if (sv_isobject(ST(0)) == 0)
4365 {
4366 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4367 PackageName);
4368 goto PerlException;
4369 }
4370 reference=SvRV(ST(0));
4371 hv=SvSTASH(reference);
4372 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4373 if (image == (Image *) NULL)
4374 {
4375 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4376 PackageName);
4377 goto PerlException;
4378 }
4379 background_color=image->background_color;
4380 if (items == 2)
4381 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4382 &background_color,exception);
4383 else
4384 for (i=2; i < items; i+=2)
4385 {
4386 attribute=(char *) SvPV(ST(i-1),na);
4387 switch (*attribute)
4388 {
4389 case 'B':
4390 case 'b':
4391 {
4392 if (LocaleCompare(attribute,"background") == 0)
4393 {
4394 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4395 AllCompliance,&background_color,exception);
4396 break;
4397 }
4398 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4399 attribute);
4400 break;
4401 }
4402 default:
4403 {
4404 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4405 attribute);
4406 break;
4407 }
4408 }
4409 }
4410 image->background_color=background_color;
4411 image=MergeImageLayers(image,FlattenLayer,exception);
4412 if (image == (Image *) NULL)
4413 goto PerlException;
4414 /*
4415 Create blessed Perl array for the returned image.
4416 */
4417 av=newAV();
4418 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4419 SvREFCNT_dec(av);
4420 AddImageToRegistry(sv,image);
4421 rv=newRV(sv);
4422 av_push(av,sv_bless(rv,hv));
4423 SvREFCNT_dec(sv);
4424 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4425 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4426 "flatten-%.*s",(int) (MagickPathExtent-9),
4427 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4428 (void) CopyMagickString(image->filename,info->image_info->filename,
4429 MagickPathExtent);
4430 SetImageInfo(info->image_info,0,exception);
4431 exception=DestroyExceptionInfo(exception);
4432 SvREFCNT_dec(perl_exception);
4433 XSRETURN(1);
4434
4435 PerlException:
4436 InheritPerlException(exception,perl_exception);
4437 exception=DestroyExceptionInfo(exception);
4438 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4439 SvPOK_on(perl_exception); /* return messages in string context */
4440 ST(0)=sv_2mortal(perl_exception);
4441 XSRETURN(1);
4442 }
4443
4444 #
4445 ###############################################################################
4446 # #
4447 # #
4448 # #
4449 # F x #
4450 # #
4451 # #
4452 # #
4453 ###############################################################################
4454 #
4455 #
4456 void
Fx(ref,...)4457 Fx(ref,...)
4458 Image::Magick ref=NO_INIT
4459 ALIAS:
4460 FxImage = 1
4461 fx = 2
4462 fximage = 3
4463 PPCODE:
4464 {
4465 AV
4466 *av;
4467
4468 char
4469 *attribute,
4470 expression[MagickPathExtent];
4471
4472 ChannelType
4473 channel,
4474 channel_mask;
4475
4476 ExceptionInfo
4477 *exception;
4478
4479 HV
4480 *hv;
4481
4482 Image
4483 *image;
4484
4485 register ssize_t
4486 i;
4487
4488 struct PackageInfo
4489 *info;
4490
4491 SV
4492 *av_reference,
4493 *perl_exception,
4494 *reference,
4495 *rv,
4496 *sv;
4497
4498 PERL_UNUSED_VAR(ref);
4499 PERL_UNUSED_VAR(ix);
4500 exception=AcquireExceptionInfo();
4501 perl_exception=newSVpv("",0);
4502 sv=NULL;
4503 attribute=NULL;
4504 av=NULL;
4505 if (sv_isobject(ST(0)) == 0)
4506 {
4507 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4508 PackageName);
4509 goto PerlException;
4510 }
4511 reference=SvRV(ST(0));
4512 hv=SvSTASH(reference);
4513 av=newAV();
4514 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4515 SvREFCNT_dec(av);
4516 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4517 if (image == (Image *) NULL)
4518 {
4519 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4520 PackageName);
4521 goto PerlException;
4522 }
4523 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4524 /*
4525 Get options.
4526 */
4527 channel=DefaultChannels;
4528 (void) CopyMagickString(expression,"u",MagickPathExtent);
4529 if (items == 2)
4530 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
4531 else
4532 for (i=2; i < items; i+=2)
4533 {
4534 attribute=(char *) SvPV(ST(i-1),na);
4535 switch (*attribute)
4536 {
4537 case 'C':
4538 case 'c':
4539 {
4540 if (LocaleCompare(attribute,"channel") == 0)
4541 {
4542 ssize_t
4543 option;
4544
4545 option=ParseChannelOption(SvPV(ST(i),na));
4546 if (option < 0)
4547 {
4548 ThrowPerlException(exception,OptionError,
4549 "UnrecognizedType",SvPV(ST(i),na));
4550 return;
4551 }
4552 channel=(ChannelType) option;
4553 break;
4554 }
4555 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4556 attribute);
4557 break;
4558 }
4559 case 'E':
4560 case 'e':
4561 {
4562 if (LocaleCompare(attribute,"expression") == 0)
4563 {
4564 (void) CopyMagickString(expression,SvPV(ST(i),na),
4565 MagickPathExtent);
4566 break;
4567 }
4568 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4569 attribute);
4570 break;
4571 }
4572 default:
4573 {
4574 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4575 attribute);
4576 break;
4577 }
4578 }
4579 }
4580 channel_mask=SetImageChannelMask(image,channel);
4581 image=FxImage(image,expression,exception);
4582 if (image != (Image *) NULL)
4583 (void) SetImageChannelMask(image,channel_mask);
4584 if (image == (Image *) NULL)
4585 goto PerlException;
4586 for ( ; image; image=image->next)
4587 {
4588 AddImageToRegistry(sv,image);
4589 rv=newRV(sv);
4590 av_push(av,sv_bless(rv,hv));
4591 SvREFCNT_dec(sv);
4592 }
4593 exception=DestroyExceptionInfo(exception);
4594 ST(0)=av_reference;
4595 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4596 XSRETURN(1);
4597
4598 PerlException:
4599 InheritPerlException(exception,perl_exception);
4600 exception=DestroyExceptionInfo(exception);
4601 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4602 SvPOK_on(perl_exception);
4603 ST(0)=sv_2mortal(perl_exception);
4604 XSRETURN(1);
4605 }
4606
4607 #
4608 ###############################################################################
4609 # #
4610 # #
4611 # #
4612 # G e t #
4613 # #
4614 # #
4615 # #
4616 ###############################################################################
4617 #
4618 #
4619 void
Get(ref,...)4620 Get(ref,...)
4621 Image::Magick ref=NO_INIT
4622 ALIAS:
4623 GetAttributes = 1
4624 GetAttribute = 2
4625 get = 3
4626 getattributes = 4
4627 getattribute = 5
4628 PPCODE:
4629 {
4630 char
4631 *attribute,
4632 color[MagickPathExtent];
4633
4634 const char
4635 *value;
4636
4637 ExceptionInfo
4638 *exception;
4639
4640 Image
4641 *image;
4642
4643 long
4644 j;
4645
4646 register ssize_t
4647 i;
4648
4649 struct PackageInfo
4650 *info;
4651
4652 SV
4653 *perl_exception,
4654 *reference,
4655 *s;
4656
4657 PERL_UNUSED_VAR(ref);
4658 PERL_UNUSED_VAR(ix);
4659 exception=AcquireExceptionInfo();
4660 perl_exception=newSVpv("",0);
4661 if (sv_isobject(ST(0)) == 0)
4662 {
4663 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4664 PackageName);
4665 XSRETURN_EMPTY;
4666 }
4667 reference=SvRV(ST(0));
4668 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4669 if (image == (Image *) NULL && !info)
4670 XSRETURN_EMPTY;
4671 EXTEND(sp,items);
4672 for (i=1; i < items; i++)
4673 {
4674 attribute=(char *) SvPV(ST(i),na);
4675 s=NULL;
4676 switch (*attribute)
4677 {
4678 case 'A':
4679 case 'a':
4680 {
4681 if (LocaleCompare(attribute,"adjoin") == 0)
4682 {
4683 if (info)
4684 s=newSViv((ssize_t) info->image_info->adjoin);
4685 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4686 continue;
4687 }
4688 if (LocaleCompare(attribute,"antialias") == 0)
4689 {
4690 if (info)
4691 s=newSViv((ssize_t) info->image_info->antialias);
4692 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4693 continue;
4694 }
4695 if (LocaleCompare(attribute,"area") == 0)
4696 {
4697 s=newSViv(GetMagickResource(AreaResource));
4698 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4699 continue;
4700 }
4701 if (LocaleCompare(attribute,"attenuate") == 0)
4702 {
4703 const char
4704 *value;
4705
4706 value=GetImageProperty(image,attribute,exception);
4707 if (value != (const char *) NULL)
4708 s=newSVpv(value,0);
4709 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4710 continue;
4711 }
4712 if (LocaleCompare(attribute,"authenticate") == 0)
4713 {
4714 if (info)
4715 {
4716 const char
4717 *option;
4718
4719 option=GetImageOption(info->image_info,attribute);
4720 if (option != (const char *) NULL)
4721 s=newSVpv(option,0);
4722 }
4723 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4724 continue;
4725 }
4726 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4727 attribute);
4728 break;
4729 }
4730 case 'B':
4731 case 'b':
4732 {
4733 if (LocaleCompare(attribute,"background") == 0)
4734 {
4735 if (image == (Image *) NULL)
4736 break;
4737 (void) FormatLocaleString(color,MagickPathExtent,
4738 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4739 (double) image->background_color.green,
4740 (double) image->background_color.blue,
4741 (double) image->background_color.alpha);
4742 s=newSVpv(color,0);
4743 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4744 continue;
4745 }
4746 if (LocaleCompare(attribute,"base-columns") == 0)
4747 {
4748 if (image != (Image *) NULL)
4749 s=newSViv((ssize_t) image->magick_columns);
4750 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4751 continue;
4752 }
4753 if (LocaleCompare(attribute,"base-filename") == 0)
4754 {
4755 if (image != (Image *) NULL)
4756 s=newSVpv(image->magick_filename,0);
4757 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4758 continue;
4759 }
4760 if (LocaleCompare(attribute,"base-height") == 0)
4761 {
4762 if (image != (Image *) NULL)
4763 s=newSViv((ssize_t) image->magick_rows);
4764 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4765 continue;
4766 }
4767 if (LocaleCompare(attribute,"base-rows") == 0)
4768 {
4769 if (image != (Image *) NULL)
4770 s=newSViv((ssize_t) image->magick_rows);
4771 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4772 continue;
4773 }
4774 if (LocaleCompare(attribute,"base-width") == 0)
4775 {
4776 if (image != (Image *) NULL)
4777 s=newSViv((ssize_t) image->magick_columns);
4778 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4779 continue;
4780 }
4781 if (LocaleCompare(attribute,"blue-primary") == 0)
4782 {
4783 if (image == (Image *) NULL)
4784 break;
4785 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
4786 image->chromaticity.blue_primary.x,
4787 image->chromaticity.blue_primary.y);
4788 s=newSVpv(color,0);
4789 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4790 continue;
4791 }
4792 if (LocaleCompare(attribute,"bordercolor") == 0)
4793 {
4794 if (image == (Image *) NULL)
4795 break;
4796 (void) FormatLocaleString(color,MagickPathExtent,
4797 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4798 (double) image->border_color.green,
4799 (double) image->border_color.blue,
4800 (double) image->border_color.alpha);
4801 s=newSVpv(color,0);
4802 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4803 continue;
4804 }
4805 if (LocaleCompare(attribute,"bounding-box") == 0)
4806 {
4807 char
4808 geometry[MagickPathExtent];
4809
4810 RectangleInfo
4811 page;
4812
4813 if (image == (Image *) NULL)
4814 break;
4815 page=GetImageBoundingBox(image,exception);
4816 (void) FormatLocaleString(geometry,MagickPathExtent,
4817 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4818 page.height,(double) page.x,(double) page.y);
4819 s=newSVpv(geometry,0);
4820 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4821 continue;
4822 }
4823 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4824 attribute);
4825 break;
4826 }
4827 case 'C':
4828 case 'c':
4829 {
4830 if (LocaleCompare(attribute,"class") == 0)
4831 {
4832 if (image == (Image *) NULL)
4833 break;
4834 s=newSViv(image->storage_class);
4835 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4836 image->storage_class));
4837 SvIOK_on(s);
4838 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4839 continue;
4840 }
4841 if (LocaleCompare(attribute,"clip-mask") == 0)
4842 {
4843 if (image != (Image *) NULL)
4844 {
4845 Image
4846 *mask_image;
4847
4848 SV
4849 *sv;
4850
4851 sv=NULL;
4852 if (image->read_mask == MagickFalse)
4853 ClipImage(image,exception);
4854 mask_image=GetImageMask(image,ReadPixelMask,exception);
4855 if (mask_image != (Image *) NULL)
4856 {
4857 AddImageToRegistry(sv,mask_image);
4858 s=sv_bless(newRV(sv),SvSTASH(reference));
4859 }
4860 }
4861 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4862 continue;
4863 }
4864 if (LocaleCompare(attribute,"clip-path") == 0)
4865 {
4866 if (image != (Image *) NULL)
4867 {
4868 Image
4869 *mask_image;
4870
4871 SV
4872 *sv;
4873
4874 sv=NULL;
4875 if (image->read_mask != MagickFalse)
4876 ClipImage(image,exception);
4877 mask_image=GetImageMask(image,ReadPixelMask,exception);
4878 if (mask_image != (Image *) NULL)
4879 {
4880 AddImageToRegistry(sv,mask_image);
4881 s=sv_bless(newRV(sv),SvSTASH(reference));
4882 }
4883 }
4884 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4885 continue;
4886 }
4887 if (LocaleCompare(attribute,"compression") == 0)
4888 {
4889 j=info ? info->image_info->compression : image ?
4890 image->compression : UndefinedCompression;
4891 if (info)
4892 if (info->image_info->compression == UndefinedCompression)
4893 j=image->compression;
4894 s=newSViv(j);
4895 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4896 j));
4897 SvIOK_on(s);
4898 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4899 continue;
4900 }
4901 if (LocaleCompare(attribute,"colorspace") == 0)
4902 {
4903 j=image ? image->colorspace : RGBColorspace;
4904 s=newSViv(j);
4905 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4906 j));
4907 SvIOK_on(s);
4908 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4909 continue;
4910 }
4911 if (LocaleCompare(attribute,"colors") == 0)
4912 {
4913 if (image != (Image *) NULL)
4914 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4915 exception));
4916 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4917 continue;
4918 }
4919 if (LocaleNCompare(attribute,"colormap",8) == 0)
4920 {
4921 int
4922 items;
4923
4924 if (image == (Image *) NULL || !image->colormap)
4925 break;
4926 j=0;
4927 items=sscanf(attribute,"%*[^[][%ld",&j);
4928 (void) items;
4929 if (j > (ssize_t) image->colors)
4930 j%=image->colors;
4931 (void) FormatLocaleString(color,MagickPathExtent,
4932 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4933 (double) image->colormap[j].green,
4934 (double) image->colormap[j].blue,
4935 (double) image->colormap[j].alpha);
4936 s=newSVpv(color,0);
4937 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4938 continue;
4939 }
4940 if (LocaleCompare(attribute,"columns") == 0)
4941 {
4942 if (image != (Image *) NULL)
4943 s=newSViv((ssize_t) image->columns);
4944 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4945 continue;
4946 }
4947 if (LocaleCompare(attribute,"comment") == 0)
4948 {
4949 const char
4950 *value;
4951
4952 value=GetImageProperty(image,attribute,exception);
4953 if (value != (const char *) NULL)
4954 s=newSVpv(value,0);
4955 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4956 continue;
4957 }
4958 if (LocaleCompare(attribute,"copyright") == 0)
4959 {
4960 s=newSVpv(GetMagickCopyright(),0);
4961 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4962 continue;
4963 }
4964 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4965 attribute);
4966 break;
4967 }
4968 case 'D':
4969 case 'd':
4970 {
4971 if (LocaleCompare(attribute,"density") == 0)
4972 {
4973 char
4974 geometry[MagickPathExtent];
4975
4976 if (image == (Image *) NULL)
4977 break;
4978 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g",
4979 image->resolution.x,image->resolution.y);
4980 s=newSVpv(geometry,0);
4981 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4982 continue;
4983 }
4984 if (LocaleCompare(attribute,"delay") == 0)
4985 {
4986 if (image != (Image *) NULL)
4987 s=newSViv((ssize_t) image->delay);
4988 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4989 continue;
4990 }
4991 if (LocaleCompare(attribute,"depth") == 0)
4992 {
4993 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4994 if (image != (Image *) NULL)
4995 s=newSViv((ssize_t) GetImageDepth(image,exception));
4996 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4997 continue;
4998 }
4999 if (LocaleCompare(attribute,"directory") == 0)
5000 {
5001 if (image && image->directory)
5002 s=newSVpv(image->directory,0);
5003 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5004 continue;
5005 }
5006 if (LocaleCompare(attribute,"dispose") == 0)
5007 {
5008 if (image == (Image *) NULL)
5009 break;
5010
5011 s=newSViv(image->dispose);
5012 (void) sv_setpv(s,
5013 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
5014 SvIOK_on(s);
5015 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5016 continue;
5017 }
5018 if (LocaleCompare(attribute,"disk") == 0)
5019 {
5020 s=newSViv(GetMagickResource(DiskResource));
5021 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5022 continue;
5023 }
5024 if (LocaleCompare(attribute,"dither") == 0)
5025 {
5026 if (info)
5027 s=newSViv((ssize_t) info->image_info->dither);
5028 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5029 continue;
5030 }
5031 if (LocaleCompare(attribute,"display") == 0) /* same as server */
5032 {
5033 if (info && info->image_info->server_name)
5034 s=newSVpv(info->image_info->server_name,0);
5035 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5036 continue;
5037 }
5038 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5039 attribute);
5040 break;
5041 }
5042 case 'E':
5043 case 'e':
5044 {
5045 if (LocaleCompare(attribute,"elapsed-time") == 0)
5046 {
5047 if (image != (Image *) NULL)
5048 s=newSVnv(GetElapsedTime(&image->timer));
5049 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5050 continue;
5051 }
5052 if (LocaleCompare(attribute,"endian") == 0)
5053 {
5054 j=info ? info->image_info->endian : image ? image->endian :
5055 UndefinedEndian;
5056 s=newSViv(j);
5057 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
5058 SvIOK_on(s);
5059 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5060 continue;
5061 }
5062 if (LocaleCompare(attribute,"error") == 0)
5063 {
5064 if (image != (Image *) NULL)
5065 s=newSVnv(image->error.mean_error_per_pixel);
5066 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5067 continue;
5068 }
5069 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5070 attribute);
5071 break;
5072 }
5073 case 'F':
5074 case 'f':
5075 {
5076 if (LocaleCompare(attribute,"filesize") == 0)
5077 {
5078 if (image != (Image *) NULL)
5079 s=newSViv((ssize_t) GetBlobSize(image));
5080 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5081 continue;
5082 }
5083 if (LocaleCompare(attribute,"filename") == 0)
5084 {
5085 if (info && *info->image_info->filename)
5086 s=newSVpv(info->image_info->filename,0);
5087 if (image != (Image *) NULL)
5088 s=newSVpv(image->filename,0);
5089 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5090 continue;
5091 }
5092 if (LocaleCompare(attribute,"filter") == 0)
5093 {
5094 s=image ? newSViv(image->filter) : newSViv(0);
5095 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5096 image->filter));
5097 SvIOK_on(s);
5098 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5099 continue;
5100 }
5101 if (LocaleCompare(attribute,"font") == 0)
5102 {
5103 if (info && info->image_info->font)
5104 s=newSVpv(info->image_info->font,0);
5105 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5106 continue;
5107 }
5108 if (LocaleCompare(attribute,"foreground") == 0)
5109 continue;
5110 if (LocaleCompare(attribute,"format") == 0)
5111 {
5112 const MagickInfo
5113 *magick_info;
5114
5115 magick_info=(const MagickInfo *) NULL;
5116 if (info && (*info->image_info->magick != '\0'))
5117 magick_info=GetMagickInfo(info->image_info->magick,exception);
5118 if (image != (Image *) NULL)
5119 magick_info=GetMagickInfo(image->magick,exception);
5120 if ((magick_info != (const MagickInfo *) NULL) &&
5121 (*magick_info->description != '\0'))
5122 s=newSVpv((char *) magick_info->description,0);
5123 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5124 continue;
5125 }
5126 if (LocaleCompare(attribute,"fuzz") == 0)
5127 {
5128 if (info)
5129 s=newSVnv(info->image_info->fuzz);
5130 if (image != (Image *) NULL)
5131 s=newSVnv(image->fuzz);
5132 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5133 continue;
5134 }
5135 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5136 attribute);
5137 break;
5138 }
5139 case 'G':
5140 case 'g':
5141 {
5142 if (LocaleCompare(attribute,"gamma") == 0)
5143 {
5144 if (image != (Image *) NULL)
5145 s=newSVnv(image->gamma);
5146 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5147 continue;
5148 }
5149 if (LocaleCompare(attribute,"geometry") == 0)
5150 {
5151 if (image && image->geometry)
5152 s=newSVpv(image->geometry,0);
5153 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5154 continue;
5155 }
5156 if (LocaleCompare(attribute,"gravity") == 0)
5157 {
5158 s=image ? newSViv(image->gravity) : newSViv(0);
5159 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5160 image->gravity));
5161 SvIOK_on(s);
5162 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5163 continue;
5164 }
5165 if (LocaleCompare(attribute,"green-primary") == 0)
5166 {
5167 if (image == (Image *) NULL)
5168 break;
5169 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
5170 image->chromaticity.green_primary.x,
5171 image->chromaticity.green_primary.y);
5172 s=newSVpv(color,0);
5173 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5174 continue;
5175 }
5176 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5177 attribute);
5178 break;
5179 }
5180 case 'H':
5181 case 'h':
5182 {
5183 if (LocaleCompare(attribute,"height") == 0)
5184 {
5185 if (image != (Image *) NULL)
5186 s=newSViv((ssize_t) image->rows);
5187 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5188 continue;
5189 }
5190 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5191 attribute);
5192 break;
5193 }
5194 case 'I':
5195 case 'i':
5196 {
5197 if (LocaleCompare(attribute,"icc") == 0)
5198 {
5199 if (image != (Image *) NULL)
5200 {
5201 const StringInfo
5202 *profile;
5203
5204 profile=GetImageProfile(image,"icc");
5205 if (profile != (StringInfo *) NULL)
5206 s=newSVpv((const char *) GetStringInfoDatum(profile),
5207 GetStringInfoLength(profile));
5208 }
5209 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5210 continue;
5211 }
5212 if (LocaleCompare(attribute,"icm") == 0)
5213 {
5214 if (image != (Image *) NULL)
5215 {
5216 const StringInfo
5217 *profile;
5218
5219 profile=GetImageProfile(image,"icm");
5220 if (profile != (const StringInfo *) NULL)
5221 s=newSVpv((const char *) GetStringInfoDatum(profile),
5222 GetStringInfoLength(profile));
5223 }
5224 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5225 continue;
5226 }
5227 if (LocaleCompare(attribute,"id") == 0)
5228 {
5229 if (image != (Image *) NULL)
5230 {
5231 char
5232 key[MagickPathExtent];
5233
5234 MagickBooleanType
5235 status;
5236
5237 static ssize_t
5238 id = 0;
5239
5240 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
5241 id);
5242 status=SetImageRegistry(ImageRegistryType,key,image,
5243 exception);
5244 (void) status;
5245 s=newSViv(id++);
5246 }
5247 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5248 continue;
5249 }
5250 if (LocaleNCompare(attribute,"index",5) == 0)
5251 {
5252 char
5253 name[MagickPathExtent];
5254
5255 int
5256 items;
5257
5258 long
5259 x,
5260 y;
5261
5262 register const Quantum
5263 *p;
5264
5265 CacheView
5266 *image_view;
5267
5268 if (image == (Image *) NULL)
5269 break;
5270 if (image->storage_class != PseudoClass)
5271 break;
5272 x=0;
5273 y=0;
5274 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5275 (void) items;
5276 image_view=AcquireVirtualCacheView(image,exception);
5277 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5278 if (p != (const Quantum *) NULL)
5279 {
5280 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
5281 GetPixelIndex(image,p));
5282 s=newSVpv(name,0);
5283 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5284 }
5285 image_view=DestroyCacheView(image_view);
5286 continue;
5287 }
5288 if (LocaleCompare(attribute,"iptc") == 0)
5289 {
5290 if (image != (Image *) NULL)
5291 {
5292 const StringInfo
5293 *profile;
5294
5295 profile=GetImageProfile(image,"iptc");
5296 if (profile != (const StringInfo *) NULL)
5297 s=newSVpv((const char *) GetStringInfoDatum(profile),
5298 GetStringInfoLength(profile));
5299 }
5300 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5301 continue;
5302 }
5303 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5304 {
5305 if (image != (Image *) NULL)
5306 s=newSViv((ssize_t) image->iterations);
5307 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5308 continue;
5309 }
5310 if (LocaleCompare(attribute,"interlace") == 0)
5311 {
5312 j=info ? info->image_info->interlace : image ? image->interlace :
5313 UndefinedInterlace;
5314 s=newSViv(j);
5315 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5316 j));
5317 SvIOK_on(s);
5318 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5319 continue;
5320 }
5321 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5322 attribute);
5323 break;
5324 }
5325 case 'L':
5326 case 'l':
5327 {
5328 if (LocaleCompare(attribute,"label") == 0)
5329 {
5330 const char
5331 *value;
5332
5333 if (image == (Image *) NULL)
5334 break;
5335 value=GetImageProperty(image,"Label",exception);
5336 if (value != (const char *) NULL)
5337 s=newSVpv(value,0);
5338 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5339 continue;
5340 }
5341 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5342 {
5343 if (image != (Image *) NULL)
5344 s=newSViv((ssize_t) image->iterations);
5345 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5346 continue;
5347 }
5348 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5349 attribute);
5350 break;
5351 }
5352 case 'M':
5353 case 'm':
5354 {
5355 if (LocaleCompare(attribute,"magick") == 0)
5356 {
5357 if (info && *info->image_info->magick)
5358 s=newSVpv(info->image_info->magick,0);
5359 if (image != (Image *) NULL)
5360 s=newSVpv(image->magick,0);
5361 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5362 continue;
5363 }
5364 if (LocaleCompare(attribute,"map") == 0)
5365 {
5366 s=newSViv(GetMagickResource(MapResource));
5367 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5368 continue;
5369 }
5370 if (LocaleCompare(attribute,"maximum-error") == 0)
5371 {
5372 if (image != (Image *) NULL)
5373 s=newSVnv(image->error.normalized_maximum_error);
5374 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5375 continue;
5376 }
5377 if (LocaleCompare(attribute,"memory") == 0)
5378 {
5379 s=newSViv(GetMagickResource(MemoryResource));
5380 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5381 continue;
5382 }
5383 if (LocaleCompare(attribute,"mean-error") == 0)
5384 {
5385 if (image != (Image *) NULL)
5386 s=newSVnv(image->error.normalized_mean_error);
5387 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5388 continue;
5389 }
5390 if (LocaleCompare(attribute,"mime") == 0)
5391 {
5392 if (info && *info->image_info->magick)
5393 s=newSVpv(MagickToMime(info->image_info->magick),0);
5394 if (image != (Image *) NULL)
5395 s=newSVpv(MagickToMime(image->magick),0);
5396 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5397 continue;
5398 }
5399 if (LocaleCompare(attribute,"mattecolor") == 0)
5400 {
5401 if (image == (Image *) NULL)
5402 break;
5403 (void) FormatLocaleString(color,MagickPathExtent,
5404 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5405 (double) image->alpha_color.green,
5406 (double) image->alpha_color.blue,
5407 (double) image->alpha_color.alpha);
5408 s=newSVpv(color,0);
5409 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5410 continue;
5411 }
5412 if (LocaleCompare(attribute,"matte") == 0)
5413 {
5414 if (image != (Image *) NULL)
5415 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
5416 1 : 0);
5417 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5418 continue;
5419 }
5420 if (LocaleCompare(attribute,"mime") == 0)
5421 {
5422 const char
5423 *magick;
5424
5425 magick=NULL;
5426 if (info && *info->image_info->magick)
5427 magick=info->image_info->magick;
5428 if (image != (Image *) NULL)
5429 magick=image->magick;
5430 if (magick)
5431 {
5432 char
5433 *mime;
5434
5435 mime=MagickToMime(magick);
5436 s=newSVpv(mime,0);
5437 mime=(char *) RelinquishMagickMemory(mime);
5438 }
5439 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5440 continue;
5441 }
5442 if (LocaleCompare(attribute,"monochrome") == 0)
5443 {
5444 if (image == (Image *) NULL)
5445 continue;
5446 j=info ? info->image_info->monochrome :
5447 SetImageMonochrome(image,exception);
5448 s=newSViv(j);
5449 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5450 continue;
5451 }
5452 if (LocaleCompare(attribute,"montage") == 0)
5453 {
5454 if (image && image->montage)
5455 s=newSVpv(image->montage,0);
5456 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5457 continue;
5458 }
5459 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5460 attribute);
5461 break;
5462 }
5463 case 'O':
5464 case 'o':
5465 {
5466 if (LocaleCompare(attribute,"orientation") == 0)
5467 {
5468 j=info ? info->image_info->orientation : image ?
5469 image->orientation : UndefinedOrientation;
5470 s=newSViv(j);
5471 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5472 j));
5473 SvIOK_on(s);
5474 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5475 continue;
5476 }
5477 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5478 attribute);
5479 break;
5480 }
5481 case 'P':
5482 case 'p':
5483 {
5484 if (LocaleCompare(attribute,"page") == 0)
5485 {
5486 if (info && info->image_info->page)
5487 s=newSVpv(info->image_info->page,0);
5488 if (image != (Image *) NULL)
5489 {
5490 char
5491 geometry[MagickPathExtent];
5492
5493 (void) FormatLocaleString(geometry,MagickPathExtent,
5494 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5495 (double) image->page.height,(double) image->page.x,(double)
5496 image->page.y);
5497 s=newSVpv(geometry,0);
5498 }
5499 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5500 continue;
5501 }
5502 if (LocaleCompare(attribute,"page.x") == 0)
5503 {
5504 if (image != (Image *) NULL)
5505 s=newSViv((ssize_t) image->page.x);
5506 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5507 continue;
5508 }
5509 if (LocaleCompare(attribute,"page.y") == 0)
5510 {
5511 if (image != (Image *) NULL)
5512 s=newSViv((ssize_t) image->page.y);
5513 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5514 continue;
5515 }
5516 if (LocaleNCompare(attribute,"pixel",5) == 0)
5517 {
5518 char
5519 tuple[MagickPathExtent];
5520
5521 int
5522 items;
5523
5524 long
5525 x,
5526 y;
5527
5528 register const Quantum
5529 *p;
5530
5531 if (image == (Image *) NULL)
5532 break;
5533 x=0;
5534 y=0;
5535 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5536 (void) items;
5537 p=GetVirtualPixels(image,x,y,1,1,exception);
5538 if (image->colorspace != CMYKColorspace)
5539 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
5540 QuantumFormat "," QuantumFormat "," QuantumFormat,
5541 GetPixelRed(image,p),GetPixelGreen(image,p),
5542 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5543 else
5544 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
5545 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5546 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5547 GetPixelBlue(image,p),GetPixelBlack(image,p),
5548 GetPixelAlpha(image,p));
5549 s=newSVpv(tuple,0);
5550 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5551 continue;
5552 }
5553 if (LocaleCompare(attribute,"pointsize") == 0)
5554 {
5555 if (info)
5556 s=newSViv((ssize_t) info->image_info->pointsize);
5557 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5558 continue;
5559 }
5560 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5561 attribute);
5562 break;
5563 }
5564 case 'Q':
5565 case 'q':
5566 {
5567 if (LocaleCompare(attribute,"quality") == 0)
5568 {
5569 if (info)
5570 s=newSViv((ssize_t) info->image_info->quality);
5571 if (image != (Image *) NULL)
5572 s=newSViv((ssize_t) image->quality);
5573 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5574 continue;
5575 }
5576 if (LocaleCompare(attribute,"quantum") == 0)
5577 {
5578 if (info)
5579 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5580 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5581 continue;
5582 }
5583 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5584 attribute);
5585 break;
5586 }
5587 case 'R':
5588 case 'r':
5589 {
5590 if (LocaleCompare(attribute,"rendering-intent") == 0)
5591 {
5592 s=newSViv(image->rendering_intent);
5593 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5594 image->rendering_intent));
5595 SvIOK_on(s);
5596 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5597 continue;
5598 }
5599 if (LocaleCompare(attribute,"red-primary") == 0)
5600 {
5601 if (image == (Image *) NULL)
5602 break;
5603 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
5604 image->chromaticity.red_primary.x,
5605 image->chromaticity.red_primary.y);
5606 s=newSVpv(color,0);
5607 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5608 continue;
5609 }
5610 if (LocaleCompare(attribute,"rows") == 0)
5611 {
5612 if (image != (Image *) NULL)
5613 s=newSViv((ssize_t) image->rows);
5614 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5615 continue;
5616 }
5617 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5618 attribute);
5619 break;
5620 }
5621 case 'S':
5622 case 's':
5623 {
5624 if (LocaleCompare(attribute,"sampling-factor") == 0)
5625 {
5626 if (info && info->image_info->sampling_factor)
5627 s=newSVpv(info->image_info->sampling_factor,0);
5628 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5629 continue;
5630 }
5631 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5632 {
5633 if (info && info->image_info->server_name)
5634 s=newSVpv(info->image_info->server_name,0);
5635 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5636 continue;
5637 }
5638 if (LocaleCompare(attribute,"size") == 0)
5639 {
5640 if (info && info->image_info->size)
5641 s=newSVpv(info->image_info->size,0);
5642 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5643 continue;
5644 }
5645 if (LocaleCompare(attribute,"scene") == 0)
5646 {
5647 if (image != (Image *) NULL)
5648 s=newSViv((ssize_t) image->scene);
5649 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5650 continue;
5651 }
5652 if (LocaleCompare(attribute,"scenes") == 0)
5653 {
5654 if (image != (Image *) NULL)
5655 s=newSViv((ssize_t) info->image_info->number_scenes);
5656 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5657 continue;
5658 }
5659 if (LocaleCompare(attribute,"signature") == 0)
5660 {
5661 const char
5662 *value;
5663
5664 if (image == (Image *) NULL)
5665 break;
5666 (void) SignatureImage(image,exception);
5667 value=GetImageProperty(image,"Signature",exception);
5668 if (value != (const char *) NULL)
5669 s=newSVpv(value,0);
5670 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5671 continue;
5672 }
5673 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5674 attribute);
5675 break;
5676 }
5677 case 'T':
5678 case 't':
5679 {
5680 if (LocaleCompare(attribute,"taint") == 0)
5681 {
5682 if (image != (Image *) NULL)
5683 s=newSViv((ssize_t) IsTaintImage(image));
5684 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5685 continue;
5686 }
5687 if (LocaleCompare(attribute,"texture") == 0)
5688 {
5689 if (info && info->image_info->texture)
5690 s=newSVpv(info->image_info->texture,0);
5691 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5692 continue;
5693 }
5694 if (LocaleCompare(attribute,"total-ink-density") == 0)
5695 {
5696 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5697 if (image != (Image *) NULL)
5698 s=newSVnv(GetImageTotalInkDensity(image,exception));
5699 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5700 continue;
5701 }
5702 if (LocaleCompare(attribute,"transparent-color") == 0)
5703 {
5704 if (image == (Image *) NULL)
5705 break;
5706 (void) FormatLocaleString(color,MagickPathExtent,
5707 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5708 (double) image->transparent_color.green,
5709 (double) image->transparent_color.blue,
5710 (double) image->transparent_color.alpha);
5711 s=newSVpv(color,0);
5712 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5713 continue;
5714 }
5715 if (LocaleCompare(attribute,"type") == 0)
5716 {
5717 if (image == (Image *) NULL)
5718 break;
5719 j=(ssize_t) GetImageType(image);
5720 s=newSViv(j);
5721 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5722 SvIOK_on(s);
5723 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5724 continue;
5725 }
5726 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5727 attribute);
5728 break;
5729 }
5730 case 'U':
5731 case 'u':
5732 {
5733 if (LocaleCompare(attribute,"units") == 0)
5734 {
5735 j=info ? info->image_info->units : image ? image->units :
5736 UndefinedResolution;
5737 if (info && (info->image_info->units == UndefinedResolution))
5738 if (image)
5739 j=image->units;
5740 if (j == UndefinedResolution)
5741 s=newSVpv("undefined units",0);
5742 else
5743 if (j == PixelsPerInchResolution)
5744 s=newSVpv("pixels / inch",0);
5745 else
5746 s=newSVpv("pixels / centimeter",0);
5747 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5748 continue;
5749 }
5750 if (LocaleCompare(attribute,"user-time") == 0)
5751 {
5752 if (image != (Image *) NULL)
5753 s=newSVnv(GetUserTime(&image->timer));
5754 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5755 continue;
5756 }
5757 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5758 attribute);
5759 break;
5760 }
5761 case 'V':
5762 case 'v':
5763 {
5764 if (LocaleCompare(attribute,"verbose") == 0)
5765 {
5766 if (info)
5767 s=newSViv((ssize_t) info->image_info->verbose);
5768 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5769 continue;
5770 }
5771 if (LocaleCompare(attribute,"version") == 0)
5772 {
5773 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5774 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5775 continue;
5776 }
5777 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5778 {
5779 if (image == (Image *) NULL)
5780 break;
5781 j=(ssize_t) GetImageVirtualPixelMethod(image);
5782 s=newSViv(j);
5783 (void) sv_setpv(s,CommandOptionToMnemonic(
5784 MagickVirtualPixelOptions,j));
5785 SvIOK_on(s);
5786 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5787 continue;
5788 }
5789 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5790 attribute);
5791 break;
5792 }
5793 case 'W':
5794 case 'w':
5795 {
5796 if (LocaleCompare(attribute,"white-point") == 0)
5797 {
5798 if (image == (Image *) NULL)
5799 break;
5800 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
5801 image->chromaticity.white_point.x,
5802 image->chromaticity.white_point.y);
5803 s=newSVpv(color,0);
5804 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5805 continue;
5806 }
5807 if (LocaleCompare(attribute,"width") == 0)
5808 {
5809 if (image != (Image *) NULL)
5810 s=newSViv((ssize_t) image->columns);
5811 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5812 continue;
5813 }
5814 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5815 attribute);
5816 break;
5817 }
5818 case 'X':
5819 case 'x':
5820 {
5821 if (LocaleCompare(attribute,"xmp") == 0)
5822 {
5823 if (image != (Image *) NULL)
5824 {
5825 const StringInfo
5826 *profile;
5827
5828 profile=GetImageProfile(image,"xmp");
5829 if (profile != (StringInfo *) NULL)
5830 s=newSVpv((const char *) GetStringInfoDatum(profile),
5831 GetStringInfoLength(profile));
5832 }
5833 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5834 continue;
5835 }
5836 if (LocaleCompare(attribute,"x-resolution") == 0)
5837 {
5838 if (image != (Image *) NULL)
5839 s=newSVnv(image->resolution.x);
5840 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5841 continue;
5842 }
5843 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5844 attribute);
5845 break;
5846 }
5847 case 'Y':
5848 case 'y':
5849 {
5850 if (LocaleCompare(attribute,"y-resolution") == 0)
5851 {
5852 if (image != (Image *) NULL)
5853 s=newSVnv(image->resolution.y);
5854 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5855 continue;
5856 }
5857 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5858 attribute);
5859 break;
5860 }
5861 default:
5862 break;
5863 }
5864 if (image == (Image *) NULL)
5865 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5866 attribute)
5867 else
5868 {
5869 value=GetImageProperty(image,attribute,exception);
5870 if (value != (const char *) NULL)
5871 {
5872 s=newSVpv(value,0);
5873 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5874 }
5875 else
5876 if (*attribute != '%')
5877 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5878 attribute)
5879 else
5880 {
5881 char
5882 *meta;
5883
5884 meta=InterpretImageProperties(info ? info->image_info :
5885 (ImageInfo *) NULL,image,attribute,exception);
5886 s=newSVpv(meta,0);
5887 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5888 meta=(char *) RelinquishMagickMemory(meta);
5889 }
5890 }
5891 }
5892 exception=DestroyExceptionInfo(exception);
5893 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5894 }
5895
5896 #
5897 ###############################################################################
5898 # #
5899 # #
5900 # #
5901 # G e t A u t h e n t i c P i x e l s #
5902 # #
5903 # #
5904 # #
5905 ###############################################################################
5906 #
5907 #
5908 void *
GetAuthenticPixels(ref,...)5909 GetAuthenticPixels(ref,...)
5910 Image::Magick ref = NO_INIT
5911 ALIAS:
5912 getauthenticpixels = 1
5913 GetImagePixels = 2
5914 getimagepixels = 3
5915 CODE:
5916 {
5917 char
5918 *attribute;
5919
5920 ExceptionInfo
5921 *exception;
5922
5923 Image
5924 *image;
5925
5926 RectangleInfo
5927 region;
5928
5929 ssize_t
5930 i;
5931
5932 struct PackageInfo
5933 *info;
5934
5935 SV
5936 *perl_exception,
5937 *reference;
5938
5939 void
5940 *blob = NULL;
5941
5942 PERL_UNUSED_VAR(ref);
5943 PERL_UNUSED_VAR(ix);
5944 exception=AcquireExceptionInfo();
5945 perl_exception=newSVpv("",0);
5946 if (sv_isobject(ST(0)) == 0)
5947 {
5948 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5949 PackageName);
5950 goto PerlException;
5951 }
5952 reference=SvRV(ST(0));
5953
5954 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5955 if (image == (Image *) NULL)
5956 {
5957 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5958 PackageName);
5959 goto PerlException;
5960 }
5961
5962 region.x=0;
5963 region.y=0;
5964 region.width=image->columns;
5965 region.height=1;
5966 if (items == 1)
5967 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion);
5968 for (i=2; i < items; i+=2)
5969 {
5970 attribute=(char *) SvPV(ST(i-1),na);
5971 switch (*attribute)
5972 {
5973 case 'g':
5974 case 'G':
5975 {
5976 if (LocaleCompare(attribute,"geometry") == 0)
5977 {
5978 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion);
5979 break;
5980 }
5981 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5982 attribute);
5983 break;
5984 }
5985 case 'H':
5986 case 'h':
5987 {
5988 if (LocaleCompare(attribute,"height") == 0)
5989 {
5990 region.height=SvIV(ST(i));
5991 continue;
5992 }
5993 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5994 attribute);
5995 break;
5996 }
5997 case 'X':
5998 case 'x':
5999 {
6000 if (LocaleCompare(attribute,"x") == 0)
6001 {
6002 region.x=SvIV(ST(i));
6003 continue;
6004 }
6005 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6006 attribute);
6007 break;
6008 }
6009 case 'Y':
6010 case 'y':
6011 {
6012 if (LocaleCompare(attribute,"y") == 0)
6013 {
6014 region.y=SvIV(ST(i));
6015 continue;
6016 }
6017 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6018 attribute);
6019 break;
6020 }
6021 case 'W':
6022 case 'w':
6023 {
6024 if (LocaleCompare(attribute,"width") == 0)
6025 {
6026 region.width=SvIV(ST(i));
6027 continue;
6028 }
6029 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6030 attribute);
6031 break;
6032 }
6033 }
6034 }
6035 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
6036 region.height,exception);
6037 if (blob != (void *) NULL)
6038 goto PerlEnd;
6039
6040 PerlException:
6041 InheritPerlException(exception,perl_exception);
6042 exception=DestroyExceptionInfo(exception);
6043 SvREFCNT_dec(perl_exception); /* throw away all errors */
6044
6045 PerlEnd:
6046 RETVAL = blob;
6047 }
6048 OUTPUT:
6049 RETVAL
6050
6051 #
6052 ###############################################################################
6053 # #
6054 # #
6055 # #
6056 # G e t V i r t u a l P i x e l s #
6057 # #
6058 # #
6059 # #
6060 ###############################################################################
6061 #
6062 #
6063 void *
GetVirtualPixels(ref,...)6064 GetVirtualPixels(ref,...)
6065 Image::Magick ref = NO_INIT
6066 ALIAS:
6067 getvirtualpixels = 1
6068 AcquireImagePixels = 2
6069 acquireimagepixels = 3
6070 CODE:
6071 {
6072 char
6073 *attribute;
6074
6075 const void
6076 *blob = NULL;
6077
6078 ExceptionInfo
6079 *exception;
6080
6081 Image
6082 *image;
6083
6084 RectangleInfo
6085 region;
6086
6087 ssize_t
6088 i;
6089
6090 struct PackageInfo
6091 *info;
6092
6093 SV
6094 *perl_exception,
6095 *reference;
6096
6097 PERL_UNUSED_VAR(ref);
6098 PERL_UNUSED_VAR(ix);
6099 exception=AcquireExceptionInfo();
6100 perl_exception=newSVpv("",0);
6101 if (sv_isobject(ST(0)) == 0)
6102 {
6103 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6104 PackageName);
6105 goto PerlException;
6106 }
6107 reference=SvRV(ST(0));
6108
6109 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6110 if (image == (Image *) NULL)
6111 {
6112 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6113 PackageName);
6114 goto PerlException;
6115 }
6116
6117 region.x=0;
6118 region.y=0;
6119 region.width=image->columns;
6120 region.height=1;
6121 if (items == 1)
6122 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion);
6123 for (i=2; i < items; i+=2)
6124 {
6125 attribute=(char *) SvPV(ST(i-1),na);
6126 switch (*attribute)
6127 {
6128 case 'g':
6129 case 'G':
6130 {
6131 if (LocaleCompare(attribute,"geometry") == 0)
6132 {
6133 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion);
6134 break;
6135 }
6136 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6137 attribute);
6138 break;
6139 }
6140 case 'H':
6141 case 'h':
6142 {
6143 if (LocaleCompare(attribute,"height") == 0)
6144 {
6145 region.height=SvIV(ST(i));
6146 continue;
6147 }
6148 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6149 attribute);
6150 break;
6151 }
6152 case 'X':
6153 case 'x':
6154 {
6155 if (LocaleCompare(attribute,"x") == 0)
6156 {
6157 region.x=SvIV(ST(i));
6158 continue;
6159 }
6160 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6161 attribute);
6162 break;
6163 }
6164 case 'Y':
6165 case 'y':
6166 {
6167 if (LocaleCompare(attribute,"y") == 0)
6168 {
6169 region.y=SvIV(ST(i));
6170 continue;
6171 }
6172 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6173 attribute);
6174 break;
6175 }
6176 case 'W':
6177 case 'w':
6178 {
6179 if (LocaleCompare(attribute,"width") == 0)
6180 {
6181 region.width=SvIV(ST(i));
6182 continue;
6183 }
6184 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6185 attribute);
6186 break;
6187 }
6188 }
6189 }
6190 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6191 region.height,exception);
6192 if (blob != (void *) NULL)
6193 goto PerlEnd;
6194
6195 PerlException:
6196 InheritPerlException(exception,perl_exception);
6197 exception=DestroyExceptionInfo(exception);
6198 SvREFCNT_dec(perl_exception); /* throw away all errors */
6199
6200 PerlEnd:
6201 RETVAL = (void *) blob;
6202 }
6203 OUTPUT:
6204 RETVAL
6205
6206 #
6207 ###############################################################################
6208 # #
6209 # #
6210 # #
6211 # G e t A u t h e n t i c M e t a c o n t e n t #
6212 # #
6213 # #
6214 # #
6215 ###############################################################################
6216 #
6217 #
6218 void *
GetAuthenticMetacontent(ref,...)6219 GetAuthenticMetacontent(ref,...)
6220 Image::Magick ref = NO_INIT
6221 ALIAS:
6222 getauthenticmetacontent = 1
6223 GetMetacontent = 2
6224 getmetacontent = 3
6225 CODE:
6226 {
6227 ExceptionInfo
6228 *exception;
6229
6230 Image
6231 *image;
6232
6233 struct PackageInfo
6234 *info;
6235
6236 SV
6237 *perl_exception,
6238 *reference;
6239
6240 void
6241 *blob = NULL;
6242
6243 PERL_UNUSED_VAR(ref);
6244 PERL_UNUSED_VAR(ix);
6245 exception=AcquireExceptionInfo();
6246 perl_exception=newSVpv("",0);
6247 if (sv_isobject(ST(0)) == 0)
6248 {
6249 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6250 PackageName);
6251 goto PerlException;
6252 }
6253 reference=SvRV(ST(0));
6254
6255 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6256 if (image == (Image *) NULL)
6257 {
6258 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6259 PackageName);
6260 goto PerlException;
6261 }
6262
6263 blob=(void *) GetAuthenticMetacontent(image);
6264 if (blob != (void *) NULL)
6265 goto PerlEnd;
6266
6267 PerlException:
6268 InheritPerlException(exception,perl_exception);
6269 exception=DestroyExceptionInfo(exception);
6270 SvREFCNT_dec(perl_exception); /* throw away all errors */
6271
6272 PerlEnd:
6273 RETVAL = blob;
6274 }
6275 OUTPUT:
6276 RETVAL
6277
6278 #
6279 ###############################################################################
6280 # #
6281 # #
6282 # #
6283 # G e t V i r t u a l M e t a c o n t e n t #
6284 # #
6285 # #
6286 # #
6287 ###############################################################################
6288 #
6289 #
6290 void *
GetVirtualMetacontent(ref,...)6291 GetVirtualMetacontent(ref,...)
6292 Image::Magick ref = NO_INIT
6293 ALIAS:
6294 getvirtualmetacontent = 1
6295 CODE:
6296 {
6297 ExceptionInfo
6298 *exception;
6299
6300 Image
6301 *image;
6302
6303 struct PackageInfo
6304 *info;
6305
6306 SV
6307 *perl_exception,
6308 *reference;
6309
6310 void
6311 *blob = NULL;
6312
6313 PERL_UNUSED_VAR(ref);
6314 PERL_UNUSED_VAR(ix);
6315 exception=AcquireExceptionInfo();
6316 perl_exception=newSVpv("",0);
6317 if (sv_isobject(ST(0)) == 0)
6318 {
6319 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6320 PackageName);
6321 goto PerlException;
6322 }
6323 reference=SvRV(ST(0));
6324
6325 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6326 if (image == (Image *) NULL)
6327 {
6328 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6329 PackageName);
6330 goto PerlException;
6331 }
6332
6333 blob=(void *) GetVirtualMetacontent(image);
6334 if (blob != (void *) NULL)
6335 goto PerlEnd;
6336
6337 PerlException:
6338 InheritPerlException(exception,perl_exception);
6339 exception=DestroyExceptionInfo(exception);
6340 SvREFCNT_dec(perl_exception); /* throw away all errors */
6341
6342 PerlEnd:
6343 RETVAL = blob;
6344 }
6345 OUTPUT:
6346 RETVAL
6347
6348 #
6349 ###############################################################################
6350 # #
6351 # #
6352 # #
6353 # H i s t o g r a m #
6354 # #
6355 # #
6356 # #
6357 ###############################################################################
6358 #
6359 #
6360 void
Histogram(ref,...)6361 Histogram(ref,...)
6362 Image::Magick ref=NO_INIT
6363 ALIAS:
6364 HistogramImage = 1
6365 histogram = 2
6366 histogramimage = 3
6367 PPCODE:
6368 {
6369 AV
6370 *av;
6371
6372 char
6373 message[MagickPathExtent];
6374
6375 PixelInfo
6376 *histogram;
6377
6378 ExceptionInfo
6379 *exception;
6380
6381 Image
6382 *image;
6383
6384 register ssize_t
6385 i;
6386
6387 ssize_t
6388 count;
6389
6390 struct PackageInfo
6391 *info;
6392
6393 SV
6394 *perl_exception,
6395 *reference;
6396
6397 size_t
6398 number_colors;
6399
6400 PERL_UNUSED_VAR(ref);
6401 PERL_UNUSED_VAR(ix);
6402 exception=AcquireExceptionInfo();
6403 perl_exception=newSVpv("",0);
6404 av=NULL;
6405 if (sv_isobject(ST(0)) == 0)
6406 {
6407 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6408 PackageName);
6409 goto PerlException;
6410 }
6411 reference=SvRV(ST(0));
6412 av=newAV();
6413 SvREFCNT_dec(av);
6414 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6415 if (image == (Image *) NULL)
6416 {
6417 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6418 PackageName);
6419 goto PerlException;
6420 }
6421 count=0;
6422 for ( ; image; image=image->next)
6423 {
6424 histogram=GetImageHistogram(image,&number_colors,exception);
6425 if (histogram == (PixelInfo *) NULL)
6426 continue;
6427 count+=(ssize_t) number_colors;
6428 EXTEND(sp,6*count);
6429 for (i=0; i < (ssize_t) number_colors; i++)
6430 {
6431 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6432 histogram[i].red);
6433 PUSHs(sv_2mortal(newSVpv(message,0)));
6434 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6435 histogram[i].green);
6436 PUSHs(sv_2mortal(newSVpv(message,0)));
6437 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6438 histogram[i].blue);
6439 PUSHs(sv_2mortal(newSVpv(message,0)));
6440 if (image->colorspace == CMYKColorspace)
6441 {
6442 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6443 histogram[i].black);
6444 PUSHs(sv_2mortal(newSVpv(message,0)));
6445 }
6446 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6447 histogram[i].alpha);
6448 PUSHs(sv_2mortal(newSVpv(message,0)));
6449 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
6450 histogram[i].count);
6451 PUSHs(sv_2mortal(newSVpv(message,0)));
6452 }
6453 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6454 }
6455
6456 PerlException:
6457 InheritPerlException(exception,perl_exception);
6458 exception=DestroyExceptionInfo(exception);
6459 SvREFCNT_dec(perl_exception);
6460 }
6461
6462 #
6463 ###############################################################################
6464 # #
6465 # #
6466 # #
6467 # G e t P i x e l #
6468 # #
6469 # #
6470 # #
6471 ###############################################################################
6472 #
6473 #
6474 void
GetPixel(ref,...)6475 GetPixel(ref,...)
6476 Image::Magick ref=NO_INIT
6477 ALIAS:
6478 getpixel = 1
6479 getPixel = 2
6480 PPCODE:
6481 {
6482 AV
6483 *av;
6484
6485 char
6486 *attribute;
6487
6488 ExceptionInfo
6489 *exception;
6490
6491 Image
6492 *image;
6493
6494 MagickBooleanType
6495 normalize;
6496
6497 RectangleInfo
6498 region;
6499
6500 register const Quantum
6501 *p;
6502
6503 register ssize_t
6504 i;
6505
6506 ssize_t
6507 option;
6508
6509 struct PackageInfo
6510 *info;
6511
6512 SV
6513 *perl_exception,
6514 *reference; /* reference is the SV* of ref=SvIV(reference) */
6515
6516 PERL_UNUSED_VAR(ref);
6517 PERL_UNUSED_VAR(ix);
6518 exception=AcquireExceptionInfo();
6519 perl_exception=newSVpv("",0);
6520 reference=SvRV(ST(0));
6521 av=(AV *) reference;
6522 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6523 exception);
6524 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6525 if (image == (Image *) NULL)
6526 {
6527 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6528 PackageName);
6529 goto PerlException;
6530 }
6531 normalize=MagickTrue;
6532 region.x=0;
6533 region.y=0;
6534 region.width=image->columns;
6535 region.height=1;
6536 if (items == 1)
6537 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion);
6538 for (i=2; i < items; i+=2)
6539 {
6540 attribute=(char *) SvPV(ST(i-1),na);
6541 switch (*attribute)
6542 {
6543 case 'C':
6544 case 'c':
6545 {
6546 if (LocaleCompare(attribute,"channel") == 0)
6547 {
6548 ssize_t
6549 option;
6550
6551 option=ParseChannelOption(SvPV(ST(i),na));
6552 if (option < 0)
6553 {
6554 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6555 SvPV(ST(i),na));
6556 return;
6557 }
6558 (void) SetPixelChannelMask(image,(ChannelType) option);
6559 break;
6560 }
6561 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6562 attribute);
6563 break;
6564 }
6565 case 'g':
6566 case 'G':
6567 {
6568 if (LocaleCompare(attribute,"geometry") == 0)
6569 {
6570 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion);
6571 break;
6572 }
6573 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6574 attribute);
6575 break;
6576 }
6577 case 'N':
6578 case 'n':
6579 {
6580 if (LocaleCompare(attribute,"normalize") == 0)
6581 {
6582 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6583 SvPV(ST(i),na));
6584 if (option < 0)
6585 {
6586 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6587 SvPV(ST(i),na));
6588 break;
6589 }
6590 normalize=option != 0 ? MagickTrue : MagickFalse;
6591 break;
6592 }
6593 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6594 attribute);
6595 break;
6596 }
6597 case 'x':
6598 case 'X':
6599 {
6600 if (LocaleCompare(attribute,"x") == 0)
6601 {
6602 region.x=SvIV(ST(i));
6603 break;
6604 }
6605 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6606 attribute);
6607 break;
6608 }
6609 case 'y':
6610 case 'Y':
6611 {
6612 if (LocaleCompare(attribute,"y") == 0)
6613 {
6614 region.y=SvIV(ST(i));
6615 break;
6616 }
6617 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6618 attribute);
6619 break;
6620 }
6621 default:
6622 {
6623 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6624 attribute);
6625 break;
6626 }
6627 }
6628 }
6629 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6630 if (p == (const Quantum *) NULL)
6631 PUSHs(&sv_undef);
6632 else
6633 {
6634 double
6635 scale;
6636
6637 scale=1.0;
6638 if (normalize != MagickFalse)
6639 scale=1.0/QuantumRange;
6640 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6641 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6642 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6643 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6644 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6645 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6646 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6647 (image->colorspace == CMYKColorspace))
6648 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6649 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6650 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6651 }
6652
6653 PerlException:
6654 InheritPerlException(exception,perl_exception);
6655 exception=DestroyExceptionInfo(exception);
6656 SvREFCNT_dec(perl_exception);
6657 }
6658
6659 #
6660 ###############################################################################
6661 # #
6662 # #
6663 # #
6664 # G e t P i x e l s #
6665 # #
6666 # #
6667 # #
6668 ###############################################################################
6669 #
6670 #
6671 void
GetPixels(ref,...)6672 GetPixels(ref,...)
6673 Image::Magick ref=NO_INIT
6674 ALIAS:
6675 getpixels = 1
6676 getPixels = 2
6677 PPCODE:
6678 {
6679 AV
6680 *av;
6681
6682 char
6683 *attribute;
6684
6685 const char
6686 *map;
6687
6688 ExceptionInfo
6689 *exception;
6690
6691 Image
6692 *image;
6693
6694 MagickBooleanType
6695 normalize,
6696 status;
6697
6698 RectangleInfo
6699 region;
6700
6701 register ssize_t
6702 i;
6703
6704 ssize_t
6705 option;
6706
6707 struct PackageInfo
6708 *info;
6709
6710 SV
6711 *perl_exception,
6712 *reference; /* reference is the SV* of ref=SvIV(reference) */
6713
6714 PERL_UNUSED_VAR(ref);
6715 PERL_UNUSED_VAR(ix);
6716 exception=AcquireExceptionInfo();
6717 perl_exception=newSVpv("",0);
6718 reference=SvRV(ST(0));
6719 av=(AV *) reference;
6720 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6721 exception);
6722 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6723 if (image == (Image *) NULL)
6724 {
6725 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6726 PackageName);
6727 goto PerlException;
6728 }
6729 map="RGB";
6730 if (image->alpha_trait != UndefinedPixelTrait)
6731 map="RGBA";
6732 if (image->colorspace == CMYKColorspace)
6733 {
6734 map="CMYK";
6735 if (image->alpha_trait != UndefinedPixelTrait)
6736 map="CMYKA";
6737 }
6738 normalize=MagickFalse;
6739 region.x=0;
6740 region.y=0;
6741 region.width=image->columns;
6742 region.height=1;
6743 if (items == 1)
6744 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion);
6745 for (i=2; i < items; i+=2)
6746 {
6747 attribute=(char *) SvPV(ST(i-1),na);
6748 switch (*attribute)
6749 {
6750 case 'g':
6751 case 'G':
6752 {
6753 if (LocaleCompare(attribute,"geometry") == 0)
6754 {
6755 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion);
6756 break;
6757 }
6758 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6759 attribute);
6760 break;
6761 }
6762 case 'H':
6763 case 'h':
6764 {
6765 if (LocaleCompare(attribute,"height") == 0)
6766 {
6767 region.height=SvIV(ST(i));
6768 break;
6769 }
6770 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6771 attribute);
6772 break;
6773 }
6774 case 'M':
6775 case 'm':
6776 {
6777 if (LocaleCompare(attribute,"map") == 0)
6778 {
6779 map=SvPV(ST(i),na);
6780 break;
6781 }
6782 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6783 attribute);
6784 break;
6785 }
6786 case 'N':
6787 case 'n':
6788 {
6789 if (LocaleCompare(attribute,"normalize") == 0)
6790 {
6791 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6792 SvPV(ST(i),na));
6793 if (option < 0)
6794 {
6795 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6796 SvPV(ST(i),na));
6797 break;
6798 }
6799 normalize=option != 0 ? MagickTrue : MagickFalse;
6800 break;
6801 }
6802 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6803 attribute);
6804 break;
6805 }
6806 case 'W':
6807 case 'w':
6808 {
6809 if (LocaleCompare(attribute,"width") == 0)
6810 {
6811 region.width=SvIV(ST(i));
6812 break;
6813 }
6814 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6815 attribute);
6816 break;
6817 }
6818 case 'x':
6819 case 'X':
6820 {
6821 if (LocaleCompare(attribute,"x") == 0)
6822 {
6823 region.x=SvIV(ST(i));
6824 break;
6825 }
6826 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6827 attribute);
6828 break;
6829 }
6830 case 'y':
6831 case 'Y':
6832 {
6833 if (LocaleCompare(attribute,"y") == 0)
6834 {
6835 region.y=SvIV(ST(i));
6836 break;
6837 }
6838 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6839 attribute);
6840 break;
6841 }
6842 default:
6843 {
6844 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6845 attribute);
6846 break;
6847 }
6848 }
6849 }
6850 if (normalize != MagickFalse)
6851 {
6852 float
6853 *pixels;
6854
6855 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6856 region.height*sizeof(*pixels));
6857 if (pixels == (float *) NULL)
6858 {
6859 ThrowPerlException(exception,ResourceLimitError,
6860 "MemoryAllocationFailed",PackageName);
6861 goto PerlException;
6862 }
6863 status=ExportImagePixels(image,region.x,region.y,region.width,
6864 region.height,map,FloatPixel,pixels,exception);
6865 if (status == MagickFalse)
6866 PUSHs(&sv_undef);
6867 else
6868 {
6869 EXTEND(sp,strlen(map)*region.width*region.height);
6870 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6871 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6872 }
6873 pixels=(float *) RelinquishMagickMemory(pixels);
6874 }
6875 else
6876 {
6877 Quantum
6878 *pixels;
6879
6880 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6881 region.height*sizeof(*pixels));
6882 if (pixels == (Quantum *) NULL)
6883 {
6884 ThrowPerlException(exception,ResourceLimitError,
6885 "MemoryAllocationFailed",PackageName);
6886 goto PerlException;
6887 }
6888 status=ExportImagePixels(image,region.x,region.y,region.width,
6889 region.height,map,QuantumPixel,pixels,exception);
6890 if (status == MagickFalse)
6891 PUSHs(&sv_undef);
6892 else
6893 {
6894 EXTEND(sp,strlen(map)*region.width*region.height);
6895 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6896 PUSHs(sv_2mortal(newSViv(pixels[i])));
6897 }
6898 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6899 }
6900
6901 PerlException:
6902 InheritPerlException(exception,perl_exception);
6903 exception=DestroyExceptionInfo(exception);
6904 SvREFCNT_dec(perl_exception);
6905 }
6906
6907 #
6908 ###############################################################################
6909 # #
6910 # #
6911 # #
6912 # I m a g e T o B l o b #
6913 # #
6914 # #
6915 # #
6916 ###############################################################################
6917 #
6918 #
6919 void
ImageToBlob(ref,...)6920 ImageToBlob(ref,...)
6921 Image::Magick ref=NO_INIT
6922 ALIAS:
6923 ImageToBlob = 1
6924 imagetoblob = 2
6925 toblob = 3
6926 blob = 4
6927 PPCODE:
6928 {
6929 char
6930 filename[MagickPathExtent];
6931
6932 ExceptionInfo
6933 *exception;
6934
6935 Image
6936 *image,
6937 *next;
6938
6939 register ssize_t
6940 i;
6941
6942 struct PackageInfo
6943 *info,
6944 *package_info;
6945
6946 size_t
6947 length;
6948
6949 ssize_t
6950 scene;
6951
6952 SV
6953 *perl_exception,
6954 *reference;
6955
6956 void
6957 *blob;
6958
6959 PERL_UNUSED_VAR(ref);
6960 PERL_UNUSED_VAR(ix);
6961 exception=AcquireExceptionInfo();
6962 perl_exception=newSVpv("",0);
6963 package_info=(struct PackageInfo *) NULL;
6964 if (sv_isobject(ST(0)) == 0)
6965 {
6966 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6967 PackageName);
6968 goto PerlException;
6969 }
6970 reference=SvRV(ST(0));
6971 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6972 if (image == (Image *) NULL)
6973 {
6974 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6975 PackageName);
6976 goto PerlException;
6977 }
6978 package_info=ClonePackageInfo(info,exception);
6979 for (i=2; i < items; i+=2)
6980 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6981 (void) CopyMagickString(filename,package_info->image_info->filename,
6982 MagickPathExtent);
6983 scene=0;
6984 for (next=image; next; next=next->next)
6985 {
6986 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
6987 next->scene=scene++;
6988 }
6989 SetImageInfo(package_info->image_info,(unsigned int)
6990 GetImageListLength(image),exception);
6991 EXTEND(sp,(ssize_t) GetImageListLength(image));
6992 for ( ; image; image=image->next)
6993 {
6994 length=0;
6995 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6996 if (blob != (char *) NULL)
6997 {
6998 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6999 blob=(unsigned char *) RelinquishMagickMemory(blob);
7000 }
7001 if (package_info->image_info->adjoin)
7002 break;
7003 }
7004
7005 PerlException:
7006 if (package_info != (struct PackageInfo *) NULL)
7007 DestroyPackageInfo(package_info);
7008 InheritPerlException(exception,perl_exception);
7009 exception=DestroyExceptionInfo(exception);
7010 SvREFCNT_dec(perl_exception); /* throw away all errors */
7011 }
7012
7013 #
7014 ###############################################################################
7015 # #
7016 # #
7017 # #
7018 # L a y e r s #
7019 # #
7020 # #
7021 # #
7022 ###############################################################################
7023 #
7024 #
7025 void
Layers(ref,...)7026 Layers(ref,...)
7027 Image::Magick ref=NO_INIT
7028 ALIAS:
7029 Layers = 1
7030 layers = 2
7031 OptimizeImageLayers = 3
7032 optimizelayers = 4
7033 optimizeimagelayers = 5
7034 PPCODE:
7035 {
7036 AV
7037 *av;
7038
7039 char
7040 *attribute;
7041
7042 CompositeOperator
7043 compose;
7044
7045 ExceptionInfo
7046 *exception;
7047
7048 HV
7049 *hv;
7050
7051 Image
7052 *image,
7053 *layers;
7054
7055 LayerMethod
7056 method;
7057
7058 register ssize_t
7059 i;
7060
7061 ssize_t
7062 option,
7063 sp;
7064
7065 struct PackageInfo
7066 *info;
7067
7068 SV
7069 *av_reference,
7070 *perl_exception,
7071 *reference,
7072 *rv,
7073 *sv;
7074
7075 PERL_UNUSED_VAR(ref);
7076 PERL_UNUSED_VAR(ix);
7077 exception=AcquireExceptionInfo();
7078 perl_exception=newSVpv("",0);
7079 sv=NULL;
7080 if (sv_isobject(ST(0)) == 0)
7081 {
7082 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7083 PackageName);
7084 goto PerlException;
7085 }
7086 reference=SvRV(ST(0));
7087 hv=SvSTASH(reference);
7088 av=newAV();
7089 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7090 SvREFCNT_dec(av);
7091 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7092 if (image == (Image *) NULL)
7093 {
7094 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7095 PackageName);
7096 goto PerlException;
7097 }
7098 compose=image->compose;
7099 method=OptimizeLayer;
7100 for (i=2; i < items; i+=2)
7101 {
7102 attribute=(char *) SvPV(ST(i-1),na);
7103 switch (*attribute)
7104 {
7105 case 'C':
7106 case 'c':
7107 {
7108 if (LocaleCompare(attribute,"compose") == 0)
7109 {
7110 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7111 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7112 if (sp < 0)
7113 {
7114 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7115 SvPV(ST(i),na));
7116 break;
7117 }
7118 compose=(CompositeOperator) sp;
7119 break;
7120 }
7121 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7122 attribute);
7123 break;
7124 }
7125 case 'M':
7126 case 'm':
7127 {
7128 if (LocaleCompare(attribute,"method") == 0)
7129 {
7130 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7131 SvPV(ST(i),na));
7132 if (option < 0)
7133 {
7134 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7135 SvPV(ST(i),na));
7136 break;
7137 }
7138 method=(LayerMethod) option;
7139 break;
7140 }
7141 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7142 attribute);
7143 break;
7144 }
7145 default:
7146 {
7147 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7148 attribute);
7149 break;
7150 }
7151 }
7152 }
7153 layers=(Image *) NULL;
7154 switch (method)
7155 {
7156 case CompareAnyLayer:
7157 case CompareClearLayer:
7158 case CompareOverlayLayer:
7159 default:
7160 {
7161 layers=CompareImagesLayers(image,method,exception);
7162 break;
7163 }
7164 case MergeLayer:
7165 case FlattenLayer:
7166 case MosaicLayer:
7167 {
7168 layers=MergeImageLayers(image,method,exception);
7169 break;
7170 }
7171 case DisposeLayer:
7172 {
7173 layers=DisposeImages(image,exception);
7174 break;
7175 }
7176 case OptimizeImageLayer:
7177 {
7178 layers=OptimizeImageLayers(image,exception);
7179 break;
7180 }
7181 case OptimizePlusLayer:
7182 {
7183 layers=OptimizePlusImageLayers(image,exception);
7184 break;
7185 }
7186 case OptimizeTransLayer:
7187 {
7188 OptimizeImageTransparency(image,exception);
7189 break;
7190 }
7191 case RemoveDupsLayer:
7192 {
7193 RemoveDuplicateLayers(&image,exception);
7194 break;
7195 }
7196 case RemoveZeroLayer:
7197 {
7198 RemoveZeroDelayLayers(&image,exception);
7199 break;
7200 }
7201 case OptimizeLayer:
7202 {
7203 QuantizeInfo
7204 *quantize_info;
7205
7206 /*
7207 General Purpose, GIF Animation Optimizer.
7208 */
7209 layers=CoalesceImages(image,exception);
7210 if (layers == (Image *) NULL)
7211 break;
7212 image=layers;
7213 layers=OptimizeImageLayers(image,exception);
7214 if (layers == (Image *) NULL)
7215 break;
7216 image=DestroyImageList(image);
7217 image=layers;
7218 layers=(Image *) NULL;
7219 OptimizeImageTransparency(image,exception);
7220 quantize_info=AcquireQuantizeInfo(info->image_info);
7221 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7222 quantize_info=DestroyQuantizeInfo(quantize_info);
7223 break;
7224 }
7225 case CompositeLayer:
7226 {
7227 Image
7228 *source;
7229
7230 RectangleInfo
7231 geometry;
7232
7233 /*
7234 Split image sequence at the first 'NULL:' image.
7235 */
7236 source=image;
7237 while (source != (Image *) NULL)
7238 {
7239 source=GetNextImageInList(source);
7240 if ((source != (Image *) NULL) &&
7241 (LocaleCompare(source->magick,"NULL") == 0))
7242 break;
7243 }
7244 if (source != (Image *) NULL)
7245 {
7246 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7247 (GetNextImageInList(source) == (Image *) NULL))
7248 source=(Image *) NULL;
7249 else
7250 {
7251 /*
7252 Separate the two lists, junk the null: image.
7253 */
7254 source=SplitImageList(source->previous);
7255 DeleteImageFromList(&source);
7256 }
7257 }
7258 if (source == (Image *) NULL)
7259 {
7260 (void) ThrowMagickException(exception,GetMagickModule(),
7261 OptionError,"MissingNullSeparator","layers Composite");
7262 break;
7263 }
7264 /*
7265 Adjust offset with gravity and virtual canvas.
7266 */
7267 SetGeometry(image,&geometry);
7268 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7269 geometry.width=source->page.width != 0 ? source->page.width :
7270 source->columns;
7271 geometry.height=source->page.height != 0 ? source->page.height :
7272 source->rows;
7273 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7274 image->columns,image->page.height != 0 ? image->page.height :
7275 image->rows,image->gravity,&geometry);
7276 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7277 source=DestroyImageList(source);
7278 break;
7279 }
7280 }
7281 if (layers != (Image *) NULL)
7282 image=layers;
7283 else
7284 image=CloneImage(image,0,0,MagickTrue,exception);
7285 if (image == (Image *) NULL)
7286 goto PerlException;
7287 for ( ; image; image=image->next)
7288 {
7289 AddImageToRegistry(sv,image);
7290 rv=newRV(sv);
7291 av_push(av,sv_bless(rv,hv));
7292 SvREFCNT_dec(sv);
7293 }
7294 exception=DestroyExceptionInfo(exception);
7295 ST(0)=av_reference;
7296 SvREFCNT_dec(perl_exception);
7297 XSRETURN(1);
7298
7299 PerlException:
7300 InheritPerlException(exception,perl_exception);
7301 exception=DestroyExceptionInfo(exception);
7302 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7303 SvPOK_on(perl_exception);
7304 ST(0)=sv_2mortal(perl_exception);
7305 XSRETURN(1);
7306 }
7307
7308 #
7309 ###############################################################################
7310 # #
7311 # #
7312 # #
7313 # M a g i c k T o M i m e #
7314 # #
7315 # #
7316 # #
7317 ###############################################################################
7318 #
7319 #
7320 SV *
MagickToMime(ref,name)7321 MagickToMime(ref,name)
7322 Image::Magick ref=NO_INIT
7323 char *name
7324 ALIAS:
7325 magicktomime = 1
7326 CODE:
7327 {
7328 char
7329 *mime;
7330
7331 PERL_UNUSED_VAR(ref);
7332 PERL_UNUSED_VAR(ix);
7333 mime=MagickToMime(name);
7334 RETVAL=newSVpv(mime,0);
7335 mime=(char *) RelinquishMagickMemory(mime);
7336 }
7337 OUTPUT:
7338 RETVAL
7339
7340 #
7341 ###############################################################################
7342 # #
7343 # #
7344 # #
7345 # M o g r i f y #
7346 # #
7347 # #
7348 # #
7349 ###############################################################################
7350 #
7351 #
7352 void
Mogrify(ref,...)7353 Mogrify(ref,...)
7354 Image::Magick ref=NO_INIT
7355 ALIAS:
7356 Comment = 1
7357 CommentImage = 2
7358 Label = 3
7359 LabelImage = 4
7360 AddNoise = 5
7361 AddNoiseImage = 6
7362 Colorize = 7
7363 ColorizeImage = 8
7364 Border = 9
7365 BorderImage = 10
7366 Blur = 11
7367 BlurImage = 12
7368 Chop = 13
7369 ChopImage = 14
7370 Crop = 15
7371 CropImage = 16
7372 Despeckle = 17
7373 DespeckleImage = 18
7374 Edge = 19
7375 EdgeImage = 20
7376 Emboss = 21
7377 EmbossImage = 22
7378 Enhance = 23
7379 EnhanceImage = 24
7380 Flip = 25
7381 FlipImage = 26
7382 Flop = 27
7383 FlopImage = 28
7384 Frame = 29
7385 FrameImage = 30
7386 Implode = 31
7387 ImplodeImage = 32
7388 Magnify = 33
7389 MagnifyImage = 34
7390 MedianFilter = 35
7391 MedianConvolveImage = 36
7392 Minify = 37
7393 MinifyImage = 38
7394 OilPaint = 39
7395 OilPaintImage = 40
7396 ReduceNoise = 41
7397 ReduceNoiseImage = 42
7398 Roll = 43
7399 RollImage = 44
7400 Rotate = 45
7401 RotateImage = 46
7402 Sample = 47
7403 SampleImage = 48
7404 Scale = 49
7405 ScaleImage = 50
7406 Shade = 51
7407 ShadeImage = 52
7408 Sharpen = 53
7409 SharpenImage = 54
7410 Shear = 55
7411 ShearImage = 56
7412 Spread = 57
7413 SpreadImage = 58
7414 Swirl = 59
7415 SwirlImage = 60
7416 Resize = 61
7417 ResizeImage = 62
7418 Zoom = 63
7419 ZoomImage = 64
7420 Annotate = 65
7421 AnnotateImage = 66
7422 ColorFloodfill = 67
7423 ColorFloodfillImage= 68
7424 Composite = 69
7425 CompositeImage = 70
7426 Contrast = 71
7427 ContrastImage = 72
7428 CycleColormap = 73
7429 CycleColormapImage = 74
7430 Draw = 75
7431 DrawImage = 76
7432 Equalize = 77
7433 EqualizeImage = 78
7434 Gamma = 79
7435 GammaImage = 80
7436 Map = 81
7437 MapImage = 82
7438 MatteFloodfill = 83
7439 MatteFloodfillImage= 84
7440 Modulate = 85
7441 ModulateImage = 86
7442 Negate = 87
7443 NegateImage = 88
7444 Normalize = 89
7445 NormalizeImage = 90
7446 NumberColors = 91
7447 NumberColorsImage = 92
7448 Opaque = 93
7449 OpaqueImage = 94
7450 Quantize = 95
7451 QuantizeImage = 96
7452 Raise = 97
7453 RaiseImage = 98
7454 Segment = 99
7455 SegmentImage = 100
7456 Signature = 101
7457 SignatureImage = 102
7458 Solarize = 103
7459 SolarizeImage = 104
7460 Sync = 105
7461 SyncImage = 106
7462 Texture = 107
7463 TextureImage = 108
7464 Evaluate = 109
7465 EvaluateImage = 110
7466 Transparent = 111
7467 TransparentImage = 112
7468 Threshold = 113
7469 ThresholdImage = 114
7470 Charcoal = 115
7471 CharcoalImage = 116
7472 Trim = 117
7473 TrimImage = 118
7474 Wave = 119
7475 WaveImage = 120
7476 Separate = 121
7477 SeparateImage = 122
7478 Stereo = 125
7479 StereoImage = 126
7480 Stegano = 127
7481 SteganoImage = 128
7482 Deconstruct = 129
7483 DeconstructImage = 130
7484 GaussianBlur = 131
7485 GaussianBlurImage = 132
7486 Convolve = 133
7487 ConvolveImage = 134
7488 Profile = 135
7489 ProfileImage = 136
7490 UnsharpMask = 137
7491 UnsharpMaskImage = 138
7492 MotionBlur = 139
7493 MotionBlurImage = 140
7494 OrderedDither = 141
7495 OrderedDitherImage = 142
7496 Shave = 143
7497 ShaveImage = 144
7498 Level = 145
7499 LevelImage = 146
7500 Clip = 147
7501 ClipImage = 148
7502 AffineTransform = 149
7503 AffineTransformImage = 150
7504 Difference = 151
7505 DifferenceImage = 152
7506 AdaptiveThreshold = 153
7507 AdaptiveThresholdImage = 154
7508 Resample = 155
7509 ResampleImage = 156
7510 Describe = 157
7511 DescribeImage = 158
7512 BlackThreshold = 159
7513 BlackThresholdImage= 160
7514 WhiteThreshold = 161
7515 WhiteThresholdImage= 162
7516 RotationalBlur = 163
7517 RotationalBlurImage= 164
7518 Thumbnail = 165
7519 ThumbnailImage = 166
7520 Strip = 167
7521 StripImage = 168
7522 Tint = 169
7523 TintImage = 170
7524 Channel = 171
7525 ChannelImage = 172
7526 Splice = 173
7527 SpliceImage = 174
7528 Posterize = 175
7529 PosterizeImage = 176
7530 Shadow = 177
7531 ShadowImage = 178
7532 Identify = 179
7533 IdentifyImage = 180
7534 SepiaTone = 181
7535 SepiaToneImage = 182
7536 SigmoidalContrast = 183
7537 SigmoidalContrastImage = 184
7538 Extent = 185
7539 ExtentImage = 186
7540 Vignette = 187
7541 VignetteImage = 188
7542 ContrastStretch = 189
7543 ContrastStretchImage = 190
7544 Sans0 = 191
7545 Sans0Image = 192
7546 Sans1 = 193
7547 Sans1Image = 194
7548 AdaptiveSharpen = 195
7549 AdaptiveSharpenImage = 196
7550 Transpose = 197
7551 TransposeImage = 198
7552 Transverse = 199
7553 TransverseImage = 200
7554 AutoOrient = 201
7555 AutoOrientImage = 202
7556 AdaptiveBlur = 203
7557 AdaptiveBlurImage = 204
7558 Sketch = 205
7559 SketchImage = 206
7560 UniqueColors = 207
7561 UniqueColorsImage = 208
7562 AdaptiveResize = 209
7563 AdaptiveResizeImage= 210
7564 ClipMask = 211
7565 ClipMaskImage = 212
7566 LinearStretch = 213
7567 LinearStretchImage = 214
7568 ColorMatrix = 215
7569 ColorMatrixImage = 216
7570 Mask = 217
7571 MaskImage = 218
7572 Polaroid = 219
7573 PolaroidImage = 220
7574 FloodfillPaint = 221
7575 FloodfillPaintImage= 222
7576 Distort = 223
7577 DistortImage = 224
7578 Clut = 225
7579 ClutImage = 226
7580 LiquidRescale = 227
7581 LiquidRescaleImage = 228
7582 Encipher = 229
7583 EncipherImage = 230
7584 Decipher = 231
7585 DecipherImage = 232
7586 Deskew = 233
7587 DeskewImage = 234
7588 Remap = 235
7589 RemapImage = 236
7590 SparseColor = 237
7591 SparseColorImage = 238
7592 Function = 239
7593 FunctionImage = 240
7594 SelectiveBlur = 241
7595 SelectiveBlurImage = 242
7596 HaldClut = 243
7597 HaldClutImage = 244
7598 BlueShift = 245
7599 BlueShiftImage = 246
7600 ForwardFourierTransform = 247
7601 ForwardFourierTransformImage = 248
7602 InverseFourierTransform = 249
7603 InverseFourierTransformImage = 250
7604 ColorDecisionList = 251
7605 ColorDecisionListImage = 252
7606 AutoGamma = 253
7607 AutoGammaImage = 254
7608 AutoLevel = 255
7609 AutoLevelImage = 256
7610 LevelColors = 257
7611 LevelImageColors = 258
7612 Clamp = 259
7613 ClampImage = 260
7614 BrightnessContrast = 261
7615 BrightnessContrastImage = 262
7616 Morphology = 263
7617 MorphologyImage = 264
7618 Mode = 265
7619 ModeImage = 266
7620 Statistic = 267
7621 StatisticImage = 268
7622 Perceptible = 269
7623 PerceptibleImage = 270
7624 Poly = 271
7625 PolyImage = 272
7626 Grayscale = 273
7627 GrayscaleImage = 274
7628 CannyEdge = 275
7629 CannyEdgeImage = 276
7630 HoughLine = 277
7631 HoughLineImage = 278
7632 MeanShift = 279
7633 MeanShiftImage = 280
7634 Kuwahara = 281
7635 KuwaharaImage = 282
7636 ConnectedComponents = 283
7637 ConnectedComponentsImage = 284
7638 CopyPixels = 285
7639 CopyImagePixels = 286
7640 Color = 287
7641 ColorImage = 288
7642 WaveletDenoise = 289
7643 WaveletDenoiseImage= 290
7644 Colorspace = 291
7645 ColorspaceImage = 292
7646 AutoThreshold = 293
7647 AutoThresholdImage = 294
7648 RangeThreshold = 295
7649 RangeThresholdImage= 296
7650 CLAHE = 297
7651 CLAHEImage = 298
7652 Kmeans = 299
7653 KMeansImage = 300
7654 MogrifyRegion = 666
7655 PPCODE:
7656 {
7657 AffineMatrix
7658 affine,
7659 current;
7660
7661 char
7662 attribute_flag[MaxArguments],
7663 message[MagickPathExtent];
7664
7665 ChannelType
7666 channel,
7667 channel_mask;
7668
7669 CompositeOperator
7670 compose;
7671
7672 const char
7673 *attribute,
7674 *value;
7675
7676 double
7677 angle;
7678
7679 ExceptionInfo
7680 *exception;
7681
7682 GeometryInfo
7683 geometry_info;
7684
7685 Image
7686 *image,
7687 *next;
7688
7689 MagickStatusType
7690 flags;
7691
7692 PixelInfo
7693 fill_color;
7694
7695 RectangleInfo
7696 geometry,
7697 region_info;
7698
7699 register ssize_t
7700 i;
7701
7702 ssize_t
7703 base,
7704 j,
7705 number_images;
7706
7707 struct Methods
7708 *rp;
7709
7710 struct PackageInfo
7711 *info;
7712
7713 SV
7714 *perl_exception,
7715 **pv,
7716 *reference,
7717 **reference_vector;
7718
7719 struct ArgumentList
7720 argument_list[MaxArguments];
7721
7722 PERL_UNUSED_VAR(ref);
7723 PERL_UNUSED_VAR(ix);
7724 exception=AcquireExceptionInfo();
7725 perl_exception=newSVpv("",0);
7726 reference_vector=NULL;
7727 number_images=0;
7728 base=2;
7729 if (sv_isobject(ST(0)) == 0)
7730 {
7731 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7732 PackageName);
7733 goto PerlException;
7734 }
7735 reference=SvRV(ST(0));
7736 region_info.width=0;
7737 region_info.height=0;
7738 region_info.x=0;
7739 region_info.y=0;
7740 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7741 if (ix && (ix != 666))
7742 {
7743 /*
7744 Called as Method(...)
7745 */
7746 ix=(ix+1)/2;
7747 rp=(&Methods[ix-1]);
7748 attribute=rp->name;
7749 }
7750 else
7751 {
7752 /*
7753 Called as Mogrify("Method",...)
7754 */
7755 attribute=(char *) SvPV(ST(1),na);
7756 if (ix)
7757 {
7758 flags=ParseGravityGeometry(image,attribute,®ion_info,exception);
7759 attribute=(char *) SvPV(ST(2),na);
7760 base++;
7761 }
7762 for (rp=Methods; ; rp++)
7763 {
7764 if (rp >= EndOf(Methods))
7765 {
7766 ThrowPerlException(exception,OptionError,
7767 "UnrecognizedPerlMagickMethod",attribute);
7768 goto PerlException;
7769 }
7770 if (strEQcase(attribute,rp->name))
7771 break;
7772 }
7773 ix=rp-Methods+1;
7774 base++;
7775 }
7776 if (image == (Image *) NULL)
7777 {
7778 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7779 goto PerlException;
7780 }
7781 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7782 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7783 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7784 {
7785 Arguments
7786 *pp,
7787 *qq;
7788
7789 ssize_t
7790 ssize_test;
7791
7792 struct ArgumentList
7793 *al;
7794
7795 SV
7796 *sv;
7797
7798 sv=NULL;
7799 ssize_test=0;
7800 pp=(Arguments *) NULL;
7801 qq=rp->arguments;
7802 if (i == items)
7803 {
7804 pp=rp->arguments,
7805 sv=ST(i-1);
7806 }
7807 else
7808 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7809 {
7810 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7811 break;
7812 if (strEQcase(attribute,qq->method) > ssize_test)
7813 {
7814 pp=qq;
7815 ssize_test=strEQcase(attribute,qq->method);
7816 }
7817 }
7818 if (pp == (Arguments *) NULL)
7819 {
7820 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7821 attribute);
7822 goto continue_outer_loop;
7823 }
7824 al=(&argument_list[pp-rp->arguments]);
7825 switch (pp->type)
7826 {
7827 case ArrayReference:
7828 {
7829 if (SvTYPE(sv) != SVt_RV)
7830 {
7831 (void) FormatLocaleString(message,MagickPathExtent,
7832 "invalid %.60s value",pp->method);
7833 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7834 goto continue_outer_loop;
7835 }
7836 al->array_reference=SvRV(sv);
7837 break;
7838 }
7839 case RealReference:
7840 {
7841 al->real_reference=SvNV(sv);
7842 break;
7843 }
7844 case FileReference:
7845 {
7846 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7847 break;
7848 }
7849 case ImageReference:
7850 {
7851 if (!sv_isobject(sv) ||
7852 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7853 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7854 {
7855 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7856 PackageName);
7857 goto PerlException;
7858 }
7859 break;
7860 }
7861 case IntegerReference:
7862 {
7863 al->integer_reference=SvIV(sv);
7864 break;
7865 }
7866 case StringReference:
7867 {
7868 al->string_reference=(char *) SvPV(sv,al->length);
7869 if (sv_isobject(sv))
7870 al->image_reference=SetupList(aTHX_ SvRV(sv),
7871 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7872 break;
7873 }
7874 default:
7875 {
7876 /*
7877 Is a string; look up name.
7878 */
7879 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7880 {
7881 al->string_reference=(char *) SvPV(sv,al->length);
7882 al->integer_reference=(-1);
7883 break;
7884 }
7885 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7886 MagickFalse,SvPV(sv,na));
7887 if (pp->type == MagickChannelOptions)
7888 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7889 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7890 {
7891 (void) FormatLocaleString(message,MagickPathExtent,
7892 "invalid %.60s value",pp->method);
7893 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7894 goto continue_outer_loop;
7895 }
7896 break;
7897 }
7898 }
7899 attribute_flag[pp-rp->arguments]++;
7900 continue_outer_loop: ;
7901 }
7902 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7903 pv=reference_vector;
7904 SetGeometryInfo(&geometry_info);
7905 channel=DefaultChannels;
7906 for (next=image; next; next=next->next)
7907 {
7908 image=next;
7909 SetGeometry(image,&geometry);
7910 if ((region_info.width*region_info.height) != 0)
7911 (void) SetImageRegionMask(image,WritePixelMask,®ion_info,exception);
7912 switch (ix)
7913 {
7914 default:
7915 {
7916 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
7917 ThrowPerlException(exception,OptionError,
7918 "UnrecognizedPerlMagickMethod",message);
7919 goto PerlException;
7920 }
7921 case 1: /* Comment */
7922 {
7923 if (attribute_flag[0] == 0)
7924 argument_list[0].string_reference=(char *) NULL;
7925 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7926 info ? info->image_info : (ImageInfo *) NULL,image,
7927 argument_list[0].string_reference,exception),exception);
7928 break;
7929 }
7930 case 2: /* Label */
7931 {
7932 if (attribute_flag[0] == 0)
7933 argument_list[0].string_reference=(char *) NULL;
7934 (void) SetImageProperty(image,"label",InterpretImageProperties(
7935 info ? info->image_info : (ImageInfo *) NULL,image,
7936 argument_list[0].string_reference,exception),exception);
7937 break;
7938 }
7939 case 3: /* AddNoise */
7940 {
7941 double
7942 attenuate;
7943
7944 if (attribute_flag[0] == 0)
7945 argument_list[0].integer_reference=UniformNoise;
7946 attenuate=1.0;
7947 if (attribute_flag[1] != 0)
7948 attenuate=argument_list[1].real_reference;
7949 if (attribute_flag[2] != 0)
7950 channel=(ChannelType) argument_list[2].integer_reference;
7951 channel_mask=SetImageChannelMask(image,channel);
7952 image=AddNoiseImage(image,(NoiseType)
7953 argument_list[0].integer_reference,attenuate,exception);
7954 if (image != (Image *) NULL)
7955 (void) SetImageChannelMask(image,channel_mask);
7956 break;
7957 }
7958 case 4: /* Colorize */
7959 {
7960 PixelInfo
7961 target;
7962
7963 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7964 0,0,&target,exception);
7965 if (attribute_flag[0] != 0)
7966 (void) QueryColorCompliance(argument_list[0].string_reference,
7967 AllCompliance,&target,exception);
7968 if (attribute_flag[1] == 0)
7969 argument_list[1].string_reference="100%";
7970 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7971 exception);
7972 break;
7973 }
7974 case 5: /* Border */
7975 {
7976 CompositeOperator
7977 compose;
7978
7979 geometry.width=0;
7980 geometry.height=0;
7981 if (attribute_flag[0] != 0)
7982 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7983 &geometry,exception);
7984 if (attribute_flag[1] != 0)
7985 geometry.width=argument_list[1].integer_reference;
7986 if (attribute_flag[2] != 0)
7987 geometry.height=argument_list[2].integer_reference;
7988 if (attribute_flag[3] != 0)
7989 QueryColorCompliance(argument_list[3].string_reference,
7990 AllCompliance,&image->border_color,exception);
7991 if (attribute_flag[4] != 0)
7992 QueryColorCompliance(argument_list[4].string_reference,
7993 AllCompliance,&image->border_color,exception);
7994 if (attribute_flag[5] != 0)
7995 QueryColorCompliance(argument_list[5].string_reference,
7996 AllCompliance,&image->border_color,exception);
7997 compose=image->compose;
7998 if (attribute_flag[6] != 0)
7999 compose=(CompositeOperator) argument_list[6].integer_reference;
8000 image=BorderImage(image,&geometry,compose,exception);
8001 break;
8002 }
8003 case 6: /* Blur */
8004 {
8005 if (attribute_flag[0] != 0)
8006 {
8007 flags=ParseGeometry(argument_list[0].string_reference,
8008 &geometry_info);
8009 if ((flags & SigmaValue) == 0)
8010 geometry_info.sigma=1.0;
8011 }
8012 if (attribute_flag[1] != 0)
8013 geometry_info.rho=argument_list[1].real_reference;
8014 if (attribute_flag[2] != 0)
8015 geometry_info.sigma=argument_list[2].real_reference;
8016 if (attribute_flag[3] != 0)
8017 channel=(ChannelType) argument_list[3].integer_reference;
8018 channel_mask=SetImageChannelMask(image,channel);
8019 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
8020 exception);
8021 if (image != (Image *) NULL)
8022 (void) SetImageChannelMask(image,channel_mask);
8023 break;
8024 }
8025 case 7: /* Chop */
8026 {
8027 if (attribute_flag[5] != 0)
8028 image->gravity=(GravityType) argument_list[5].integer_reference;
8029 if (attribute_flag[0] != 0)
8030 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8031 &geometry,exception);
8032 if (attribute_flag[1] != 0)
8033 geometry.width=argument_list[1].integer_reference;
8034 if (attribute_flag[2] != 0)
8035 geometry.height=argument_list[2].integer_reference;
8036 if (attribute_flag[3] != 0)
8037 geometry.x=argument_list[3].integer_reference;
8038 if (attribute_flag[4] != 0)
8039 geometry.y=argument_list[4].integer_reference;
8040 image=ChopImage(image,&geometry,exception);
8041 break;
8042 }
8043 case 8: /* Crop */
8044 {
8045 if (attribute_flag[6] != 0)
8046 image->gravity=(GravityType) argument_list[6].integer_reference;
8047 if (attribute_flag[0] != 0)
8048 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8049 &geometry,exception);
8050 if (attribute_flag[1] != 0)
8051 geometry.width=argument_list[1].integer_reference;
8052 if (attribute_flag[2] != 0)
8053 geometry.height=argument_list[2].integer_reference;
8054 if (attribute_flag[3] != 0)
8055 geometry.x=argument_list[3].integer_reference;
8056 if (attribute_flag[4] != 0)
8057 geometry.y=argument_list[4].integer_reference;
8058 if (attribute_flag[5] != 0)
8059 image->fuzz=StringToDoubleInterval(
8060 argument_list[5].string_reference,(double) QuantumRange+1.0);
8061 image=CropImage(image,&geometry,exception);
8062 break;
8063 }
8064 case 9: /* Despeckle */
8065 {
8066 image=DespeckleImage(image,exception);
8067 break;
8068 }
8069 case 10: /* Edge */
8070 {
8071 if (attribute_flag[0] != 0)
8072 geometry_info.rho=argument_list[0].real_reference;
8073 image=EdgeImage(image,geometry_info.rho,exception);
8074 break;
8075 }
8076 case 11: /* Emboss */
8077 {
8078 if (attribute_flag[0] != 0)
8079 {
8080 flags=ParseGeometry(argument_list[0].string_reference,
8081 &geometry_info);
8082 if ((flags & SigmaValue) == 0)
8083 geometry_info.sigma=1.0;
8084 }
8085 if (attribute_flag[1] != 0)
8086 geometry_info.rho=argument_list[1].real_reference;
8087 if (attribute_flag[2] != 0)
8088 geometry_info.sigma=argument_list[2].real_reference;
8089 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8090 exception);
8091 break;
8092 }
8093 case 12: /* Enhance */
8094 {
8095 image=EnhanceImage(image,exception);
8096 break;
8097 }
8098 case 13: /* Flip */
8099 {
8100 image=FlipImage(image,exception);
8101 break;
8102 }
8103 case 14: /* Flop */
8104 {
8105 image=FlopImage(image,exception);
8106 break;
8107 }
8108 case 15: /* Frame */
8109 {
8110 CompositeOperator
8111 compose;
8112
8113 FrameInfo
8114 frame_info;
8115
8116 if (attribute_flag[0] != 0)
8117 {
8118 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8119 &geometry,exception);
8120 frame_info.width=geometry.width;
8121 frame_info.height=geometry.height;
8122 frame_info.outer_bevel=geometry.x;
8123 frame_info.inner_bevel=geometry.y;
8124 }
8125 if (attribute_flag[1] != 0)
8126 frame_info.width=argument_list[1].integer_reference;
8127 if (attribute_flag[2] != 0)
8128 frame_info.height=argument_list[2].integer_reference;
8129 if (attribute_flag[3] != 0)
8130 frame_info.inner_bevel=argument_list[3].integer_reference;
8131 if (attribute_flag[4] != 0)
8132 frame_info.outer_bevel=argument_list[4].integer_reference;
8133 if (attribute_flag[5] != 0)
8134 QueryColorCompliance(argument_list[5].string_reference,
8135 AllCompliance,&fill_color,exception);
8136 if (attribute_flag[6] != 0)
8137 QueryColorCompliance(argument_list[6].string_reference,
8138 AllCompliance,&fill_color,exception);
8139 frame_info.x=(ssize_t) frame_info.width;
8140 frame_info.y=(ssize_t) frame_info.height;
8141 frame_info.width=image->columns+2*frame_info.x;
8142 frame_info.height=image->rows+2*frame_info.y;
8143 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
8144 image->alpha_color=fill_color;
8145 compose=image->compose;
8146 if (attribute_flag[7] != 0)
8147 compose=(CompositeOperator) argument_list[7].integer_reference;
8148 image=FrameImage(image,&frame_info,compose,exception);
8149 break;
8150 }
8151 case 16: /* Implode */
8152 {
8153 PixelInterpolateMethod
8154 method;
8155
8156 if (attribute_flag[0] == 0)
8157 argument_list[0].real_reference=0.5;
8158 method=UndefinedInterpolatePixel;
8159 if (attribute_flag[1] != 0)
8160 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8161 image=ImplodeImage(image,argument_list[0].real_reference,
8162 method,exception);
8163 break;
8164 }
8165 case 17: /* Magnify */
8166 {
8167 image=MagnifyImage(image,exception);
8168 break;
8169 }
8170 case 18: /* MedianFilter */
8171 {
8172 if (attribute_flag[0] != 0)
8173 {
8174 flags=ParseGeometry(argument_list[0].string_reference,
8175 &geometry_info);
8176 if ((flags & SigmaValue) == 0)
8177 geometry_info.sigma=geometry_info.rho;
8178 }
8179 if (attribute_flag[1] != 0)
8180 geometry_info.rho=argument_list[1].real_reference;
8181 if (attribute_flag[2] != 0)
8182 geometry_info.sigma=argument_list[2].real_reference;
8183 if (attribute_flag[3] != 0)
8184 channel=(ChannelType) argument_list[3].integer_reference;
8185 channel_mask=SetImageChannelMask(image,channel);
8186 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8187 (size_t) geometry_info.sigma,exception);
8188 if (image != (Image *) NULL)
8189 (void) SetImageChannelMask(image,channel_mask);
8190 break;
8191 }
8192 case 19: /* Minify */
8193 {
8194 image=MinifyImage(image,exception);
8195 break;
8196 }
8197 case 20: /* OilPaint */
8198 {
8199 if (attribute_flag[0] == 0)
8200 argument_list[0].real_reference=0.0;
8201 if (attribute_flag[1] == 0)
8202 argument_list[1].real_reference=1.0;
8203 image=OilPaintImage(image,argument_list[0].real_reference,
8204 argument_list[1].real_reference,exception);
8205 break;
8206 }
8207 case 21: /* ReduceNoise */
8208 {
8209 if (attribute_flag[0] != 0)
8210 {
8211 flags=ParseGeometry(argument_list[0].string_reference,
8212 &geometry_info);
8213 if ((flags & SigmaValue) == 0)
8214 geometry_info.sigma=1.0;
8215 }
8216 if (attribute_flag[1] != 0)
8217 geometry_info.rho=argument_list[1].real_reference;
8218 if (attribute_flag[2] != 0)
8219 geometry_info.sigma=argument_list[2].real_reference;
8220 if (attribute_flag[3] != 0)
8221 channel=(ChannelType) argument_list[3].integer_reference;
8222 channel_mask=SetImageChannelMask(image,channel);
8223 image=StatisticImage(image,NonpeakStatistic,(size_t)
8224 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8225 if (image != (Image *) NULL)
8226 (void) SetImageChannelMask(image,channel_mask);
8227 break;
8228 }
8229 case 22: /* Roll */
8230 {
8231 if (attribute_flag[0] != 0)
8232 {
8233 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8234 &geometry,exception);
8235 if ((flags & PercentValue) != 0)
8236 {
8237 geometry.x*=(double) image->columns/100.0;
8238 geometry.y*=(double) image->rows/100.0;
8239 }
8240 }
8241 if (attribute_flag[1] != 0)
8242 geometry.x=argument_list[1].integer_reference;
8243 if (attribute_flag[2] != 0)
8244 geometry.y=argument_list[2].integer_reference;
8245 image=RollImage(image,geometry.x,geometry.y,exception);
8246 break;
8247 }
8248 case 23: /* Rotate */
8249 {
8250 if (attribute_flag[0] == 0)
8251 argument_list[0].real_reference=90.0;
8252 if (attribute_flag[1] != 0)
8253 {
8254 QueryColorCompliance(argument_list[1].string_reference,
8255 AllCompliance,&image->background_color,exception);
8256 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8257 (image->alpha_trait == UndefinedPixelTrait))
8258 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8259 }
8260 image=RotateImage(image,argument_list[0].real_reference,exception);
8261 break;
8262 }
8263 case 24: /* Sample */
8264 {
8265 if (attribute_flag[0] != 0)
8266 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8267 &geometry,exception);
8268 if (attribute_flag[1] != 0)
8269 geometry.width=argument_list[1].integer_reference;
8270 if (attribute_flag[2] != 0)
8271 geometry.height=argument_list[2].integer_reference;
8272 image=SampleImage(image,geometry.width,geometry.height,exception);
8273 break;
8274 }
8275 case 25: /* Scale */
8276 {
8277 if (attribute_flag[0] != 0)
8278 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8279 &geometry,exception);
8280 if (attribute_flag[1] != 0)
8281 geometry.width=argument_list[1].integer_reference;
8282 if (attribute_flag[2] != 0)
8283 geometry.height=argument_list[2].integer_reference;
8284 image=ScaleImage(image,geometry.width,geometry.height,exception);
8285 break;
8286 }
8287 case 26: /* Shade */
8288 {
8289 if (attribute_flag[0] != 0)
8290 {
8291 flags=ParseGeometry(argument_list[0].string_reference,
8292 &geometry_info);
8293 if ((flags & SigmaValue) == 0)
8294 geometry_info.sigma=0.0;
8295 }
8296 if (attribute_flag[1] != 0)
8297 geometry_info.rho=argument_list[1].real_reference;
8298 if (attribute_flag[2] != 0)
8299 geometry_info.sigma=argument_list[2].real_reference;
8300 image=ShadeImage(image,
8301 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8302 geometry_info.rho,geometry_info.sigma,exception);
8303 break;
8304 }
8305 case 27: /* Sharpen */
8306 {
8307 if (attribute_flag[0] != 0)
8308 {
8309 flags=ParseGeometry(argument_list[0].string_reference,
8310 &geometry_info);
8311 if ((flags & SigmaValue) == 0)
8312 geometry_info.sigma=1.0;
8313 }
8314 if (attribute_flag[1] != 0)
8315 geometry_info.rho=argument_list[1].real_reference;
8316 if (attribute_flag[2] != 0)
8317 geometry_info.sigma=argument_list[2].real_reference;
8318 if (attribute_flag[3] != 0)
8319 channel=(ChannelType) argument_list[3].integer_reference;
8320 channel_mask=SetImageChannelMask(image,channel);
8321 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8322 exception);
8323 if (image != (Image *) NULL)
8324 (void) SetImageChannelMask(image,channel_mask);
8325 break;
8326 }
8327 case 28: /* Shear */
8328 {
8329 if (attribute_flag[0] != 0)
8330 {
8331 flags=ParseGeometry(argument_list[0].string_reference,
8332 &geometry_info);
8333 if ((flags & SigmaValue) == 0)
8334 geometry_info.sigma=geometry_info.rho;
8335 }
8336 if (attribute_flag[1] != 0)
8337 geometry_info.rho=argument_list[1].real_reference;
8338 if (attribute_flag[2] != 0)
8339 geometry_info.sigma=argument_list[2].real_reference;
8340 if (attribute_flag[3] != 0)
8341 QueryColorCompliance(argument_list[3].string_reference,
8342 AllCompliance,&image->background_color,exception);
8343 if (attribute_flag[4] != 0)
8344 QueryColorCompliance(argument_list[4].string_reference,
8345 AllCompliance,&image->background_color,exception);
8346 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8347 exception);
8348 break;
8349 }
8350 case 29: /* Spread */
8351 {
8352 PixelInterpolateMethod
8353 method;
8354
8355 if (attribute_flag[0] == 0)
8356 argument_list[0].real_reference=1.0;
8357 method=UndefinedInterpolatePixel;
8358 if (attribute_flag[1] != 0)
8359 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8360 image=SpreadImage(image,method,argument_list[0].real_reference,
8361 exception);
8362 break;
8363 }
8364 case 30: /* Swirl */
8365 {
8366 PixelInterpolateMethod
8367 method;
8368
8369 if (attribute_flag[0] == 0)
8370 argument_list[0].real_reference=50.0;
8371 method=UndefinedInterpolatePixel;
8372 if (attribute_flag[1] != 0)
8373 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8374 image=SwirlImage(image,argument_list[0].real_reference,
8375 method,exception);
8376 break;
8377 }
8378 case 31: /* Resize */
8379 case 32: /* Zoom */
8380 {
8381 if (attribute_flag[0] != 0)
8382 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8383 &geometry,exception);
8384 if (attribute_flag[1] != 0)
8385 geometry.width=argument_list[1].integer_reference;
8386 if (attribute_flag[2] != 0)
8387 geometry.height=argument_list[2].integer_reference;
8388 if (attribute_flag[3] == 0)
8389 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8390 if (attribute_flag[4] != 0)
8391 SetImageArtifact(image,"filter:support",
8392 argument_list[4].string_reference);
8393 image=ResizeImage(image,geometry.width,geometry.height,
8394 (FilterType) argument_list[3].integer_reference,
8395 exception);
8396 break;
8397 }
8398 case 33: /* Annotate */
8399 {
8400 DrawInfo
8401 *draw_info;
8402
8403 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8404 (DrawInfo *) NULL);
8405 if (attribute_flag[0] != 0)
8406 {
8407 char
8408 *text;
8409
8410 text=InterpretImageProperties(info ? info->image_info :
8411 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8412 exception);
8413 (void) CloneString(&draw_info->text,text);
8414 text=DestroyString(text);
8415 }
8416 if (attribute_flag[1] != 0)
8417 (void) CloneString(&draw_info->font,
8418 argument_list[1].string_reference);
8419 if (attribute_flag[2] != 0)
8420 draw_info->pointsize=argument_list[2].real_reference;
8421 if (attribute_flag[3] != 0)
8422 (void) CloneString(&draw_info->density,
8423 argument_list[3].string_reference);
8424 if (attribute_flag[4] != 0)
8425 (void) QueryColorCompliance(argument_list[4].string_reference,
8426 AllCompliance,&draw_info->undercolor,exception);
8427 if (attribute_flag[5] != 0)
8428 {
8429 (void) QueryColorCompliance(argument_list[5].string_reference,
8430 AllCompliance,&draw_info->stroke,exception);
8431 if (argument_list[5].image_reference != (Image *) NULL)
8432 draw_info->stroke_pattern=CloneImage(
8433 argument_list[5].image_reference,0,0,MagickTrue,exception);
8434 }
8435 if (attribute_flag[6] != 0)
8436 {
8437 (void) QueryColorCompliance(argument_list[6].string_reference,
8438 AllCompliance,&draw_info->fill,exception);
8439 if (argument_list[6].image_reference != (Image *) NULL)
8440 draw_info->fill_pattern=CloneImage(
8441 argument_list[6].image_reference,0,0,MagickTrue,exception);
8442 }
8443 if (attribute_flag[7] != 0)
8444 {
8445 (void) CloneString(&draw_info->geometry,
8446 argument_list[7].string_reference);
8447 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8448 &geometry,exception);
8449 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8450 geometry_info.sigma=geometry_info.xi;
8451 }
8452 if (attribute_flag[8] != 0)
8453 (void) QueryColorCompliance(argument_list[8].string_reference,
8454 AllCompliance,&draw_info->fill,exception);
8455 if (attribute_flag[11] != 0)
8456 draw_info->gravity=(GravityType)
8457 argument_list[11].integer_reference;
8458 if (attribute_flag[25] != 0)
8459 {
8460 AV
8461 *av;
8462
8463 av=(AV *) argument_list[25].array_reference;
8464 if ((av_len(av) != 3) && (av_len(av) != 5))
8465 {
8466 ThrowPerlException(exception,OptionError,
8467 "affine matrix must have 4 or 6 elements",PackageName);
8468 goto PerlException;
8469 }
8470 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8471 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8472 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8473 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8474 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8475 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8476 {
8477 ThrowPerlException(exception,OptionError,
8478 "affine matrix is singular",PackageName);
8479 goto PerlException;
8480 }
8481 if (av_len(av) == 5)
8482 {
8483 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8484 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8485 }
8486 }
8487 for (j=12; j < 17; j++)
8488 {
8489 if (attribute_flag[j] == 0)
8490 continue;
8491 value=argument_list[j].string_reference;
8492 angle=argument_list[j].real_reference;
8493 current=draw_info->affine;
8494 GetAffineMatrix(&affine);
8495 switch (j)
8496 {
8497 case 12:
8498 {
8499 /*
8500 Translate.
8501 */
8502 flags=ParseGeometry(value,&geometry_info);
8503 affine.tx=geometry_info.xi;
8504 affine.ty=geometry_info.psi;
8505 if ((flags & PsiValue) == 0)
8506 affine.ty=affine.tx;
8507 break;
8508 }
8509 case 13:
8510 {
8511 /*
8512 Scale.
8513 */
8514 flags=ParseGeometry(value,&geometry_info);
8515 affine.sx=geometry_info.rho;
8516 affine.sy=geometry_info.sigma;
8517 if ((flags & SigmaValue) == 0)
8518 affine.sy=affine.sx;
8519 break;
8520 }
8521 case 14:
8522 {
8523 /*
8524 Rotate.
8525 */
8526 if (angle == 0.0)
8527 break;
8528 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8529 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8530 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8531 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8532 break;
8533 }
8534 case 15:
8535 {
8536 /*
8537 SkewX.
8538 */
8539 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8540 break;
8541 }
8542 case 16:
8543 {
8544 /*
8545 SkewY.
8546 */
8547 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8548 break;
8549 }
8550 }
8551 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8552 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8553 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8554 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8555 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8556 current.tx;
8557 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8558 current.ty;
8559 }
8560 if (attribute_flag[9] == 0)
8561 argument_list[9].real_reference=0.0;
8562 if (attribute_flag[10] == 0)
8563 argument_list[10].real_reference=0.0;
8564 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8565 {
8566 char
8567 geometry[MagickPathExtent];
8568
8569 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
8570 (double) argument_list[9].real_reference+draw_info->affine.tx,
8571 (double) argument_list[10].real_reference+draw_info->affine.ty);
8572 (void) CloneString(&draw_info->geometry,geometry);
8573 }
8574 if (attribute_flag[17] != 0)
8575 draw_info->stroke_width=argument_list[17].real_reference;
8576 if (attribute_flag[18] != 0)
8577 {
8578 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8579 MagickTrue : MagickFalse;
8580 draw_info->stroke_antialias=draw_info->text_antialias;
8581 }
8582 if (attribute_flag[19] != 0)
8583 (void) CloneString(&draw_info->family,
8584 argument_list[19].string_reference);
8585 if (attribute_flag[20] != 0)
8586 draw_info->style=(StyleType) argument_list[20].integer_reference;
8587 if (attribute_flag[21] != 0)
8588 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8589 if (attribute_flag[22] != 0)
8590 draw_info->weight=argument_list[22].integer_reference;
8591 if (attribute_flag[23] != 0)
8592 draw_info->align=(AlignType) argument_list[23].integer_reference;
8593 if (attribute_flag[24] != 0)
8594 (void) CloneString(&draw_info->encoding,
8595 argument_list[24].string_reference);
8596 if (attribute_flag[25] != 0)
8597 draw_info->fill_pattern=CloneImage(
8598 argument_list[25].image_reference,0,0,MagickTrue,exception);
8599 if (attribute_flag[26] != 0)
8600 draw_info->fill_pattern=CloneImage(
8601 argument_list[26].image_reference,0,0,MagickTrue,exception);
8602 if (attribute_flag[27] != 0)
8603 draw_info->stroke_pattern=CloneImage(
8604 argument_list[27].image_reference,0,0,MagickTrue,exception);
8605 if (attribute_flag[29] != 0)
8606 draw_info->kerning=argument_list[29].real_reference;
8607 if (attribute_flag[30] != 0)
8608 draw_info->interline_spacing=argument_list[30].real_reference;
8609 if (attribute_flag[31] != 0)
8610 draw_info->interword_spacing=argument_list[31].real_reference;
8611 if (attribute_flag[32] != 0)
8612 draw_info->direction=(DirectionType)
8613 argument_list[32].integer_reference;
8614 if (attribute_flag[33] != 0)
8615 draw_info->decorate=(DecorationType)
8616 argument_list[33].integer_reference;
8617 (void) AnnotateImage(image,draw_info,exception);
8618 draw_info=DestroyDrawInfo(draw_info);
8619 break;
8620 }
8621 case 34: /* ColorFloodfill */
8622 {
8623 DrawInfo
8624 *draw_info;
8625
8626 MagickBooleanType
8627 invert;
8628
8629 PixelInfo
8630 target;
8631
8632 draw_info=CloneDrawInfo(info ? info->image_info :
8633 (ImageInfo *) NULL,(DrawInfo *) NULL);
8634 if (attribute_flag[0] != 0)
8635 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8636 &geometry,exception);
8637 if (attribute_flag[1] != 0)
8638 geometry.x=argument_list[1].integer_reference;
8639 if (attribute_flag[2] != 0)
8640 geometry.y=argument_list[2].integer_reference;
8641 if (attribute_flag[3] != 0)
8642 (void) QueryColorCompliance(argument_list[3].string_reference,
8643 AllCompliance,&draw_info->fill,exception);
8644 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8645 geometry.x,geometry.y,&target,exception);
8646 invert=MagickFalse;
8647 if (attribute_flag[4] != 0)
8648 {
8649 QueryColorCompliance(argument_list[4].string_reference,
8650 AllCompliance,&target,exception);
8651 invert=MagickTrue;
8652 }
8653 if (attribute_flag[5] != 0)
8654 image->fuzz=StringToDoubleInterval(
8655 argument_list[5].string_reference,(double) QuantumRange+1.0);
8656 if (attribute_flag[6] != 0)
8657 invert=(MagickBooleanType) argument_list[6].integer_reference;
8658 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8659 geometry.y,invert,exception);
8660 draw_info=DestroyDrawInfo(draw_info);
8661 break;
8662 }
8663 case 35: /* Composite */
8664 {
8665 char
8666 composite_geometry[MagickPathExtent];
8667
8668 Image
8669 *composite_image,
8670 *rotate_image;
8671
8672 MagickBooleanType
8673 clip_to_self;
8674
8675 compose=OverCompositeOp;
8676 if (attribute_flag[0] != 0)
8677 composite_image=argument_list[0].image_reference;
8678 else
8679 {
8680 ThrowPerlException(exception,OptionError,
8681 "CompositeImageRequired",PackageName);
8682 goto PerlException;
8683 }
8684 /*
8685 Parameter Handling used for BOTH normal and tiled composition.
8686 */
8687 if (attribute_flag[1] != 0) /* compose */
8688 compose=(CompositeOperator) argument_list[1].integer_reference;
8689 if (attribute_flag[6] != 0) /* opacity */
8690 {
8691 if (compose != DissolveCompositeOp)
8692 (void) SetImageAlpha(composite_image,(Quantum)
8693 StringToDoubleInterval(argument_list[6].string_reference,
8694 (double) QuantumRange+1.0),exception);
8695 else
8696 {
8697 CacheView
8698 *composite_view;
8699
8700 double
8701 opacity;
8702
8703 MagickBooleanType
8704 sync;
8705
8706 register ssize_t
8707 x;
8708
8709 register Quantum
8710 *q;
8711
8712 ssize_t
8713 y;
8714
8715 /*
8716 Handle dissolve composite operator (patch by
8717 Kevin A. McGrail).
8718 */
8719 (void) CloneString(&image->geometry,
8720 argument_list[6].string_reference);
8721 opacity=(Quantum) StringToDoubleInterval(
8722 argument_list[6].string_reference,(double) QuantumRange+
8723 1.0);
8724 if (composite_image->alpha_trait != UndefinedPixelTrait)
8725 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8726 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8727 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8728 {
8729 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8730 composite_image->columns,1,exception);
8731 for (x=0; x < (ssize_t) composite_image->columns; x++)
8732 {
8733 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8734 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8735 q);
8736 q+=GetPixelChannels(composite_image);
8737 }
8738 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8739 if (sync == MagickFalse)
8740 break;
8741 }
8742 composite_view=DestroyCacheView(composite_view);
8743 }
8744 }
8745 if (attribute_flag[9] != 0) /* "color=>" */
8746 QueryColorCompliance(argument_list[9].string_reference,
8747 AllCompliance,&composite_image->background_color,exception);
8748 if (attribute_flag[12] != 0) /* "interpolate=>" */
8749 image->interpolate=(PixelInterpolateMethod)
8750 argument_list[12].integer_reference;
8751 if (attribute_flag[13] != 0) /* "args=>" */
8752 (void) SetImageArtifact(composite_image,"compose:args",
8753 argument_list[13].string_reference);
8754 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8755 (void) SetImageArtifact(composite_image,"compose:args",
8756 argument_list[14].string_reference);
8757 clip_to_self=MagickTrue;
8758 switch (compose)
8759 {
8760 case ClearCompositeOp:
8761 case SrcCompositeOp:
8762 case InCompositeOp:
8763 case SrcInCompositeOp:
8764 case OutCompositeOp:
8765 case SrcOutCompositeOp:
8766 case DstInCompositeOp:
8767 case DstAtopCompositeOp:
8768 case CopyAlphaCompositeOp:
8769 case ChangeMaskCompositeOp:
8770 case DissolveCompositeOp:
8771 case BlendCompositeOp:
8772 {
8773 clip_to_self=MagickFalse;
8774 break;
8775 }
8776 default:
8777 break;
8778 }
8779 if (attribute_flag[15] != 0)
8780 clip_to_self=(MagickBooleanType)
8781 argument_list[15].integer_reference;
8782 /*
8783 Tiling Composition (with orthogonal rotate).
8784 */
8785 rotate_image=(Image *) NULL;
8786 if (attribute_flag[8] != 0) /* "rotate=>" */
8787 {
8788 /*
8789 Rotate image.
8790 */
8791 rotate_image=RotateImage(composite_image,
8792 argument_list[8].real_reference,exception);
8793 if (rotate_image == (Image *) NULL)
8794 break;
8795 }
8796 if ((attribute_flag[7] != 0) &&
8797 (argument_list[7].integer_reference != 0)) /* tile */
8798 {
8799 ssize_t
8800 x,
8801 y;
8802
8803 /*
8804 Tile the composite image.
8805 */
8806 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8807 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8808 {
8809 if (attribute_flag[8] != 0) /* rotate */
8810 (void) CompositeImage(image,rotate_image,compose,
8811 MagickTrue,x,y,exception);
8812 else
8813 (void) CompositeImage(image,composite_image,compose,
8814 MagickTrue,x,y,exception);
8815 }
8816 if (attribute_flag[8] != 0) /* rotate */
8817 rotate_image=DestroyImage(rotate_image);
8818 break;
8819 }
8820 /*
8821 Parameter Handling used used ONLY for normal composition.
8822 */
8823 if (attribute_flag[5] != 0) /* gravity */
8824 image->gravity=(GravityType) argument_list[5].integer_reference;
8825 if (attribute_flag[2] != 0) /* geometry offset */
8826 {
8827 SetGeometry(image,&geometry);
8828 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8829 &geometry);
8830 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8831 &geometry);
8832 }
8833 if (attribute_flag[3] != 0) /* x offset */
8834 geometry.x=argument_list[3].integer_reference;
8835 if (attribute_flag[4] != 0) /* y offset */
8836 geometry.y=argument_list[4].integer_reference;
8837 if (attribute_flag[10] != 0) /* mask */
8838 {
8839 if ((image->compose == DisplaceCompositeOp) ||
8840 (image->compose == DistortCompositeOp))
8841 {
8842 /*
8843 Merge Y displacement into X displacement image.
8844 */
8845 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8846 exception);
8847 (void) CompositeImage(composite_image,
8848 argument_list[10].image_reference,CopyGreenCompositeOp,
8849 clip_to_self,0,0,exception);
8850 }
8851 else
8852 {
8853 Image
8854 *mask_image;
8855
8856 /*
8857 Set a blending mask for the composition.
8858 */
8859 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8860 MagickTrue,exception);
8861 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
8862 exception);
8863 mask_image=DestroyImage(mask_image);
8864 }
8865 }
8866 if (attribute_flag[11] != 0) /* channel */
8867 channel=(ChannelType) argument_list[11].integer_reference;
8868 /*
8869 Composite two images (normal composition).
8870 */
8871 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
8872 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8873 (double) composite_image->rows,(double) geometry.x,(double)
8874 geometry.y);
8875 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8876 exception);
8877 channel_mask=SetImageChannelMask(image,channel);
8878 if (attribute_flag[8] == 0) /* no rotate */
8879 CompositeImage(image,composite_image,compose,clip_to_self,
8880 geometry.x,geometry.y,exception);
8881 else
8882 {
8883 /*
8884 Position adjust rotated image then composite.
8885 */
8886 geometry.x-=(ssize_t) (rotate_image->columns-
8887 composite_image->columns)/2;
8888 geometry.y-=(ssize_t) (rotate_image->rows-
8889 composite_image->rows)/2;
8890 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8891 geometry.y,exception);
8892 rotate_image=DestroyImage(rotate_image);
8893 }
8894 if (attribute_flag[10] != 0) /* mask */
8895 {
8896 if ((image->compose == DisplaceCompositeOp) ||
8897 (image->compose == DistortCompositeOp))
8898 composite_image=DestroyImage(composite_image);
8899 else
8900 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
8901 exception);
8902 }
8903 (void) SetImageChannelMask(image,channel_mask);
8904 break;
8905 }
8906 case 36: /* Contrast */
8907 {
8908 if (attribute_flag[0] == 0)
8909 argument_list[0].integer_reference=0;
8910 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8911 MagickTrue : MagickFalse,exception);
8912 break;
8913 }
8914 case 37: /* CycleColormap */
8915 {
8916 if (attribute_flag[0] == 0)
8917 argument_list[0].integer_reference=6;
8918 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8919 exception);
8920 break;
8921 }
8922 case 38: /* Draw */
8923 {
8924 DrawInfo
8925 *draw_info;
8926
8927 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8928 (DrawInfo *) NULL);
8929 (void) CloneString(&draw_info->primitive,"point");
8930 if (attribute_flag[0] != 0)
8931 {
8932 if (argument_list[0].integer_reference < 0)
8933 (void) CloneString(&draw_info->primitive,
8934 argument_list[0].string_reference);
8935 else
8936 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8937 MagickPrimitiveOptions,argument_list[0].integer_reference));
8938 }
8939 if (attribute_flag[1] != 0)
8940 {
8941 if (LocaleCompare(draw_info->primitive,"path") == 0)
8942 {
8943 (void) ConcatenateString(&draw_info->primitive," '");
8944 ConcatenateString(&draw_info->primitive,
8945 argument_list[1].string_reference);
8946 (void) ConcatenateString(&draw_info->primitive,"'");
8947 }
8948 else
8949 {
8950 (void) ConcatenateString(&draw_info->primitive," ");
8951 ConcatenateString(&draw_info->primitive,
8952 argument_list[1].string_reference);
8953 }
8954 }
8955 if (attribute_flag[2] != 0)
8956 {
8957 (void) ConcatenateString(&draw_info->primitive," ");
8958 (void) ConcatenateString(&draw_info->primitive,
8959 CommandOptionToMnemonic(MagickMethodOptions,
8960 argument_list[2].integer_reference));
8961 }
8962 if (attribute_flag[3] != 0)
8963 {
8964 (void) QueryColorCompliance(argument_list[3].string_reference,
8965 AllCompliance,&draw_info->stroke,exception);
8966 if (argument_list[3].image_reference != (Image *) NULL)
8967 draw_info->stroke_pattern=CloneImage(
8968 argument_list[3].image_reference,0,0,MagickTrue,exception);
8969 }
8970 if (attribute_flag[4] != 0)
8971 {
8972 (void) QueryColorCompliance(argument_list[4].string_reference,
8973 AllCompliance,&draw_info->fill,exception);
8974 if (argument_list[4].image_reference != (Image *) NULL)
8975 draw_info->fill_pattern=CloneImage(
8976 argument_list[4].image_reference,0,0,MagickTrue,exception);
8977 }
8978 if (attribute_flag[5] != 0)
8979 draw_info->stroke_width=argument_list[5].real_reference;
8980 if (attribute_flag[6] != 0)
8981 (void) CloneString(&draw_info->font,
8982 argument_list[6].string_reference);
8983 if (attribute_flag[7] != 0)
8984 (void) QueryColorCompliance(argument_list[7].string_reference,
8985 AllCompliance,&draw_info->border_color,exception);
8986 if (attribute_flag[8] != 0)
8987 draw_info->affine.tx=argument_list[8].real_reference;
8988 if (attribute_flag[9] != 0)
8989 draw_info->affine.ty=argument_list[9].real_reference;
8990 if (attribute_flag[20] != 0)
8991 {
8992 AV
8993 *av;
8994
8995 av=(AV *) argument_list[20].array_reference;
8996 if ((av_len(av) != 3) && (av_len(av) != 5))
8997 {
8998 ThrowPerlException(exception,OptionError,
8999 "affine matrix must have 4 or 6 elements",PackageName);
9000 goto PerlException;
9001 }
9002 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9003 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9004 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9005 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9006 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9007 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9008 {
9009 ThrowPerlException(exception,OptionError,
9010 "affine matrix is singular",PackageName);
9011 goto PerlException;
9012 }
9013 if (av_len(av) == 5)
9014 {
9015 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9016 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9017 }
9018 }
9019 for (j=10; j < 15; j++)
9020 {
9021 if (attribute_flag[j] == 0)
9022 continue;
9023 value=argument_list[j].string_reference;
9024 angle=argument_list[j].real_reference;
9025 current=draw_info->affine;
9026 GetAffineMatrix(&affine);
9027 switch (j)
9028 {
9029 case 10:
9030 {
9031 /*
9032 Translate.
9033 */
9034 flags=ParseGeometry(value,&geometry_info);
9035 affine.tx=geometry_info.xi;
9036 affine.ty=geometry_info.psi;
9037 if ((flags & PsiValue) == 0)
9038 affine.ty=affine.tx;
9039 break;
9040 }
9041 case 11:
9042 {
9043 /*
9044 Scale.
9045 */
9046 flags=ParseGeometry(value,&geometry_info);
9047 affine.sx=geometry_info.rho;
9048 affine.sy=geometry_info.sigma;
9049 if ((flags & SigmaValue) == 0)
9050 affine.sy=affine.sx;
9051 break;
9052 }
9053 case 12:
9054 {
9055 /*
9056 Rotate.
9057 */
9058 if (angle == 0.0)
9059 break;
9060 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9061 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9062 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9063 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9064 break;
9065 }
9066 case 13:
9067 {
9068 /*
9069 SkewX.
9070 */
9071 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9072 break;
9073 }
9074 case 14:
9075 {
9076 /*
9077 SkewY.
9078 */
9079 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9080 break;
9081 }
9082 }
9083 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9084 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9085 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9086 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9087 draw_info->affine.tx=
9088 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9089 draw_info->affine.ty=
9090 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9091 }
9092 if (attribute_flag[15] != 0)
9093 draw_info->fill_pattern=CloneImage(
9094 argument_list[15].image_reference,0,0,MagickTrue,exception);
9095 if (attribute_flag[16] != 0)
9096 draw_info->pointsize=argument_list[16].real_reference;
9097 if (attribute_flag[17] != 0)
9098 {
9099 draw_info->stroke_antialias=argument_list[17].integer_reference != 0 ? MagickTrue : MagickFalse;
9100 draw_info->text_antialias=draw_info->stroke_antialias;
9101 }
9102 if (attribute_flag[18] != 0)
9103 (void) CloneString(&draw_info->density,
9104 argument_list[18].string_reference);
9105 if (attribute_flag[19] != 0)
9106 draw_info->stroke_width=argument_list[19].real_reference;
9107 if (attribute_flag[21] != 0)
9108 draw_info->dash_offset=argument_list[21].real_reference;
9109 if (attribute_flag[22] != 0)
9110 {
9111 AV
9112 *av;
9113
9114 av=(AV *) argument_list[22].array_reference;
9115 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9116 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9117 if (draw_info->dash_pattern != (double *) NULL)
9118 {
9119 for (i=0; i <= av_len(av); i++)
9120 draw_info->dash_pattern[i]=(double)
9121 SvNV(*(av_fetch(av,i,0)));
9122 draw_info->dash_pattern[i]=0.0;
9123 }
9124 }
9125 if (attribute_flag[23] != 0)
9126 image->interpolate=(PixelInterpolateMethod)
9127 argument_list[23].integer_reference;
9128 if ((attribute_flag[24] != 0) &&
9129 (draw_info->fill_pattern != (Image *) NULL))
9130 flags=ParsePageGeometry(draw_info->fill_pattern,
9131 argument_list[24].string_reference,
9132 &draw_info->fill_pattern->tile_offset,exception);
9133 if (attribute_flag[25] != 0)
9134 {
9135 (void) ConcatenateString(&draw_info->primitive," '");
9136 (void) ConcatenateString(&draw_info->primitive,
9137 argument_list[25].string_reference);
9138 (void) ConcatenateString(&draw_info->primitive,"'");
9139 }
9140 if (attribute_flag[26] != 0)
9141 draw_info->fill_pattern=CloneImage(
9142 argument_list[26].image_reference,0,0,MagickTrue,exception);
9143 if (attribute_flag[27] != 0)
9144 draw_info->stroke_pattern=CloneImage(
9145 argument_list[27].image_reference,0,0,MagickTrue,exception);
9146 if (attribute_flag[28] != 0)
9147 (void) CloneString(&draw_info->primitive,
9148 argument_list[28].string_reference);
9149 if (attribute_flag[29] != 0)
9150 draw_info->kerning=argument_list[29].real_reference;
9151 if (attribute_flag[30] != 0)
9152 draw_info->interline_spacing=argument_list[30].real_reference;
9153 if (attribute_flag[31] != 0)
9154 draw_info->interword_spacing=argument_list[31].real_reference;
9155 if (attribute_flag[32] != 0)
9156 draw_info->direction=(DirectionType)
9157 argument_list[32].integer_reference;
9158 (void) DrawImage(image,draw_info,exception);
9159 draw_info=DestroyDrawInfo(draw_info);
9160 break;
9161 }
9162 case 39: /* Equalize */
9163 {
9164 if (attribute_flag[0] != 0)
9165 channel=(ChannelType) argument_list[0].integer_reference;
9166 channel_mask=SetImageChannelMask(image,channel);
9167 (void) EqualizeImage(image,exception);
9168 (void) SetImageChannelMask(image,channel_mask);
9169 break;
9170 }
9171 case 40: /* Gamma */
9172 {
9173 if (attribute_flag[1] != 0)
9174 channel=(ChannelType) argument_list[1].integer_reference;
9175 if (attribute_flag[2] == 0)
9176 argument_list[2].real_reference=1.0;
9177 if (attribute_flag[3] == 0)
9178 argument_list[3].real_reference=1.0;
9179 if (attribute_flag[4] == 0)
9180 argument_list[4].real_reference=1.0;
9181 if (attribute_flag[0] == 0)
9182 {
9183 (void) FormatLocaleString(message,MagickPathExtent,
9184 "%.20g,%.20g,%.20g",(double) argument_list[2].real_reference,
9185 (double) argument_list[3].real_reference,
9186 (double) argument_list[4].real_reference);
9187 argument_list[0].string_reference=message;
9188 }
9189 (void) GammaImage(image,StringToDouble(
9190 argument_list[0].string_reference,(char **) NULL),exception);
9191 break;
9192 }
9193 case 41: /* Map */
9194 {
9195 QuantizeInfo
9196 *quantize_info;
9197
9198 if (attribute_flag[0] == 0)
9199 {
9200 ThrowPerlException(exception,OptionError,"MapImageRequired",
9201 PackageName);
9202 goto PerlException;
9203 }
9204 quantize_info=AcquireQuantizeInfo(info->image_info);
9205 if (attribute_flag[1] != 0)
9206 quantize_info->dither_method=(DitherMethod)
9207 argument_list[1].integer_reference;
9208 (void) RemapImages(quantize_info,image,
9209 argument_list[0].image_reference,exception);
9210 quantize_info=DestroyQuantizeInfo(quantize_info);
9211 break;
9212 }
9213 case 42: /* MatteFloodfill */
9214 {
9215 DrawInfo
9216 *draw_info;
9217
9218 MagickBooleanType
9219 invert;
9220
9221 PixelInfo
9222 target;
9223
9224 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9225 (DrawInfo *) NULL);
9226 if (attribute_flag[0] != 0)
9227 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9228 &geometry,exception);
9229 if (attribute_flag[1] != 0)
9230 geometry.x=argument_list[1].integer_reference;
9231 if (attribute_flag[2] != 0)
9232 geometry.y=argument_list[2].integer_reference;
9233 if (image->alpha_trait == UndefinedPixelTrait)
9234 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9235 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9236 geometry.x,geometry.y,&target,exception);
9237 if (attribute_flag[4] != 0)
9238 QueryColorCompliance(argument_list[4].string_reference,
9239 AllCompliance,&target,exception);
9240 if (attribute_flag[3] != 0)
9241 target.alpha=StringToDoubleInterval(
9242 argument_list[3].string_reference,(double) (double) QuantumRange+
9243 1.0);
9244 if (attribute_flag[5] != 0)
9245 image->fuzz=StringToDoubleInterval(
9246 argument_list[5].string_reference,(double) QuantumRange+1.0);
9247 invert=MagickFalse;
9248 if (attribute_flag[6] != 0)
9249 invert=(MagickBooleanType) argument_list[6].integer_reference;
9250 channel_mask=SetImageChannelMask(image,AlphaChannel);
9251 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9252 geometry.y,invert,exception);
9253 (void) SetImageChannelMask(image,channel_mask);
9254 draw_info=DestroyDrawInfo(draw_info);
9255 break;
9256 }
9257 case 43: /* Modulate */
9258 {
9259 char
9260 modulate[MagickPathExtent];
9261
9262 geometry_info.rho=100.0;
9263 geometry_info.sigma=100.0;
9264 geometry_info.xi=100.0;
9265 if (attribute_flag[0] != 0)
9266 (void)ParseGeometry(argument_list[0].string_reference,
9267 &geometry_info);
9268 if (attribute_flag[1] != 0)
9269 geometry_info.xi=argument_list[1].real_reference;
9270 if (attribute_flag[2] != 0)
9271 geometry_info.sigma=argument_list[2].real_reference;
9272 if (attribute_flag[3] != 0)
9273 {
9274 geometry_info.sigma=argument_list[3].real_reference;
9275 SetImageArtifact(image,"modulate:colorspace","HWB");
9276 }
9277 if (attribute_flag[4] != 0)
9278 {
9279 geometry_info.rho=argument_list[4].real_reference;
9280 SetImageArtifact(image,"modulate:colorspace","HSB");
9281 }
9282 if (attribute_flag[5] != 0)
9283 {
9284 geometry_info.sigma=argument_list[5].real_reference;
9285 SetImageArtifact(image,"modulate:colorspace","HSL");
9286 }
9287 if (attribute_flag[6] != 0)
9288 {
9289 geometry_info.rho=argument_list[6].real_reference;
9290 SetImageArtifact(image,"modulate:colorspace","HWB");
9291 }
9292 (void) FormatLocaleString(modulate,MagickPathExtent,"%.20g,%.20g,%.20g",
9293 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9294 (void) ModulateImage(image,modulate,exception);
9295 break;
9296 }
9297 case 44: /* Negate */
9298 {
9299 if (attribute_flag[0] == 0)
9300 argument_list[0].integer_reference=0;
9301 if (attribute_flag[1] != 0)
9302 channel=(ChannelType) argument_list[1].integer_reference;
9303 channel_mask=SetImageChannelMask(image,channel);
9304 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9305 MagickTrue : MagickFalse,exception);
9306 (void) SetImageChannelMask(image,channel_mask);
9307 break;
9308 }
9309 case 45: /* Normalize */
9310 {
9311 if (attribute_flag[0] != 0)
9312 channel=(ChannelType) argument_list[0].integer_reference;
9313 channel_mask=SetImageChannelMask(image,channel);
9314 NormalizeImage(image,exception);
9315 (void) SetImageChannelMask(image,channel_mask);
9316 break;
9317 }
9318 case 46: /* NumberColors */
9319 break;
9320 case 47: /* Opaque */
9321 {
9322 MagickBooleanType
9323 invert;
9324
9325 PixelInfo
9326 fill_color,
9327 target;
9328
9329 (void) QueryColorCompliance("none",AllCompliance,&target,
9330 exception);
9331 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9332 exception);
9333 if (attribute_flag[0] != 0)
9334 (void) QueryColorCompliance(argument_list[0].string_reference,
9335 AllCompliance,&target,exception);
9336 if (attribute_flag[1] != 0)
9337 (void) QueryColorCompliance(argument_list[1].string_reference,
9338 AllCompliance,&fill_color,exception);
9339 if (attribute_flag[2] != 0)
9340 image->fuzz=StringToDoubleInterval(
9341 argument_list[2].string_reference,(double) QuantumRange+1.0);
9342 if (attribute_flag[3] != 0)
9343 channel=(ChannelType) argument_list[3].integer_reference;
9344 invert=MagickFalse;
9345 if (attribute_flag[4] != 0)
9346 invert=(MagickBooleanType) argument_list[4].integer_reference;
9347 channel_mask=SetImageChannelMask(image,channel);
9348 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9349 (void) SetImageChannelMask(image,channel_mask);
9350 break;
9351 }
9352 case 48: /* Quantize */
9353 {
9354 QuantizeInfo
9355 *quantize_info;
9356
9357 quantize_info=AcquireQuantizeInfo(info->image_info);
9358 if (attribute_flag[0] != 0)
9359 quantize_info->number_colors=(size_t)
9360 argument_list[0].integer_reference;
9361 if (attribute_flag[1] != 0)
9362 quantize_info->tree_depth=(size_t)
9363 argument_list[1].integer_reference;
9364 if (attribute_flag[2] != 0)
9365 quantize_info->colorspace=(ColorspaceType)
9366 argument_list[2].integer_reference;
9367 if (attribute_flag[3] != 0)
9368 quantize_info->dither_method=(DitherMethod)
9369 argument_list[3].integer_reference;
9370 if (attribute_flag[4] != 0)
9371 quantize_info->measure_error=
9372 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
9373 if (attribute_flag[6] != 0)
9374 (void) QueryColorCompliance(argument_list[6].string_reference,
9375 AllCompliance,&image->transparent_color,exception);
9376 if (attribute_flag[7] != 0)
9377 quantize_info->dither_method=(DitherMethod)
9378 argument_list[7].integer_reference;
9379 if (attribute_flag[5] && argument_list[5].integer_reference)
9380 (void) QuantizeImages(quantize_info,image,exception);
9381 else
9382 if ((image->storage_class == DirectClass) ||
9383 (image->colors > quantize_info->number_colors) ||
9384 (quantize_info->colorspace == GRAYColorspace))
9385 (void) QuantizeImage(quantize_info,image,exception);
9386 else
9387 CompressImageColormap(image,exception);
9388 quantize_info=DestroyQuantizeInfo(quantize_info);
9389 break;
9390 }
9391 case 49: /* Raise */
9392 {
9393 if (attribute_flag[0] != 0)
9394 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9395 &geometry,exception);
9396 if (attribute_flag[1] != 0)
9397 geometry.width=argument_list[1].integer_reference;
9398 if (attribute_flag[2] != 0)
9399 geometry.height=argument_list[2].integer_reference;
9400 if (attribute_flag[3] == 0)
9401 argument_list[3].integer_reference=1;
9402 (void) RaiseImage(image,&geometry,
9403 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9404 exception);
9405 break;
9406 }
9407 case 50: /* Segment */
9408 {
9409 ColorspaceType
9410 colorspace;
9411
9412 double
9413 cluster_threshold,
9414 smoothing_threshold;
9415
9416 MagickBooleanType
9417 verbose;
9418
9419 cluster_threshold=1.0;
9420 smoothing_threshold=1.5;
9421 colorspace=sRGBColorspace;
9422 verbose=MagickFalse;
9423 if (attribute_flag[0] != 0)
9424 {
9425 flags=ParseGeometry(argument_list[0].string_reference,
9426 &geometry_info);
9427 cluster_threshold=geometry_info.rho;
9428 if (flags & SigmaValue)
9429 smoothing_threshold=geometry_info.sigma;
9430 }
9431 if (attribute_flag[1] != 0)
9432 cluster_threshold=argument_list[1].real_reference;
9433 if (attribute_flag[2] != 0)
9434 smoothing_threshold=argument_list[2].real_reference;
9435 if (attribute_flag[3] != 0)
9436 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9437 if (attribute_flag[4] != 0)
9438 verbose=argument_list[4].integer_reference != 0 ?
9439 MagickTrue : MagickFalse;
9440 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9441 smoothing_threshold,exception);
9442 break;
9443 }
9444 case 51: /* Signature */
9445 {
9446 (void) SignatureImage(image,exception);
9447 break;
9448 }
9449 case 52: /* Solarize */
9450 {
9451 geometry_info.rho=QuantumRange/2.0;
9452 if (attribute_flag[0] != 0)
9453 flags=ParseGeometry(argument_list[0].string_reference,
9454 &geometry_info);
9455 if (attribute_flag[1] != 0)
9456 geometry_info.rho=StringToDoubleInterval(
9457 argument_list[1].string_reference,(double) QuantumRange+1.0);
9458 (void) SolarizeImage(image,geometry_info.rho,exception);
9459 break;
9460 }
9461 case 53: /* Sync */
9462 {
9463 (void) SyncImage(image,exception);
9464 break;
9465 }
9466 case 54: /* Texture */
9467 {
9468 if (attribute_flag[0] == 0)
9469 break;
9470 TextureImage(image,argument_list[0].image_reference,exception);
9471 break;
9472 }
9473 case 55: /* Evalute */
9474 {
9475 MagickEvaluateOperator
9476 op;
9477
9478 op=SetEvaluateOperator;
9479 if (attribute_flag[0] == MagickFalse)
9480 argument_list[0].real_reference=0.0;
9481 if (attribute_flag[1] != MagickFalse)
9482 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9483 if (attribute_flag[2] != MagickFalse)
9484 channel=(ChannelType) argument_list[2].integer_reference;
9485 channel_mask=SetImageChannelMask(image,channel);
9486 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9487 exception);
9488 (void) SetImageChannelMask(image,channel_mask);
9489 break;
9490 }
9491 case 56: /* Transparent */
9492 {
9493 double
9494 opacity;
9495
9496 MagickBooleanType
9497 invert;
9498
9499 PixelInfo
9500 target;
9501
9502 (void) QueryColorCompliance("none",AllCompliance,&target,
9503 exception);
9504 if (attribute_flag[0] != 0)
9505 (void) QueryColorCompliance(argument_list[0].string_reference,
9506 AllCompliance,&target,exception);
9507 opacity=TransparentAlpha;
9508 if (attribute_flag[1] != 0)
9509 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9510 (double) QuantumRange+1.0);
9511 if (attribute_flag[2] != 0)
9512 image->fuzz=StringToDoubleInterval(
9513 argument_list[2].string_reference,(double) QuantumRange+1.0);
9514 if (attribute_flag[3] == 0)
9515 argument_list[3].integer_reference=0;
9516 invert=MagickFalse;
9517 if (attribute_flag[3] != 0)
9518 invert=(MagickBooleanType) argument_list[3].integer_reference;
9519 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9520 invert,exception);
9521 break;
9522 }
9523 case 57: /* Threshold */
9524 {
9525 double
9526 threshold;
9527
9528 if (attribute_flag[0] == 0)
9529 argument_list[0].string_reference="50%";
9530 if (attribute_flag[1] != 0)
9531 channel=(ChannelType) argument_list[1].integer_reference;
9532 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9533 (double) QuantumRange+1.0);
9534 channel_mask=SetImageChannelMask(image,channel);
9535 (void) BilevelImage(image,threshold,exception);
9536 (void) SetImageChannelMask(image,channel_mask);
9537 break;
9538 }
9539 case 58: /* Charcoal */
9540 {
9541 if (attribute_flag[0] != 0)
9542 {
9543 flags=ParseGeometry(argument_list[0].string_reference,
9544 &geometry_info);
9545 if ((flags & SigmaValue) == 0)
9546 geometry_info.sigma=1.0;
9547 }
9548 if (attribute_flag[1] != 0)
9549 geometry_info.rho=argument_list[1].real_reference;
9550 if (attribute_flag[2] != 0)
9551 geometry_info.sigma=argument_list[2].real_reference;
9552 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9553 exception);
9554 break;
9555 }
9556 case 59: /* Trim */
9557 {
9558 if (attribute_flag[0] != 0)
9559 image->fuzz=StringToDoubleInterval(
9560 argument_list[0].string_reference,(double) QuantumRange+1.0);
9561 image=TrimImage(image,exception);
9562 break;
9563 }
9564 case 60: /* Wave */
9565 {
9566 PixelInterpolateMethod
9567 method;
9568
9569 if (attribute_flag[0] != 0)
9570 {
9571 flags=ParseGeometry(argument_list[0].string_reference,
9572 &geometry_info);
9573 if ((flags & SigmaValue) == 0)
9574 geometry_info.sigma=1.0;
9575 }
9576 if (attribute_flag[1] != 0)
9577 geometry_info.rho=argument_list[1].real_reference;
9578 if (attribute_flag[2] != 0)
9579 geometry_info.sigma=argument_list[2].real_reference;
9580 method=UndefinedInterpolatePixel;
9581 if (attribute_flag[3] != 0)
9582 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9583 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9584 method,exception);
9585 break;
9586 }
9587 case 61: /* Separate */
9588 {
9589 if (attribute_flag[0] != 0)
9590 channel=(ChannelType) argument_list[0].integer_reference;
9591 image=SeparateImage(image,channel,exception);
9592 break;
9593 }
9594 case 63: /* Stereo */
9595 {
9596 if (attribute_flag[0] == 0)
9597 {
9598 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9599 PackageName);
9600 goto PerlException;
9601 }
9602 if (attribute_flag[1] != 0)
9603 geometry.x=argument_list[1].integer_reference;
9604 if (attribute_flag[2] != 0)
9605 geometry.y=argument_list[2].integer_reference;
9606 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9607 geometry.x,geometry.y,exception);
9608 break;
9609 }
9610 case 64: /* Stegano */
9611 {
9612 if (attribute_flag[0] == 0)
9613 {
9614 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9615 PackageName);
9616 goto PerlException;
9617 }
9618 if (attribute_flag[1] == 0)
9619 argument_list[1].integer_reference=0;
9620 image->offset=argument_list[1].integer_reference;
9621 image=SteganoImage(image,argument_list[0].image_reference,exception);
9622 break;
9623 }
9624 case 65: /* Deconstruct */
9625 {
9626 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9627 break;
9628 }
9629 case 66: /* GaussianBlur */
9630 {
9631 if (attribute_flag[0] != 0)
9632 {
9633 flags=ParseGeometry(argument_list[0].string_reference,
9634 &geometry_info);
9635 if ((flags & SigmaValue) == 0)
9636 geometry_info.sigma=1.0;
9637 }
9638 if (attribute_flag[1] != 0)
9639 geometry_info.rho=argument_list[1].real_reference;
9640 if (attribute_flag[2] != 0)
9641 geometry_info.sigma=argument_list[2].real_reference;
9642 if (attribute_flag[3] != 0)
9643 channel=(ChannelType) argument_list[3].integer_reference;
9644 channel_mask=SetImageChannelMask(image,channel);
9645 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9646 exception);
9647 if (image != (Image *) NULL)
9648 (void) SetImageChannelMask(image,channel_mask);
9649 break;
9650 }
9651 case 67: /* Convolve */
9652 {
9653 KernelInfo
9654 *kernel;
9655
9656 kernel=(KernelInfo *) NULL;
9657 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9658 break;
9659 if (attribute_flag[0] != 0)
9660 {
9661 AV
9662 *av;
9663
9664 size_t
9665 order;
9666
9667 kernel=AcquireKernelInfo((const char *) NULL,exception);
9668 if (kernel == (KernelInfo *) NULL)
9669 break;
9670 av=(AV *) argument_list[0].array_reference;
9671 order=(size_t) sqrt(av_len(av)+1);
9672 kernel->width=order;
9673 kernel->height=order;
9674 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9675 order*sizeof(*kernel->values));
9676 if (kernel->values == (MagickRealType *) NULL)
9677 {
9678 kernel=DestroyKernelInfo(kernel);
9679 ThrowPerlException(exception,ResourceLimitFatalError,
9680 "MemoryAllocationFailed",PackageName);
9681 goto PerlException;
9682 }
9683 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9684 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9685 for ( ; j < (ssize_t) (order*order); j++)
9686 kernel->values[j]=0.0;
9687 }
9688 if (attribute_flag[1] != 0)
9689 channel=(ChannelType) argument_list[1].integer_reference;
9690 if (attribute_flag[2] != 0)
9691 SetImageArtifact(image,"convolve:bias",
9692 argument_list[2].string_reference);
9693 if (attribute_flag[3] != 0)
9694 {
9695 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9696 exception);
9697 if (kernel == (KernelInfo *) NULL)
9698 break;
9699 }
9700 channel_mask=SetImageChannelMask(image,channel);
9701 image=ConvolveImage(image,kernel,exception);
9702 if (image != (Image *) NULL)
9703 (void) SetImageChannelMask(image,channel_mask);
9704 kernel=DestroyKernelInfo(kernel);
9705 break;
9706 }
9707 case 68: /* Profile */
9708 {
9709 const char
9710 *name;
9711
9712 Image
9713 *profile_image;
9714
9715 ImageInfo
9716 *profile_info;
9717
9718 StringInfo
9719 *profile;
9720
9721 name="*";
9722 if (attribute_flag[0] != 0)
9723 name=argument_list[0].string_reference;
9724 if (attribute_flag[2] != 0)
9725 image->rendering_intent=(RenderingIntent)
9726 argument_list[2].integer_reference;
9727 if (attribute_flag[3] != 0)
9728 image->black_point_compensation=
9729 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9730 if (attribute_flag[1] != 0)
9731 {
9732 if (argument_list[1].length == 0)
9733 {
9734 /*
9735 Remove a profile from the image.
9736 */
9737 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9738 exception);
9739 break;
9740 }
9741 /*
9742 Associate user supplied profile with the image.
9743 */
9744 profile=AcquireStringInfo(argument_list[1].length);
9745 SetStringInfoDatum(profile,(const unsigned char *)
9746 argument_list[1].string_reference);
9747 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9748 (size_t) GetStringInfoLength(profile),exception);
9749 profile=DestroyStringInfo(profile);
9750 break;
9751 }
9752 /*
9753 Associate a profile with the image.
9754 */
9755 profile_info=CloneImageInfo(info ? info->image_info :
9756 (ImageInfo *) NULL);
9757 profile_image=ReadImages(profile_info,name,exception);
9758 if (profile_image == (Image *) NULL)
9759 break;
9760 ResetImageProfileIterator(profile_image);
9761 name=GetNextImageProfile(profile_image);
9762 while (name != (const char *) NULL)
9763 {
9764 const StringInfo
9765 *profile;
9766
9767 profile=GetImageProfile(profile_image,name);
9768 if (profile != (const StringInfo *) NULL)
9769 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9770 (size_t) GetStringInfoLength(profile),exception);
9771 name=GetNextImageProfile(profile_image);
9772 }
9773 profile_image=DestroyImage(profile_image);
9774 profile_info=DestroyImageInfo(profile_info);
9775 break;
9776 }
9777 case 69: /* UnsharpMask */
9778 {
9779 if (attribute_flag[0] != 0)
9780 {
9781 flags=ParseGeometry(argument_list[0].string_reference,
9782 &geometry_info);
9783 if ((flags & SigmaValue) == 0)
9784 geometry_info.sigma=1.0;
9785 if ((flags & XiValue) == 0)
9786 geometry_info.xi=1.0;
9787 if ((flags & PsiValue) == 0)
9788 geometry_info.psi=0.5;
9789 }
9790 if (attribute_flag[1] != 0)
9791 geometry_info.rho=argument_list[1].real_reference;
9792 if (attribute_flag[2] != 0)
9793 geometry_info.sigma=argument_list[2].real_reference;
9794 if (attribute_flag[3] != 0)
9795 geometry_info.xi=argument_list[3].real_reference;
9796 if (attribute_flag[4] != 0)
9797 geometry_info.psi=argument_list[4].real_reference;
9798 if (attribute_flag[5] != 0)
9799 channel=(ChannelType) argument_list[5].integer_reference;
9800 channel_mask=SetImageChannelMask(image,channel);
9801 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9802 geometry_info.xi,geometry_info.psi,exception);
9803 if (image != (Image *) NULL)
9804 (void) SetImageChannelMask(image,channel_mask);
9805 break;
9806 }
9807 case 70: /* MotionBlur */
9808 {
9809 if (attribute_flag[0] != 0)
9810 {
9811 flags=ParseGeometry(argument_list[0].string_reference,
9812 &geometry_info);
9813 if ((flags & SigmaValue) == 0)
9814 geometry_info.sigma=1.0;
9815 if ((flags & XiValue) == 0)
9816 geometry_info.xi=1.0;
9817 }
9818 if (attribute_flag[1] != 0)
9819 geometry_info.rho=argument_list[1].real_reference;
9820 if (attribute_flag[2] != 0)
9821 geometry_info.sigma=argument_list[2].real_reference;
9822 if (attribute_flag[3] != 0)
9823 geometry_info.xi=argument_list[3].real_reference;
9824 if (attribute_flag[4] != 0)
9825 channel=(ChannelType) argument_list[4].integer_reference;
9826 channel_mask=SetImageChannelMask(image,channel);
9827 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9828 geometry_info.xi,exception);
9829 if (image != (Image *) NULL)
9830 (void) SetImageChannelMask(image,channel_mask);
9831 break;
9832 }
9833 case 71: /* OrderedDither */
9834 {
9835 if (attribute_flag[0] == 0)
9836 argument_list[0].string_reference="o8x8";
9837 if (attribute_flag[1] != 0)
9838 channel=(ChannelType) argument_list[1].integer_reference;
9839 channel_mask=SetImageChannelMask(image,channel);
9840 (void) OrderedDitherImage(image,argument_list[0].string_reference,
9841 exception);
9842 (void) SetImageChannelMask(image,channel_mask);
9843 break;
9844 }
9845 case 72: /* Shave */
9846 {
9847 if (attribute_flag[0] != 0)
9848 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9849 &geometry,exception);
9850 if (attribute_flag[1] != 0)
9851 geometry.width=argument_list[1].integer_reference;
9852 if (attribute_flag[2] != 0)
9853 geometry.height=argument_list[2].integer_reference;
9854 image=ShaveImage(image,&geometry,exception);
9855 break;
9856 }
9857 case 73: /* Level */
9858 {
9859 double
9860 black_point,
9861 gamma,
9862 white_point;
9863
9864 black_point=0.0;
9865 white_point=(double) image->columns*image->rows;
9866 gamma=1.0;
9867 if (attribute_flag[0] != 0)
9868 {
9869 flags=ParseGeometry(argument_list[0].string_reference,
9870 &geometry_info);
9871 black_point=geometry_info.rho;
9872 if ((flags & SigmaValue) != 0)
9873 white_point=geometry_info.sigma;
9874 if ((flags & XiValue) != 0)
9875 gamma=geometry_info.xi;
9876 if ((flags & PercentValue) != 0)
9877 {
9878 black_point*=(double) (QuantumRange/100.0);
9879 white_point*=(double) (QuantumRange/100.0);
9880 }
9881 if ((flags & SigmaValue) == 0)
9882 white_point=(double) QuantumRange-black_point;
9883 }
9884 if (attribute_flag[1] != 0)
9885 black_point=argument_list[1].real_reference;
9886 if (attribute_flag[2] != 0)
9887 white_point=argument_list[2].real_reference;
9888 if (attribute_flag[3] != 0)
9889 gamma=argument_list[3].real_reference;
9890 if (attribute_flag[4] != 0)
9891 channel=(ChannelType) argument_list[4].integer_reference;
9892 if (attribute_flag[5] != 0)
9893 {
9894 argument_list[0].real_reference=argument_list[5].real_reference;
9895 attribute_flag[0]=attribute_flag[5];
9896 }
9897 channel_mask=SetImageChannelMask(image,channel);
9898 (void) LevelImage(image,black_point,white_point,gamma,exception);
9899 (void) SetImageChannelMask(image,channel_mask);
9900 break;
9901 }
9902 case 74: /* Clip */
9903 {
9904 if (attribute_flag[0] == 0)
9905 argument_list[0].string_reference="#1";
9906 if (attribute_flag[1] == 0)
9907 argument_list[1].integer_reference=MagickTrue;
9908 (void) ClipImagePath(image,argument_list[0].string_reference,
9909 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9910 exception);
9911 break;
9912 }
9913 case 75: /* AffineTransform */
9914 {
9915 DrawInfo
9916 *draw_info;
9917
9918 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9919 (DrawInfo *) NULL);
9920 if (attribute_flag[0] != 0)
9921 {
9922 AV
9923 *av;
9924
9925 av=(AV *) argument_list[0].array_reference;
9926 if ((av_len(av) != 3) && (av_len(av) != 5))
9927 {
9928 ThrowPerlException(exception,OptionError,
9929 "affine matrix must have 4 or 6 elements",PackageName);
9930 goto PerlException;
9931 }
9932 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9933 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9934 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9935 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9936 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9937 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9938 {
9939 ThrowPerlException(exception,OptionError,
9940 "affine matrix is singular",PackageName);
9941 goto PerlException;
9942 }
9943 if (av_len(av) == 5)
9944 {
9945 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9946 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9947 }
9948 }
9949 for (j=1; j < 6; j++)
9950 {
9951 if (attribute_flag[j] == 0)
9952 continue;
9953 value=argument_list[j].string_reference;
9954 angle=argument_list[j].real_reference;
9955 current=draw_info->affine;
9956 GetAffineMatrix(&affine);
9957 switch (j)
9958 {
9959 case 1:
9960 {
9961 /*
9962 Translate.
9963 */
9964 flags=ParseGeometry(value,&geometry_info);
9965 affine.tx=geometry_info.xi;
9966 affine.ty=geometry_info.psi;
9967 if ((flags & PsiValue) == 0)
9968 affine.ty=affine.tx;
9969 break;
9970 }
9971 case 2:
9972 {
9973 /*
9974 Scale.
9975 */
9976 flags=ParseGeometry(value,&geometry_info);
9977 affine.sx=geometry_info.rho;
9978 affine.sy=geometry_info.sigma;
9979 if ((flags & SigmaValue) == 0)
9980 affine.sy=affine.sx;
9981 break;
9982 }
9983 case 3:
9984 {
9985 /*
9986 Rotate.
9987 */
9988 if (angle == 0.0)
9989 break;
9990 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9991 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9992 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9993 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9994 break;
9995 }
9996 case 4:
9997 {
9998 /*
9999 SkewX.
10000 */
10001 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
10002 break;
10003 }
10004 case 5:
10005 {
10006 /*
10007 SkewY.
10008 */
10009 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
10010 break;
10011 }
10012 }
10013 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
10014 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
10015 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
10016 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
10017 draw_info->affine.tx=
10018 current.sx*affine.tx+current.ry*affine.ty+current.tx;
10019 draw_info->affine.ty=
10020 current.rx*affine.tx+current.sy*affine.ty+current.ty;
10021 }
10022 if (attribute_flag[6] != 0)
10023 image->interpolate=(PixelInterpolateMethod)
10024 argument_list[6].integer_reference;
10025 if (attribute_flag[7] != 0)
10026 QueryColorCompliance(argument_list[7].string_reference,
10027 AllCompliance,&image->background_color,exception);
10028 image=AffineTransformImage(image,&draw_info->affine,exception);
10029 draw_info=DestroyDrawInfo(draw_info);
10030 break;
10031 }
10032 case 76: /* Difference */
10033 {
10034 if (attribute_flag[0] == 0)
10035 {
10036 ThrowPerlException(exception,OptionError,
10037 "ReferenceImageRequired",PackageName);
10038 goto PerlException;
10039 }
10040 if (attribute_flag[1] != 0)
10041 image->fuzz=StringToDoubleInterval(
10042 argument_list[1].string_reference,(double) QuantumRange+1.0);
10043 (void) SetImageColorMetric(image,argument_list[0].image_reference,
10044 exception);
10045 break;
10046 }
10047 case 77: /* AdaptiveThreshold */
10048 {
10049 if (attribute_flag[0] != 0)
10050 {
10051 flags=ParseGeometry(argument_list[0].string_reference,
10052 &geometry_info);
10053 if ((flags & PercentValue) != 0)
10054 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10055 }
10056 if (attribute_flag[1] != 0)
10057 geometry_info.rho=argument_list[1].integer_reference;
10058 if (attribute_flag[2] != 0)
10059 geometry_info.sigma=argument_list[2].integer_reference;
10060 if (attribute_flag[3] != 0)
10061 geometry_info.xi=argument_list[3].integer_reference;;
10062 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
10063 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
10064 break;
10065 }
10066 case 78: /* Resample */
10067 {
10068 size_t
10069 height,
10070 width;
10071
10072 if (attribute_flag[0] != 0)
10073 {
10074 flags=ParseGeometry(argument_list[0].string_reference,
10075 &geometry_info);
10076 if ((flags & SigmaValue) == 0)
10077 geometry_info.sigma=geometry_info.rho;
10078 }
10079 if (attribute_flag[1] != 0)
10080 geometry_info.rho=argument_list[1].real_reference;
10081 if (attribute_flag[2] != 0)
10082 geometry_info.sigma=argument_list[2].real_reference;
10083 if (attribute_flag[3] == 0)
10084 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10085 if (attribute_flag[4] == 0)
10086 SetImageArtifact(image,"filter:support",
10087 argument_list[4].string_reference);
10088 width=(size_t) (geometry_info.rho*image->columns/
10089 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10090 height=(size_t) (geometry_info.sigma*image->rows/
10091 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
10092 image=ResizeImage(image,width,height,(FilterType)
10093 argument_list[3].integer_reference,exception);
10094 if (image != (Image *) NULL)
10095 {
10096 image->resolution.x=geometry_info.rho;
10097 image->resolution.y=geometry_info.sigma;
10098 }
10099 break;
10100 }
10101 case 79: /* Describe */
10102 {
10103 if (attribute_flag[0] == 0)
10104 argument_list[0].file_reference=(FILE *) NULL;
10105 if (attribute_flag[1] != 0)
10106 (void) SetImageArtifact(image,"identify:features",
10107 argument_list[1].string_reference);
10108 (void) IdentifyImage(image,argument_list[0].file_reference,
10109 MagickTrue,exception);
10110 break;
10111 }
10112 case 80: /* BlackThreshold */
10113 {
10114 if (attribute_flag[0] == 0)
10115 argument_list[0].string_reference="50%";
10116 if (attribute_flag[2] != 0)
10117 channel=(ChannelType) argument_list[2].integer_reference;
10118 channel_mask=SetImageChannelMask(image,channel);
10119 BlackThresholdImage(image,argument_list[0].string_reference,
10120 exception);
10121 (void) SetImageChannelMask(image,channel_mask);
10122 break;
10123 }
10124 case 81: /* WhiteThreshold */
10125 {
10126 if (attribute_flag[0] == 0)
10127 argument_list[0].string_reference="50%";
10128 if (attribute_flag[2] != 0)
10129 channel=(ChannelType) argument_list[2].integer_reference;
10130 channel_mask=SetImageChannelMask(image,channel);
10131 WhiteThresholdImage(image,argument_list[0].string_reference,
10132 exception);
10133 (void) SetImageChannelMask(image,channel_mask);
10134 break;
10135 }
10136 case 82: /* RotationalBlur */
10137 {
10138 if (attribute_flag[0] != 0)
10139 {
10140 flags=ParseGeometry(argument_list[0].string_reference,
10141 &geometry_info);
10142 }
10143 if (attribute_flag[1] != 0)
10144 geometry_info.rho=argument_list[1].real_reference;
10145 if (attribute_flag[2] != 0)
10146 channel=(ChannelType) argument_list[2].integer_reference;
10147 channel_mask=SetImageChannelMask(image,channel);
10148 image=RotationalBlurImage(image,geometry_info.rho,exception);
10149 if (image != (Image *) NULL)
10150 (void) SetImageChannelMask(image,channel_mask);
10151 break;
10152 }
10153 case 83: /* Thumbnail */
10154 {
10155 if (attribute_flag[0] != 0)
10156 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10157 &geometry,exception);
10158 if (attribute_flag[1] != 0)
10159 geometry.width=argument_list[1].integer_reference;
10160 if (attribute_flag[2] != 0)
10161 geometry.height=argument_list[2].integer_reference;
10162 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10163 break;
10164 }
10165 case 84: /* Strip */
10166 {
10167 (void) StripImage(image,exception);
10168 break;
10169 }
10170 case 85: /* Tint */
10171 {
10172 PixelInfo
10173 tint;
10174
10175 GetPixelInfo(image,&tint);
10176 if (attribute_flag[0] != 0)
10177 (void) QueryColorCompliance(argument_list[0].string_reference,
10178 AllCompliance,&tint,exception);
10179 if (attribute_flag[1] == 0)
10180 argument_list[1].string_reference="100";
10181 image=TintImage(image,argument_list[1].string_reference,&tint,
10182 exception);
10183 break;
10184 }
10185 case 86: /* Channel */
10186 {
10187 if (attribute_flag[0] != 0)
10188 channel=(ChannelType) argument_list[0].integer_reference;
10189 image=SeparateImage(image,channel,exception);
10190 break;
10191 }
10192 case 87: /* Splice */
10193 {
10194 if (attribute_flag[7] != 0)
10195 image->gravity=(GravityType) argument_list[7].integer_reference;
10196 if (attribute_flag[0] != 0)
10197 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10198 &geometry,exception);
10199 if (attribute_flag[1] != 0)
10200 geometry.width=argument_list[1].integer_reference;
10201 if (attribute_flag[2] != 0)
10202 geometry.height=argument_list[2].integer_reference;
10203 if (attribute_flag[3] != 0)
10204 geometry.x=argument_list[3].integer_reference;
10205 if (attribute_flag[4] != 0)
10206 geometry.y=argument_list[4].integer_reference;
10207 if (attribute_flag[5] != 0)
10208 image->fuzz=StringToDoubleInterval(
10209 argument_list[5].string_reference,(double) QuantumRange+1.0);
10210 if (attribute_flag[6] != 0)
10211 (void) QueryColorCompliance(argument_list[6].string_reference,
10212 AllCompliance,&image->background_color,exception);
10213 image=SpliceImage(image,&geometry,exception);
10214 break;
10215 }
10216 case 88: /* Posterize */
10217 {
10218 if (attribute_flag[0] == 0)
10219 argument_list[0].integer_reference=3;
10220 if (attribute_flag[1] == 0)
10221 argument_list[1].integer_reference=0;
10222 (void) PosterizeImage(image,argument_list[0].integer_reference,
10223 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10224 NoDitherMethod,exception);
10225 break;
10226 }
10227 case 89: /* Shadow */
10228 {
10229 if (attribute_flag[0] != 0)
10230 {
10231 flags=ParseGeometry(argument_list[0].string_reference,
10232 &geometry_info);
10233 if ((flags & SigmaValue) == 0)
10234 geometry_info.sigma=1.0;
10235 if ((flags & XiValue) == 0)
10236 geometry_info.xi=4.0;
10237 if ((flags & PsiValue) == 0)
10238 geometry_info.psi=4.0;
10239 }
10240 if (attribute_flag[1] != 0)
10241 geometry_info.rho=argument_list[1].real_reference;
10242 if (attribute_flag[2] != 0)
10243 geometry_info.sigma=argument_list[2].real_reference;
10244 if (attribute_flag[3] != 0)
10245 geometry_info.xi=argument_list[3].integer_reference;
10246 if (attribute_flag[4] != 0)
10247 geometry_info.psi=argument_list[4].integer_reference;
10248 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10249 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10250 ceil(geometry_info.psi-0.5),exception);
10251 break;
10252 }
10253 case 90: /* Identify */
10254 {
10255 if (attribute_flag[0] == 0)
10256 argument_list[0].file_reference=(FILE *) NULL;
10257 if (attribute_flag[1] != 0)
10258 (void) SetImageArtifact(image,"identify:features",
10259 argument_list[1].string_reference);
10260 if ((attribute_flag[2] != 0) &&
10261 (argument_list[2].integer_reference != 0))
10262 (void) SetImageArtifact(image,"identify:unique","true");
10263 (void) IdentifyImage(image,argument_list[0].file_reference,
10264 MagickTrue,exception);
10265 break;
10266 }
10267 case 91: /* SepiaTone */
10268 {
10269 if (attribute_flag[0] == 0)
10270 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10271 image=SepiaToneImage(image,argument_list[0].real_reference,
10272 exception);
10273 break;
10274 }
10275 case 92: /* SigmoidalContrast */
10276 {
10277 MagickBooleanType
10278 sharpen;
10279
10280 if (attribute_flag[0] != 0)
10281 {
10282 flags=ParseGeometry(argument_list[0].string_reference,
10283 &geometry_info);
10284 if ((flags & SigmaValue) == 0)
10285 geometry_info.sigma=QuantumRange/2.0;
10286 if ((flags & PercentValue) != 0)
10287 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10288 }
10289 if (attribute_flag[1] != 0)
10290 geometry_info.rho=argument_list[1].real_reference;
10291 if (attribute_flag[2] != 0)
10292 geometry_info.sigma=argument_list[2].real_reference;
10293 if (attribute_flag[3] != 0)
10294 channel=(ChannelType) argument_list[3].integer_reference;
10295 sharpen=MagickTrue;
10296 if (attribute_flag[4] != 0)
10297 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10298 MagickFalse;
10299 channel_mask=SetImageChannelMask(image,channel);
10300 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10301 geometry_info.sigma,exception);
10302 (void) SetImageChannelMask(image,channel_mask);
10303 break;
10304 }
10305 case 93: /* Extent */
10306 {
10307 if (attribute_flag[7] != 0)
10308 image->gravity=(GravityType) argument_list[7].integer_reference;
10309 if (attribute_flag[0] != 0)
10310 {
10311 int
10312 flags;
10313
10314 flags=ParseGravityGeometry(image,
10315 argument_list[0].string_reference,&geometry,exception);
10316 (void) flags;
10317 if (geometry.width == 0)
10318 geometry.width=image->columns;
10319 if (geometry.height == 0)
10320 geometry.height=image->rows;
10321 }
10322 if (attribute_flag[1] != 0)
10323 geometry.width=argument_list[1].integer_reference;
10324 if (attribute_flag[2] != 0)
10325 geometry.height=argument_list[2].integer_reference;
10326 if (attribute_flag[3] != 0)
10327 geometry.x=argument_list[3].integer_reference;
10328 if (attribute_flag[4] != 0)
10329 geometry.y=argument_list[4].integer_reference;
10330 if (attribute_flag[5] != 0)
10331 image->fuzz=StringToDoubleInterval(
10332 argument_list[5].string_reference,(double) QuantumRange+1.0);
10333 if (attribute_flag[6] != 0)
10334 (void) QueryColorCompliance(argument_list[6].string_reference,
10335 AllCompliance,&image->background_color,exception);
10336 image=ExtentImage(image,&geometry,exception);
10337 break;
10338 }
10339 case 94: /* Vignette */
10340 {
10341 if (attribute_flag[0] != 0)
10342 {
10343 flags=ParseGeometry(argument_list[0].string_reference,
10344 &geometry_info);
10345 if ((flags & SigmaValue) == 0)
10346 geometry_info.sigma=1.0;
10347 if ((flags & XiValue) == 0)
10348 geometry_info.xi=0.1*image->columns;
10349 if ((flags & PsiValue) == 0)
10350 geometry_info.psi=0.1*image->rows;
10351 }
10352 if (attribute_flag[1] != 0)
10353 geometry_info.rho=argument_list[1].real_reference;
10354 if (attribute_flag[2] != 0)
10355 geometry_info.sigma=argument_list[2].real_reference;
10356 if (attribute_flag[3] != 0)
10357 geometry_info.xi=argument_list[3].integer_reference;
10358 if (attribute_flag[4] != 0)
10359 geometry_info.psi=argument_list[4].integer_reference;
10360 if (attribute_flag[5] != 0)
10361 (void) QueryColorCompliance(argument_list[5].string_reference,
10362 AllCompliance,&image->background_color,exception);
10363 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10364 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10365 ceil(geometry_info.psi-0.5),exception);
10366 break;
10367 }
10368 case 95: /* ContrastStretch */
10369 {
10370 double
10371 black_point,
10372 white_point;
10373
10374 black_point=0.0;
10375 white_point=(double) image->columns*image->rows;
10376 if (attribute_flag[0] != 0)
10377 {
10378 flags=ParseGeometry(argument_list[0].string_reference,
10379 &geometry_info);
10380 black_point=geometry_info.rho;
10381 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10382 black_point;
10383 if ((flags & PercentValue) != 0)
10384 {
10385 black_point*=(double) image->columns*image->rows/100.0;
10386 white_point*=(double) image->columns*image->rows/100.0;
10387 }
10388 white_point=(double) image->columns*image->rows-
10389 white_point;
10390 }
10391 if (attribute_flag[1] != 0)
10392 black_point=argument_list[1].real_reference;
10393 if (attribute_flag[2] != 0)
10394 white_point=argument_list[2].real_reference;
10395 if (attribute_flag[4] != 0)
10396 channel=(ChannelType) argument_list[4].integer_reference;
10397 channel_mask=SetImageChannelMask(image,channel);
10398 (void) ContrastStretchImage(image,black_point,white_point,exception);
10399 (void) SetImageChannelMask(image,channel_mask);
10400 break;
10401 }
10402 case 96: /* Sans0 */
10403 {
10404 break;
10405 }
10406 case 97: /* Sans1 */
10407 {
10408 break;
10409 }
10410 case 98: /* AdaptiveSharpen */
10411 {
10412 if (attribute_flag[0] != 0)
10413 {
10414 flags=ParseGeometry(argument_list[0].string_reference,
10415 &geometry_info);
10416 if ((flags & SigmaValue) == 0)
10417 geometry_info.sigma=1.0;
10418 if ((flags & XiValue) == 0)
10419 geometry_info.xi=0.0;
10420 }
10421 if (attribute_flag[1] != 0)
10422 geometry_info.rho=argument_list[1].real_reference;
10423 if (attribute_flag[2] != 0)
10424 geometry_info.sigma=argument_list[2].real_reference;
10425 if (attribute_flag[3] != 0)
10426 geometry_info.xi=argument_list[3].real_reference;
10427 if (attribute_flag[4] != 0)
10428 channel=(ChannelType) argument_list[4].integer_reference;
10429 channel_mask=SetImageChannelMask(image,channel);
10430 image=AdaptiveSharpenImage(image,geometry_info.rho,
10431 geometry_info.sigma,exception);
10432 if (image != (Image *) NULL)
10433 (void) SetImageChannelMask(image,channel_mask);
10434 break;
10435 }
10436 case 99: /* Transpose */
10437 {
10438 image=TransposeImage(image,exception);
10439 break;
10440 }
10441 case 100: /* Tranverse */
10442 {
10443 image=TransverseImage(image,exception);
10444 break;
10445 }
10446 case 101: /* AutoOrient */
10447 {
10448 image=AutoOrientImage(image,image->orientation,exception);
10449 break;
10450 }
10451 case 102: /* AdaptiveBlur */
10452 {
10453 if (attribute_flag[0] != 0)
10454 {
10455 flags=ParseGeometry(argument_list[0].string_reference,
10456 &geometry_info);
10457 if ((flags & SigmaValue) == 0)
10458 geometry_info.sigma=1.0;
10459 if ((flags & XiValue) == 0)
10460 geometry_info.xi=0.0;
10461 }
10462 if (attribute_flag[1] != 0)
10463 geometry_info.rho=argument_list[1].real_reference;
10464 if (attribute_flag[2] != 0)
10465 geometry_info.sigma=argument_list[2].real_reference;
10466 if (attribute_flag[3] != 0)
10467 channel=(ChannelType) argument_list[3].integer_reference;
10468 channel_mask=SetImageChannelMask(image,channel);
10469 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10470 exception);
10471 if (image != (Image *) NULL)
10472 (void) SetImageChannelMask(image,channel_mask);
10473 break;
10474 }
10475 case 103: /* Sketch */
10476 {
10477 if (attribute_flag[0] != 0)
10478 {
10479 flags=ParseGeometry(argument_list[0].string_reference,
10480 &geometry_info);
10481 if ((flags & SigmaValue) == 0)
10482 geometry_info.sigma=1.0;
10483 if ((flags & XiValue) == 0)
10484 geometry_info.xi=1.0;
10485 }
10486 if (attribute_flag[1] != 0)
10487 geometry_info.rho=argument_list[1].real_reference;
10488 if (attribute_flag[2] != 0)
10489 geometry_info.sigma=argument_list[2].real_reference;
10490 if (attribute_flag[3] != 0)
10491 geometry_info.xi=argument_list[3].real_reference;
10492 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10493 geometry_info.xi,exception);
10494 break;
10495 }
10496 case 104: /* UniqueColors */
10497 {
10498 image=UniqueImageColors(image,exception);
10499 break;
10500 }
10501 case 105: /* AdaptiveResize */
10502 {
10503 if (attribute_flag[0] != 0)
10504 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10505 &geometry,exception);
10506 if (attribute_flag[1] != 0)
10507 geometry.width=argument_list[1].integer_reference;
10508 if (attribute_flag[2] != 0)
10509 geometry.height=argument_list[2].integer_reference;
10510 if (attribute_flag[3] != 0)
10511 image->filter=(FilterType) argument_list[4].integer_reference;
10512 if (attribute_flag[4] != 0)
10513 SetImageArtifact(image,"filter:support",
10514 argument_list[4].string_reference);
10515 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10516 exception);
10517 break;
10518 }
10519 case 106: /* ClipMask */
10520 {
10521 Image
10522 *mask_image;
10523
10524 if (attribute_flag[0] == 0)
10525 {
10526 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10527 PackageName);
10528 goto PerlException;
10529 }
10530 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10531 exception);
10532 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
10533 mask_image=DestroyImage(mask_image);
10534 break;
10535 }
10536 case 107: /* LinearStretch */
10537 {
10538 double
10539 black_point,
10540 white_point;
10541
10542 black_point=0.0;
10543 white_point=(double) image->columns*image->rows;
10544 if (attribute_flag[0] != 0)
10545 {
10546 flags=ParseGeometry(argument_list[0].string_reference,
10547 &geometry_info);
10548 if ((flags & SigmaValue) != 0)
10549 white_point=geometry_info.sigma;
10550 if ((flags & PercentValue) != 0)
10551 {
10552 black_point*=(double) image->columns*image->rows/100.0;
10553 white_point*=(double) image->columns*image->rows/100.0;
10554 }
10555 if ((flags & SigmaValue) == 0)
10556 white_point=(double) image->columns*image->rows-black_point;
10557 }
10558 if (attribute_flag[1] != 0)
10559 black_point=argument_list[1].real_reference;
10560 if (attribute_flag[2] != 0)
10561 white_point=argument_list[2].real_reference;
10562 (void) LinearStretchImage(image,black_point,white_point,exception);
10563 break;
10564 }
10565 case 108: /* ColorMatrix */
10566 {
10567 AV
10568 *av;
10569
10570 double
10571 *color_matrix;
10572
10573 KernelInfo
10574 *kernel_info;
10575
10576 size_t
10577 order;
10578
10579 if (attribute_flag[0] == 0)
10580 break;
10581 av=(AV *) argument_list[0].array_reference;
10582 order=(size_t) sqrt(av_len(av)+1);
10583 color_matrix=(double *) AcquireQuantumMemory(order,order*
10584 sizeof(*color_matrix));
10585 if (color_matrix == (double *) NULL)
10586 {
10587 ThrowPerlException(exception,ResourceLimitFatalError,
10588 "MemoryAllocationFailed",PackageName);
10589 goto PerlException;
10590 }
10591 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10592 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10593 for ( ; j < (ssize_t) (order*order); j++)
10594 color_matrix[j]=0.0;
10595 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
10596 if (kernel_info == (KernelInfo *) NULL)
10597 break;
10598 kernel_info->width=order;
10599 kernel_info->height=order;
10600 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10601 order*sizeof(*kernel_info->values));
10602 if (kernel_info->values != (MagickRealType *) NULL)
10603 {
10604 for (i=0; i < (ssize_t) (order*order); i++)
10605 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10606 image=ColorMatrixImage(image,kernel_info,exception);
10607 }
10608 kernel_info=DestroyKernelInfo(kernel_info);
10609 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10610 break;
10611 }
10612 case 109: /* Mask */
10613 {
10614 Image
10615 *mask_image;
10616
10617 if (attribute_flag[0] == 0)
10618 {
10619 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10620 PackageName);
10621 goto PerlException;
10622 }
10623 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10624 MagickTrue,exception);
10625 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
10626 mask_image=DestroyImage(mask_image);
10627 break;
10628 }
10629 case 110: /* Polaroid */
10630 {
10631 char
10632 *caption;
10633
10634 DrawInfo
10635 *draw_info;
10636
10637 double
10638 angle;
10639
10640 PixelInterpolateMethod
10641 method;
10642
10643 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10644 (DrawInfo *) NULL);
10645 caption=(char *) NULL;
10646 if (attribute_flag[0] != 0)
10647 caption=InterpretImageProperties(info ? info->image_info :
10648 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10649 exception);
10650 angle=0.0;
10651 if (attribute_flag[1] != 0)
10652 angle=argument_list[1].real_reference;
10653 if (attribute_flag[2] != 0)
10654 (void) CloneString(&draw_info->font,
10655 argument_list[2].string_reference);
10656 if (attribute_flag[3] != 0)
10657 (void) QueryColorCompliance(argument_list[3].string_reference,
10658 AllCompliance,&draw_info->stroke,exception);
10659 if (attribute_flag[4] != 0)
10660 (void) QueryColorCompliance(argument_list[4].string_reference,
10661 AllCompliance,&draw_info->fill,exception);
10662 if (attribute_flag[5] != 0)
10663 draw_info->stroke_width=argument_list[5].real_reference;
10664 if (attribute_flag[6] != 0)
10665 draw_info->pointsize=argument_list[6].real_reference;
10666 if (attribute_flag[7] != 0)
10667 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10668 if (attribute_flag[8] != 0)
10669 (void) QueryColorCompliance(argument_list[8].string_reference,
10670 AllCompliance,&image->background_color,exception);
10671 method=UndefinedInterpolatePixel;
10672 if (attribute_flag[9] != 0)
10673 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10674 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10675 draw_info=DestroyDrawInfo(draw_info);
10676 if (caption != (char *) NULL)
10677 caption=DestroyString(caption);
10678 break;
10679 }
10680 case 111: /* FloodfillPaint */
10681 {
10682 DrawInfo
10683 *draw_info;
10684
10685 MagickBooleanType
10686 invert;
10687
10688 PixelInfo
10689 target;
10690
10691 draw_info=CloneDrawInfo(info ? info->image_info :
10692 (ImageInfo *) NULL,(DrawInfo *) NULL);
10693 if (attribute_flag[0] != 0)
10694 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10695 &geometry,exception);
10696 if (attribute_flag[1] != 0)
10697 geometry.x=argument_list[1].integer_reference;
10698 if (attribute_flag[2] != 0)
10699 geometry.y=argument_list[2].integer_reference;
10700 if (attribute_flag[3] != 0)
10701 (void) QueryColorCompliance(argument_list[3].string_reference,
10702 AllCompliance,&draw_info->fill,exception);
10703 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10704 geometry.x,geometry.y,&target,exception);
10705 if (attribute_flag[4] != 0)
10706 QueryColorCompliance(argument_list[4].string_reference,
10707 AllCompliance,&target,exception);
10708 if (attribute_flag[5] != 0)
10709 image->fuzz=StringToDoubleInterval(
10710 argument_list[5].string_reference,(double) QuantumRange+1.0);
10711 if (attribute_flag[6] != 0)
10712 channel=(ChannelType) argument_list[6].integer_reference;
10713 invert=MagickFalse;
10714 if (attribute_flag[7] != 0)
10715 invert=(MagickBooleanType) argument_list[7].integer_reference;
10716 channel_mask=SetImageChannelMask(image,channel);
10717 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10718 geometry.y,invert,exception);
10719 (void) SetImageChannelMask(image,channel_mask);
10720 draw_info=DestroyDrawInfo(draw_info);
10721 break;
10722 }
10723 case 112: /* Distort */
10724 {
10725 AV
10726 *av;
10727
10728 double
10729 *coordinates;
10730
10731 DistortMethod
10732 method;
10733
10734 size_t
10735 number_coordinates;
10736
10737 VirtualPixelMethod
10738 virtual_pixel;
10739
10740 if (attribute_flag[0] == 0)
10741 break;
10742 method=UndefinedDistortion;
10743 if (attribute_flag[1] != 0)
10744 method=(DistortMethod) argument_list[1].integer_reference;
10745 av=(AV *) argument_list[0].array_reference;
10746 number_coordinates=(size_t) av_len(av)+1;
10747 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10748 sizeof(*coordinates));
10749 if (coordinates == (double *) NULL)
10750 {
10751 ThrowPerlException(exception,ResourceLimitFatalError,
10752 "MemoryAllocationFailed",PackageName);
10753 goto PerlException;
10754 }
10755 for (j=0; j < (ssize_t) number_coordinates; j++)
10756 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10757 virtual_pixel=UndefinedVirtualPixelMethod;
10758 if (attribute_flag[2] != 0)
10759 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10760 argument_list[2].integer_reference,exception);
10761 image=DistortImage(image,method,number_coordinates,coordinates,
10762 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10763 exception);
10764 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10765 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10766 exception);
10767 coordinates=(double *) RelinquishMagickMemory(coordinates);
10768 break;
10769 }
10770 case 113: /* Clut */
10771 {
10772 PixelInterpolateMethod
10773 method;
10774
10775 if (attribute_flag[0] == 0)
10776 {
10777 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10778 PackageName);
10779 goto PerlException;
10780 }
10781 method=UndefinedInterpolatePixel;
10782 if (attribute_flag[1] != 0)
10783 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10784 if (attribute_flag[2] != 0)
10785 channel=(ChannelType) argument_list[2].integer_reference;
10786 channel_mask=SetImageChannelMask(image,channel);
10787 (void) ClutImage(image,argument_list[0].image_reference,method,
10788 exception);
10789 (void) SetImageChannelMask(image,channel_mask);
10790 break;
10791 }
10792 case 114: /* LiquidRescale */
10793 {
10794 if (attribute_flag[0] != 0)
10795 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10796 &geometry,exception);
10797 if (attribute_flag[1] != 0)
10798 geometry.width=argument_list[1].integer_reference;
10799 if (attribute_flag[2] != 0)
10800 geometry.height=argument_list[2].integer_reference;
10801 if (attribute_flag[3] == 0)
10802 argument_list[3].real_reference=1.0;
10803 if (attribute_flag[4] == 0)
10804 argument_list[4].real_reference=0.0;
10805 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10806 argument_list[3].real_reference,argument_list[4].real_reference,
10807 exception);
10808 break;
10809 }
10810 case 115: /* EncipherImage */
10811 {
10812 (void) EncipherImage(image,argument_list[0].string_reference,
10813 exception);
10814 break;
10815 }
10816 case 116: /* DecipherImage */
10817 {
10818 (void) DecipherImage(image,argument_list[0].string_reference,
10819 exception);
10820 break;
10821 }
10822 case 117: /* Deskew */
10823 {
10824 geometry_info.rho=QuantumRange/2.0;
10825 if (attribute_flag[0] != 0)
10826 flags=ParseGeometry(argument_list[0].string_reference,
10827 &geometry_info);
10828 if (attribute_flag[1] != 0)
10829 geometry_info.rho=StringToDoubleInterval(
10830 argument_list[1].string_reference,(double) QuantumRange+1.0);
10831 image=DeskewImage(image,geometry_info.rho,exception);
10832 break;
10833 }
10834 case 118: /* Remap */
10835 {
10836 QuantizeInfo
10837 *quantize_info;
10838
10839 if (attribute_flag[0] == 0)
10840 {
10841 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10842 PackageName);
10843 goto PerlException;
10844 }
10845 quantize_info=AcquireQuantizeInfo(info->image_info);
10846 if (attribute_flag[1] != 0)
10847 quantize_info->dither_method=(DitherMethod)
10848 argument_list[1].integer_reference;
10849 (void) RemapImages(quantize_info,image,
10850 argument_list[0].image_reference,exception);
10851 quantize_info=DestroyQuantizeInfo(quantize_info);
10852 break;
10853 }
10854 case 119: /* SparseColor */
10855 {
10856 AV
10857 *av;
10858
10859 double
10860 *coordinates;
10861
10862 SparseColorMethod
10863 method;
10864
10865 size_t
10866 number_coordinates;
10867
10868 VirtualPixelMethod
10869 virtual_pixel;
10870
10871 if (attribute_flag[0] == 0)
10872 break;
10873 method=UndefinedColorInterpolate;
10874 if (attribute_flag[1] != 0)
10875 method=(SparseColorMethod) argument_list[1].integer_reference;
10876 av=(AV *) argument_list[0].array_reference;
10877 number_coordinates=(size_t) av_len(av)+1;
10878 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10879 sizeof(*coordinates));
10880 if (coordinates == (double *) NULL)
10881 {
10882 ThrowPerlException(exception,ResourceLimitFatalError,
10883 "MemoryAllocationFailed",PackageName);
10884 goto PerlException;
10885 }
10886 for (j=0; j < (ssize_t) number_coordinates; j++)
10887 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10888 virtual_pixel=UndefinedVirtualPixelMethod;
10889 if (attribute_flag[2] != 0)
10890 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10891 argument_list[2].integer_reference,exception);
10892 if (attribute_flag[3] != 0)
10893 channel=(ChannelType) argument_list[3].integer_reference;
10894 channel_mask=SetImageChannelMask(image,channel);
10895 image=SparseColorImage(image,method,number_coordinates,coordinates,
10896 exception);
10897 if (image != (Image *) NULL)
10898 (void) SetImageChannelMask(image,channel_mask);
10899 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10900 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10901 exception);
10902 coordinates=(double *) RelinquishMagickMemory(coordinates);
10903 break;
10904 }
10905 case 120: /* Function */
10906 {
10907 AV
10908 *av;
10909
10910 double
10911 *parameters;
10912
10913 MagickFunction
10914 function;
10915
10916 size_t
10917 number_parameters;
10918
10919 VirtualPixelMethod
10920 virtual_pixel;
10921
10922 if (attribute_flag[0] == 0)
10923 break;
10924 function=UndefinedFunction;
10925 if (attribute_flag[1] != 0)
10926 function=(MagickFunction) argument_list[1].integer_reference;
10927 av=(AV *) argument_list[0].array_reference;
10928 number_parameters=(size_t) av_len(av)+1;
10929 parameters=(double *) AcquireQuantumMemory(number_parameters,
10930 sizeof(*parameters));
10931 if (parameters == (double *) NULL)
10932 {
10933 ThrowPerlException(exception,ResourceLimitFatalError,
10934 "MemoryAllocationFailed",PackageName);
10935 goto PerlException;
10936 }
10937 for (j=0; j < (ssize_t) number_parameters; j++)
10938 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10939 virtual_pixel=UndefinedVirtualPixelMethod;
10940 if (attribute_flag[2] != 0)
10941 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10942 argument_list[2].integer_reference,exception);
10943 (void) FunctionImage(image,function,number_parameters,parameters,
10944 exception);
10945 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10946 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10947 exception);
10948 parameters=(double *) RelinquishMagickMemory(parameters);
10949 break;
10950 }
10951 case 121: /* SelectiveBlur */
10952 {
10953 if (attribute_flag[0] != 0)
10954 {
10955 flags=ParseGeometry(argument_list[0].string_reference,
10956 &geometry_info);
10957 if ((flags & SigmaValue) == 0)
10958 geometry_info.sigma=1.0;
10959 if ((flags & PercentValue) != 0)
10960 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10961 }
10962 if (attribute_flag[1] != 0)
10963 geometry_info.rho=argument_list[1].real_reference;
10964 if (attribute_flag[2] != 0)
10965 geometry_info.sigma=argument_list[2].real_reference;
10966 if (attribute_flag[3] != 0)
10967 geometry_info.xi=argument_list[3].integer_reference;;
10968 if (attribute_flag[5] != 0)
10969 channel=(ChannelType) argument_list[5].integer_reference;
10970 channel_mask=SetImageChannelMask(image,channel);
10971 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10972 geometry_info.xi,exception);
10973 if (image != (Image *) NULL)
10974 (void) SetImageChannelMask(image,channel_mask);
10975 break;
10976 }
10977 case 122: /* HaldClut */
10978 {
10979 if (attribute_flag[0] == 0)
10980 {
10981 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10982 PackageName);
10983 goto PerlException;
10984 }
10985 if (attribute_flag[1] != 0)
10986 channel=(ChannelType) argument_list[1].integer_reference;
10987 channel_mask=SetImageChannelMask(image,channel);
10988 (void) HaldClutImage(image,argument_list[0].image_reference,
10989 exception);
10990 (void) SetImageChannelMask(image,channel_mask);
10991 break;
10992 }
10993 case 123: /* BlueShift */
10994 {
10995 if (attribute_flag[0] != 0)
10996 (void) ParseGeometry(argument_list[0].string_reference,
10997 &geometry_info);
10998 image=BlueShiftImage(image,geometry_info.rho,exception);
10999 break;
11000 }
11001 case 124: /* ForwardFourierTransformImage */
11002 {
11003 image=ForwardFourierTransformImage(image,
11004 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11005 exception);
11006 break;
11007 }
11008 case 125: /* InverseFourierTransformImage */
11009 {
11010 image=InverseFourierTransformImage(image,image->next,
11011 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11012 exception);
11013 break;
11014 }
11015 case 126: /* ColorDecisionList */
11016 {
11017 if (attribute_flag[0] == 0)
11018 argument_list[0].string_reference=(char *) NULL;
11019 (void) ColorDecisionListImage(image,
11020 argument_list[0].string_reference,exception);
11021 break;
11022 }
11023 case 127: /* AutoGamma */
11024 {
11025 if (attribute_flag[0] != 0)
11026 channel=(ChannelType) argument_list[0].integer_reference;
11027 channel_mask=SetImageChannelMask(image,channel);
11028 (void) AutoGammaImage(image,exception);
11029 (void) SetImageChannelMask(image,channel_mask);
11030 break;
11031 }
11032 case 128: /* AutoLevel */
11033 {
11034 if (attribute_flag[0] != 0)
11035 channel=(ChannelType) argument_list[0].integer_reference;
11036 channel_mask=SetImageChannelMask(image,channel);
11037 (void) AutoLevelImage(image,exception);
11038 (void) SetImageChannelMask(image,channel_mask);
11039 break;
11040 }
11041 case 129: /* LevelColors */
11042 {
11043 PixelInfo
11044 black_point,
11045 white_point;
11046
11047 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
11048 exception);
11049 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
11050 exception);
11051 if (attribute_flag[1] != 0)
11052 (void) QueryColorCompliance(
11053 argument_list[1].string_reference,AllCompliance,&black_point,
11054 exception);
11055 if (attribute_flag[2] != 0)
11056 (void) QueryColorCompliance(
11057 argument_list[2].string_reference,AllCompliance,&white_point,
11058 exception);
11059 if (attribute_flag[3] != 0)
11060 channel=(ChannelType) argument_list[3].integer_reference;
11061 channel_mask=SetImageChannelMask(image,channel);
11062 (void) LevelImageColors(image,&black_point,&white_point,
11063 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11064 exception);
11065 (void) SetImageChannelMask(image,channel_mask);
11066 break;
11067 }
11068 case 130: /* Clamp */
11069 {
11070 if (attribute_flag[0] != 0)
11071 channel=(ChannelType) argument_list[0].integer_reference;
11072 channel_mask=SetImageChannelMask(image,channel);
11073 (void) ClampImage(image,exception);
11074 (void) SetImageChannelMask(image,channel_mask);
11075 break;
11076 }
11077 case 131: /* BrightnessContrast */
11078 {
11079 double
11080 brightness,
11081 contrast;
11082
11083 brightness=0.0;
11084 contrast=0.0;
11085 if (attribute_flag[0] != 0)
11086 {
11087 flags=ParseGeometry(argument_list[0].string_reference,
11088 &geometry_info);
11089 brightness=geometry_info.rho;
11090 if ((flags & SigmaValue) == 0)
11091 contrast=geometry_info.sigma;
11092 }
11093 if (attribute_flag[1] != 0)
11094 brightness=argument_list[1].real_reference;
11095 if (attribute_flag[2] != 0)
11096 contrast=argument_list[2].real_reference;
11097 if (attribute_flag[4] != 0)
11098 channel=(ChannelType) argument_list[4].integer_reference;
11099 channel_mask=SetImageChannelMask(image,channel);
11100 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11101 (void) SetImageChannelMask(image,channel_mask);
11102 break;
11103 }
11104 case 132: /* Morphology */
11105 {
11106 KernelInfo
11107 *kernel;
11108
11109 MorphologyMethod
11110 method;
11111
11112 ssize_t
11113 iterations;
11114
11115 if (attribute_flag[0] == 0)
11116 break;
11117 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
11118 if (kernel == (KernelInfo *) NULL)
11119 break;
11120 if (attribute_flag[1] != 0)
11121 channel=(ChannelType) argument_list[1].integer_reference;
11122 method=UndefinedMorphology;
11123 if (attribute_flag[2] != 0)
11124 method=argument_list[2].integer_reference;
11125 iterations=1;
11126 if (attribute_flag[3] != 0)
11127 iterations=argument_list[3].integer_reference;
11128 channel_mask=SetImageChannelMask(image,channel);
11129 image=MorphologyImage(image,method,iterations,kernel,exception);
11130 if (image != (Image *) NULL)
11131 (void) SetImageChannelMask(image,channel_mask);
11132 kernel=DestroyKernelInfo(kernel);
11133 break;
11134 }
11135 case 133: /* Mode */
11136 {
11137 if (attribute_flag[0] != 0)
11138 {
11139 flags=ParseGeometry(argument_list[0].string_reference,
11140 &geometry_info);
11141 if ((flags & SigmaValue) == 0)
11142 geometry_info.sigma=1.0;
11143 }
11144 if (attribute_flag[1] != 0)
11145 geometry_info.rho=argument_list[1].real_reference;
11146 if (attribute_flag[2] != 0)
11147 geometry_info.sigma=argument_list[2].real_reference;
11148 if (attribute_flag[3] != 0)
11149 channel=(ChannelType) argument_list[3].integer_reference;
11150 channel_mask=SetImageChannelMask(image,channel);
11151 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11152 (size_t) geometry_info.sigma,exception);
11153 if (image != (Image *) NULL)
11154 (void) SetImageChannelMask(image,channel_mask);
11155 break;
11156 }
11157 case 134: /* Statistic */
11158 {
11159 StatisticType
11160 statistic;
11161
11162 statistic=UndefinedStatistic;
11163 if (attribute_flag[0] != 0)
11164 {
11165 flags=ParseGeometry(argument_list[0].string_reference,
11166 &geometry_info);
11167 if ((flags & SigmaValue) == 0)
11168 geometry_info.sigma=1.0;
11169 }
11170 if (attribute_flag[1] != 0)
11171 geometry_info.rho=argument_list[1].real_reference;
11172 if (attribute_flag[2] != 0)
11173 geometry_info.sigma=argument_list[2].real_reference;
11174 if (attribute_flag[3] != 0)
11175 channel=(ChannelType) argument_list[3].integer_reference;
11176 if (attribute_flag[4] != 0)
11177 statistic=(StatisticType) argument_list[4].integer_reference;
11178 channel_mask=SetImageChannelMask(image,channel);
11179 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11180 (size_t) geometry_info.sigma,exception);
11181 if (image != (Image *) NULL)
11182 (void) SetImageChannelMask(image,channel_mask);
11183 break;
11184 }
11185 case 135: /* Perceptible */
11186 {
11187 double
11188 epsilon;
11189
11190 epsilon=MagickEpsilon;
11191 if (attribute_flag[0] != 0)
11192 epsilon=argument_list[0].real_reference;
11193 if (attribute_flag[1] != 0)
11194 channel=(ChannelType) argument_list[1].integer_reference;
11195 channel_mask=SetImageChannelMask(image,channel);
11196 (void) PerceptibleImage(image,epsilon,exception);
11197 (void) SetImageChannelMask(image,channel_mask);
11198 break;
11199 }
11200 case 136: /* Poly */
11201 {
11202 AV
11203 *av;
11204
11205 double
11206 *terms;
11207
11208 size_t
11209 number_terms;
11210
11211 if (attribute_flag[0] == 0)
11212 break;
11213 if (attribute_flag[1] != 0)
11214 channel=(ChannelType) argument_list[1].integer_reference;
11215 av=(AV *) argument_list[0].array_reference;
11216 number_terms=(size_t) av_len(av);
11217 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11218 if (terms == (double *) NULL)
11219 {
11220 ThrowPerlException(exception,ResourceLimitFatalError,
11221 "MemoryAllocationFailed",PackageName);
11222 goto PerlException;
11223 }
11224 for (j=0; j < av_len(av); j++)
11225 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11226 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11227 terms=(double *) RelinquishMagickMemory(terms);
11228 break;
11229 }
11230 case 137: /* Grayscale */
11231 {
11232 PixelIntensityMethod
11233 method;
11234
11235 method=UndefinedPixelIntensityMethod;
11236 if (attribute_flag[0] != 0)
11237 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11238 (void) GrayscaleImage(image,method,exception);
11239 break;
11240 }
11241 case 138: /* Canny */
11242 {
11243 if (attribute_flag[0] != 0)
11244 {
11245 flags=ParseGeometry(argument_list[0].string_reference,
11246 &geometry_info);
11247 if ((flags & SigmaValue) == 0)
11248 geometry_info.sigma=1.0;
11249 if ((flags & XiValue) == 0)
11250 geometry_info.xi=0.10;
11251 if ((flags & PsiValue) == 0)
11252 geometry_info.psi=0.30;
11253 if ((flags & PercentValue) != 0)
11254 {
11255 geometry_info.xi/=100.0;
11256 geometry_info.psi/=100.0;
11257 }
11258 }
11259 if (attribute_flag[1] != 0)
11260 geometry_info.rho=argument_list[1].real_reference;
11261 if (attribute_flag[2] != 0)
11262 geometry_info.sigma=argument_list[2].real_reference;
11263 if (attribute_flag[3] != 0)
11264 geometry_info.xi=argument_list[3].real_reference;
11265 if (attribute_flag[4] != 0)
11266 geometry_info.psi=argument_list[4].real_reference;
11267 if (attribute_flag[5] != 0)
11268 channel=(ChannelType) argument_list[5].integer_reference;
11269 channel_mask=SetImageChannelMask(image,channel);
11270 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11271 geometry_info.xi,geometry_info.psi,exception);
11272 if (image != (Image *) NULL)
11273 (void) SetImageChannelMask(image,channel_mask);
11274 break;
11275 }
11276 case 139: /* HoughLine */
11277 {
11278 if (attribute_flag[0] != 0)
11279 {
11280 flags=ParseGeometry(argument_list[0].string_reference,
11281 &geometry_info);
11282 if ((flags & SigmaValue) == 0)
11283 geometry_info.sigma=geometry_info.rho;
11284 if ((flags & XiValue) == 0)
11285 geometry_info.xi=40;
11286 }
11287 if (attribute_flag[1] != 0)
11288 geometry_info.rho=(double) argument_list[1].integer_reference;
11289 if (attribute_flag[2] != 0)
11290 geometry_info.sigma=(double) argument_list[2].integer_reference;
11291 if (attribute_flag[3] != 0)
11292 geometry_info.xi=(double) argument_list[3].integer_reference;
11293 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11294 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11295 break;
11296 }
11297 case 140: /* MeanShift */
11298 {
11299 if (attribute_flag[0] != 0)
11300 {
11301 flags=ParseGeometry(argument_list[0].string_reference,
11302 &geometry_info);
11303 if ((flags & SigmaValue) == 0)
11304 geometry_info.sigma=geometry_info.rho;
11305 if ((flags & XiValue) == 0)
11306 geometry_info.xi=0.10*QuantumRange;
11307 if ((flags & PercentValue) != 0)
11308 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
11309 }
11310 if (attribute_flag[1] != 0)
11311 geometry_info.rho=(double) argument_list[1].integer_reference;
11312 if (attribute_flag[2] != 0)
11313 geometry_info.sigma=(double) argument_list[2].integer_reference;
11314 if (attribute_flag[3] != 0)
11315 geometry_info.xi=(double) argument_list[3].integer_reference;
11316 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
11317 geometry_info.sigma,geometry_info.xi,exception);
11318 break;
11319 }
11320 case 141: /* Kuwahara */
11321 {
11322 if (attribute_flag[0] != 0)
11323 {
11324 flags=ParseGeometry(argument_list[0].string_reference,
11325 &geometry_info);
11326 if ((flags & SigmaValue) == 0)
11327 geometry_info.sigma=geometry_info.rho-0.5;
11328 }
11329 if (attribute_flag[1] != 0)
11330 geometry_info.rho=argument_list[1].real_reference;
11331 if (attribute_flag[2] != 0)
11332 geometry_info.sigma=argument_list[2].real_reference;
11333 if (attribute_flag[3] != 0)
11334 channel=(ChannelType) argument_list[3].integer_reference;
11335 channel_mask=SetImageChannelMask(image,channel);
11336 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11337 exception);
11338 if (image != (Image *) NULL)
11339 (void) SetImageChannelMask(image,channel_mask);
11340 break;
11341 }
11342 case 142: /* ConnectedComponents */
11343 {
11344 size_t
11345 connectivity;
11346
11347 connectivity=4;
11348 if (attribute_flag[0] != 0)
11349 connectivity=argument_list[0].integer_reference;
11350 image=ConnectedComponentsImage(image,connectivity,
11351 (CCObjectInfo **) NULL,exception);
11352 break;
11353 }
11354 case 143: /* Copy */
11355 {
11356 Image
11357 *source_image;
11358
11359 OffsetInfo
11360 offset;
11361
11362 RectangleInfo
11363 offset_geometry;
11364
11365 source_image=image;
11366 if (attribute_flag[0] != 0)
11367 source_image=argument_list[0].image_reference;
11368 SetGeometry(source_image,&geometry);
11369 if (attribute_flag[1] != 0)
11370 flags=ParseGravityGeometry(source_image,
11371 argument_list[1].string_reference,&geometry,exception);
11372 if (attribute_flag[2] != 0)
11373 geometry.width=argument_list[2].integer_reference;
11374 if (attribute_flag[3] != 0)
11375 geometry.height=argument_list[3].integer_reference;
11376 if (attribute_flag[4] != 0)
11377 geometry.x=argument_list[4].integer_reference;
11378 if (attribute_flag[5] != 0)
11379 geometry.y=argument_list[5].integer_reference;
11380 if (attribute_flag[6] != 0)
11381 image->gravity=(GravityType) argument_list[6].integer_reference;
11382 SetGeometry(image,&offset_geometry);
11383 if (attribute_flag[7] != 0)
11384 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11385 &offset_geometry,exception);
11386 offset.x=offset_geometry.x;
11387 offset.y=offset_geometry.y;
11388 if (attribute_flag[8] != 0)
11389 offset.x=argument_list[8].integer_reference;
11390 if (attribute_flag[9] != 0)
11391 offset.y=argument_list[9].integer_reference;
11392 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11393 exception);
11394 break;
11395 }
11396 case 144: /* Color */
11397 {
11398 PixelInfo
11399 color;
11400
11401 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
11402 if (attribute_flag[0] != 0)
11403 (void) QueryColorCompliance(argument_list[0].string_reference,
11404 AllCompliance,&color,exception);
11405 (void) SetImageColor(image,&color,exception);
11406 break;
11407 }
11408 case 145: /* WaveletDenoise */
11409 {
11410 if (attribute_flag[0] != 0)
11411 {
11412 flags=ParseGeometry(argument_list[0].string_reference,
11413 &geometry_info);
11414 if ((flags & PercentValue) != 0)
11415 {
11416 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11417 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11418 }
11419 if ((flags & SigmaValue) == 0)
11420 geometry_info.sigma=0.0;
11421 }
11422 if (attribute_flag[1] != 0)
11423 geometry_info.rho=argument_list[1].real_reference;
11424 if (attribute_flag[2] != 0)
11425 geometry_info.sigma=argument_list[2].real_reference;
11426 if (attribute_flag[3] != 0)
11427 channel=(ChannelType) argument_list[3].integer_reference;
11428 channel_mask=SetImageChannelMask(image,channel);
11429 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11430 exception);
11431 if (image != (Image *) NULL)
11432 (void) SetImageChannelMask(image,channel_mask);
11433 break;
11434 }
11435 case 146: /* Colorspace */
11436 {
11437 ColorspaceType
11438 colorspace;
11439
11440 colorspace=sRGBColorspace;
11441 if (attribute_flag[0] != 0)
11442 colorspace=(ColorspaceType) argument_list[0].integer_reference;
11443 (void) TransformImageColorspace(image,colorspace,exception);
11444 break;
11445 }
11446 case 147: /* AutoThreshold */
11447 {
11448 AutoThresholdMethod
11449 method;
11450
11451 method=UndefinedThresholdMethod;
11452 if (attribute_flag[0] != 0)
11453 method=(AutoThresholdMethod) argument_list[0].integer_reference;
11454 (void) AutoThresholdImage(image,method,exception);
11455 break;
11456 }
11457 case 148: /* RangeThreshold */
11458 {
11459 if (attribute_flag[0] != 0)
11460 {
11461 flags=ParseGeometry(argument_list[0].string_reference,
11462 &geometry_info);
11463 if ((flags & SigmaValue) == 0)
11464 geometry_info.sigma=geometry_info.rho;
11465 if ((flags & XiValue) == 0)
11466 geometry_info.xi=geometry_info.sigma;
11467 if ((flags & PsiValue) == 0)
11468 geometry_info.psi=geometry_info.xi;
11469 }
11470 if (attribute_flag[1] != 0)
11471 geometry_info.rho=argument_list[1].real_reference;
11472 if (attribute_flag[2] != 0)
11473 geometry_info.sigma=argument_list[2].real_reference;
11474 if (attribute_flag[3] != 0)
11475 geometry_info.xi=argument_list[3].real_reference;
11476 if (attribute_flag[4] != 0)
11477 geometry_info.psi=argument_list[4].real_reference;
11478 if (attribute_flag[5] != 0)
11479 channel=(ChannelType) argument_list[5].integer_reference;
11480 channel_mask=SetImageChannelMask(image,channel);
11481 (void) RangeThresholdImage(image,geometry_info.rho,
11482 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
11483 if (image != (Image *) NULL)
11484 (void) SetImageChannelMask(image,channel_mask);
11485 break;
11486 }
11487 case 149: /* CLAHE */
11488 {
11489 if (attribute_flag[0] != 0)
11490 {
11491 flags=ParseGeometry(argument_list[0].string_reference,
11492 &geometry_info);
11493 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
11494 &geometry,exception);
11495 }
11496 if (attribute_flag[1] != 0)
11497 geometry.width=argument_list[1].integer_reference;
11498 if (attribute_flag[2] != 0)
11499 geometry.height=argument_list[2].integer_reference;
11500 if (attribute_flag[3] != 0)
11501 geometry.x=argument_list[3].integer_reference;
11502 if (attribute_flag[4] != 0)
11503 geometry_info.psi=argument_list[4].real_reference;
11504 (void) CLAHEImage(image,geometry.width,geometry.height,geometry.x,
11505 geometry_info.psi,exception);
11506 break;
11507 }
11508 case 150: /* Kmeans */
11509 {
11510 if (attribute_flag[0] != 0)
11511 {
11512 flags=ParseGeometry(argument_list[0].string_reference,
11513 &geometry_info);
11514 if ((flags & SigmaValue) == 0)
11515 geometry_info.sigma=100.0;
11516 if ((flags & XiValue) == 0)
11517 geometry_info.xi=0.01;
11518 }
11519 if (attribute_flag[1] != 0)
11520 geometry_info.rho=argument_list[1].integer_reference;
11521 if (attribute_flag[2] != 0)
11522 geometry_info.sigma=argument_list[2].integer_reference;
11523 if (attribute_flag[3] != 0)
11524 geometry_info.xi=(ChannelType) argument_list[3].real_reference;
11525 (void) KmeansImage(image,geometry_info.rho,geometry_info.sigma,
11526 geometry_info.xi,exception);
11527 break;
11528 }
11529 }
11530 if (next != (Image *) NULL)
11531 (void) CatchImageException(next);
11532 if ((region_info.width*region_info.height) != 0)
11533 (void) SetImageRegionMask(image,WritePixelMask,
11534 (const RectangleInfo *) NULL,exception);
11535 if (image != (Image *) NULL)
11536 {
11537 number_images++;
11538 if (next && (next != image))
11539 {
11540 image->next=next->next;
11541 if (image->next != (Image *) NULL)
11542 image->next->previous=image;
11543 DeleteImageFromRegistry(*pv,next);
11544 }
11545 sv_setiv(*pv,PTR2IV(image));
11546 next=image;
11547 }
11548 if (*pv)
11549 pv++;
11550 }
11551
11552 PerlException:
11553 if (reference_vector)
11554 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11555 InheritPerlException(exception,perl_exception);
11556 exception=DestroyExceptionInfo(exception);
11557 sv_setiv(perl_exception,(IV) number_images);
11558 SvPOK_on(perl_exception);
11559 ST(0)=sv_2mortal(perl_exception);
11560 XSRETURN(1);
11561 }
11562
11563 #
11564 ###############################################################################
11565 # #
11566 # #
11567 # #
11568 # M o n t a g e #
11569 # #
11570 # #
11571 # #
11572 ###############################################################################
11573 #
11574 #
11575 void
Montage(ref,...)11576 Montage(ref,...)
11577 Image::Magick ref=NO_INIT
11578 ALIAS:
11579 MontageImage = 1
11580 montage = 2
11581 montageimage = 3
11582 PPCODE:
11583 {
11584 AV
11585 *av;
11586
11587 char
11588 *attribute;
11589
11590 ExceptionInfo
11591 *exception;
11592
11593 HV
11594 *hv;
11595
11596 Image
11597 *image,
11598 *next;
11599
11600 PixelInfo
11601 transparent_color;
11602
11603 MontageInfo
11604 *montage_info;
11605
11606 register ssize_t
11607 i;
11608
11609 ssize_t
11610 sp;
11611
11612 struct PackageInfo
11613 *info;
11614
11615 SV
11616 *av_reference,
11617 *perl_exception,
11618 *reference,
11619 *rv,
11620 *sv;
11621
11622 PERL_UNUSED_VAR(ref);
11623 PERL_UNUSED_VAR(ix);
11624 exception=AcquireExceptionInfo();
11625 perl_exception=newSVpv("",0);
11626 sv=NULL;
11627 attribute=NULL;
11628 if (sv_isobject(ST(0)) == 0)
11629 {
11630 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11631 PackageName);
11632 goto PerlException;
11633 }
11634 reference=SvRV(ST(0));
11635 hv=SvSTASH(reference);
11636 av=newAV();
11637 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11638 SvREFCNT_dec(av);
11639 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11640 if (image == (Image *) NULL)
11641 {
11642 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11643 PackageName);
11644 goto PerlException;
11645 }
11646 /*
11647 Get options.
11648 */
11649 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11650 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11651 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11652 exception);
11653 for (i=2; i < items; i+=2)
11654 {
11655 attribute=(char *) SvPV(ST(i-1),na);
11656 switch (*attribute)
11657 {
11658 case 'B':
11659 case 'b':
11660 {
11661 if (LocaleCompare(attribute,"background") == 0)
11662 {
11663 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11664 &montage_info->background_color,exception);
11665 for (next=image; next; next=next->next)
11666 next->background_color=montage_info->background_color;
11667 break;
11668 }
11669 if (LocaleCompare(attribute,"border") == 0)
11670 {
11671 montage_info->border_width=SvIV(ST(i));
11672 break;
11673 }
11674 if (LocaleCompare(attribute,"bordercolor") == 0)
11675 {
11676 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11677 &montage_info->border_color,exception);
11678 for (next=image; next; next=next->next)
11679 next->border_color=montage_info->border_color;
11680 break;
11681 }
11682 if (LocaleCompare(attribute,"borderwidth") == 0)
11683 {
11684 montage_info->border_width=SvIV(ST(i));
11685 break;
11686 }
11687 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11688 attribute);
11689 break;
11690 }
11691 case 'C':
11692 case 'c':
11693 {
11694 if (LocaleCompare(attribute,"compose") == 0)
11695 {
11696 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11697 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11698 if (sp < 0)
11699 {
11700 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11701 SvPV(ST(i),na));
11702 break;
11703 }
11704 for (next=image; next; next=next->next)
11705 next->compose=(CompositeOperator) sp;
11706 break;
11707 }
11708 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11709 attribute);
11710 break;
11711 }
11712 case 'F':
11713 case 'f':
11714 {
11715 if (LocaleCompare(attribute,"fill") == 0)
11716 {
11717 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11718 &montage_info->fill,exception);
11719 break;
11720 }
11721 if (LocaleCompare(attribute,"font") == 0)
11722 {
11723 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11724 break;
11725 }
11726 if (LocaleCompare(attribute,"frame") == 0)
11727 {
11728 char
11729 *p;
11730
11731 p=SvPV(ST(i),na);
11732 if (IsGeometry(p) == MagickFalse)
11733 {
11734 ThrowPerlException(exception,OptionError,"MissingGeometry",
11735 p);
11736 break;
11737 }
11738 (void) CloneString(&montage_info->frame,p);
11739 if (*p == '\0')
11740 montage_info->frame=(char *) NULL;
11741 break;
11742 }
11743 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11744 attribute);
11745 break;
11746 }
11747 case 'G':
11748 case 'g':
11749 {
11750 if (LocaleCompare(attribute,"geometry") == 0)
11751 {
11752 char
11753 *p;
11754
11755 p=SvPV(ST(i),na);
11756 if (IsGeometry(p) == MagickFalse)
11757 {
11758 ThrowPerlException(exception,OptionError,"MissingGeometry",
11759 p);
11760 break;
11761 }
11762 (void) CloneString(&montage_info->geometry,p);
11763 if (*p == '\0')
11764 montage_info->geometry=(char *) NULL;
11765 break;
11766 }
11767 if (LocaleCompare(attribute,"gravity") == 0)
11768 {
11769 ssize_t
11770 in;
11771
11772 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11773 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11774 if (in < 0)
11775 {
11776 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11777 SvPV(ST(i),na));
11778 return;
11779 }
11780 montage_info->gravity=(GravityType) in;
11781 for (next=image; next; next=next->next)
11782 next->gravity=(GravityType) in;
11783 break;
11784 }
11785 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11786 attribute);
11787 break;
11788 }
11789 case 'L':
11790 case 'l':
11791 {
11792 if (LocaleCompare(attribute,"label") == 0)
11793 {
11794 for (next=image; next; next=next->next)
11795 (void) SetImageProperty(next,"label",InterpretImageProperties(
11796 info ? info->image_info : (ImageInfo *) NULL,next,
11797 SvPV(ST(i),na),exception),exception);
11798 break;
11799 }
11800 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11801 attribute);
11802 break;
11803 }
11804 case 'M':
11805 case 'm':
11806 {
11807 if (LocaleCompare(attribute,"mattecolor") == 0)
11808 {
11809 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11810 &montage_info->alpha_color,exception);
11811 for (next=image; next; next=next->next)
11812 next->alpha_color=montage_info->alpha_color;
11813 break;
11814 }
11815 if (LocaleCompare(attribute,"mode") == 0)
11816 {
11817 ssize_t
11818 in;
11819
11820 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11821 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11822 switch (in)
11823 {
11824 default:
11825 {
11826 ThrowPerlException(exception,OptionError,
11827 "UnrecognizedModeType",SvPV(ST(i),na));
11828 break;
11829 }
11830 case FrameMode:
11831 {
11832 (void) CloneString(&montage_info->frame,"15x15+3+3");
11833 montage_info->shadow=MagickTrue;
11834 break;
11835 }
11836 case UnframeMode:
11837 {
11838 montage_info->frame=(char *) NULL;
11839 montage_info->shadow=MagickFalse;
11840 montage_info->border_width=0;
11841 break;
11842 }
11843 case ConcatenateMode:
11844 {
11845 montage_info->frame=(char *) NULL;
11846 montage_info->shadow=MagickFalse;
11847 (void) CloneString(&montage_info->geometry,"+0+0");
11848 montage_info->border_width=0;
11849 }
11850 }
11851 break;
11852 }
11853 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11854 attribute);
11855 break;
11856 }
11857 case 'P':
11858 case 'p':
11859 {
11860 if (LocaleCompare(attribute,"pointsize") == 0)
11861 {
11862 montage_info->pointsize=SvIV(ST(i));
11863 break;
11864 }
11865 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11866 attribute);
11867 break;
11868 }
11869 case 'S':
11870 case 's':
11871 {
11872 if (LocaleCompare(attribute,"shadow") == 0)
11873 {
11874 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11875 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11876 if (sp < 0)
11877 {
11878 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11879 SvPV(ST(i),na));
11880 break;
11881 }
11882 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11883 break;
11884 }
11885 if (LocaleCompare(attribute,"stroke") == 0)
11886 {
11887 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11888 &montage_info->stroke,exception);
11889 break;
11890 }
11891 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11892 attribute);
11893 break;
11894 }
11895 case 'T':
11896 case 't':
11897 {
11898 if (LocaleCompare(attribute,"texture") == 0)
11899 {
11900 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11901 break;
11902 }
11903 if (LocaleCompare(attribute,"tile") == 0)
11904 {
11905 char *p=SvPV(ST(i),na);
11906 if (IsGeometry(p) == MagickFalse)
11907 {
11908 ThrowPerlException(exception,OptionError,"MissingGeometry",
11909 p);
11910 break;
11911 }
11912 (void) CloneString(&montage_info->tile,p);
11913 if (*p == '\0')
11914 montage_info->tile=(char *) NULL;
11915 break;
11916 }
11917 if (LocaleCompare(attribute,"title") == 0)
11918 {
11919 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11920 break;
11921 }
11922 if (LocaleCompare(attribute,"transparent") == 0)
11923 {
11924 PixelInfo
11925 transparent_color;
11926
11927 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11928 &transparent_color,exception);
11929 for (next=image; next; next=next->next)
11930 (void) TransparentPaintImage(next,&transparent_color,
11931 TransparentAlpha,MagickFalse,exception);
11932 break;
11933 }
11934 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11935 attribute);
11936 break;
11937 }
11938 default:
11939 {
11940 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11941 attribute);
11942 break;
11943 }
11944 }
11945 }
11946 image=MontageImageList(info->image_info,montage_info,image,exception);
11947 montage_info=DestroyMontageInfo(montage_info);
11948 if (image == (Image *) NULL)
11949 goto PerlException;
11950 if (transparent_color.alpha != TransparentAlpha)
11951 for (next=image; next; next=next->next)
11952 (void) TransparentPaintImage(next,&transparent_color,
11953 TransparentAlpha,MagickFalse,exception);
11954 for ( ; image; image=image->next)
11955 {
11956 AddImageToRegistry(sv,image);
11957 rv=newRV(sv);
11958 av_push(av,sv_bless(rv,hv));
11959 SvREFCNT_dec(sv);
11960 }
11961 exception=DestroyExceptionInfo(exception);
11962 ST(0)=av_reference;
11963 SvREFCNT_dec(perl_exception);
11964 XSRETURN(1);
11965
11966 PerlException:
11967 InheritPerlException(exception,perl_exception);
11968 exception=DestroyExceptionInfo(exception);
11969 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11970 SvPOK_on(perl_exception);
11971 ST(0)=sv_2mortal(perl_exception);
11972 XSRETURN(1);
11973 }
11974
11975 #
11976 ###############################################################################
11977 # #
11978 # #
11979 # #
11980 # M o r p h #
11981 # #
11982 # #
11983 # #
11984 ###############################################################################
11985 #
11986 #
11987 void
Morph(ref,...)11988 Morph(ref,...)
11989 Image::Magick ref=NO_INIT
11990 ALIAS:
11991 MorphImage = 1
11992 morph = 2
11993 morphimage = 3
11994 PPCODE:
11995 {
11996 AV
11997 *av;
11998
11999 char
12000 *attribute;
12001
12002 ExceptionInfo
12003 *exception;
12004
12005 HV
12006 *hv;
12007
12008 Image
12009 *image;
12010
12011 register ssize_t
12012 i;
12013
12014 ssize_t
12015 number_frames;
12016
12017 struct PackageInfo
12018 *info;
12019
12020 SV
12021 *av_reference,
12022 *perl_exception,
12023 *reference,
12024 *rv,
12025 *sv;
12026
12027 PERL_UNUSED_VAR(ref);
12028 PERL_UNUSED_VAR(ix);
12029 exception=AcquireExceptionInfo();
12030 perl_exception=newSVpv("",0);
12031 sv=NULL;
12032 av=NULL;
12033 attribute=NULL;
12034 if (sv_isobject(ST(0)) == 0)
12035 {
12036 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12037 PackageName);
12038 goto PerlException;
12039 }
12040 reference=SvRV(ST(0));
12041 hv=SvSTASH(reference);
12042 av=newAV();
12043 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12044 SvREFCNT_dec(av);
12045 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12046 if (image == (Image *) NULL)
12047 {
12048 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12049 PackageName);
12050 goto PerlException;
12051 }
12052 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12053 /*
12054 Get attribute.
12055 */
12056 number_frames=30;
12057 for (i=2; i < items; i+=2)
12058 {
12059 attribute=(char *) SvPV(ST(i-1),na);
12060 switch (*attribute)
12061 {
12062 case 'F':
12063 case 'f':
12064 {
12065 if (LocaleCompare(attribute,"frames") == 0)
12066 {
12067 number_frames=SvIV(ST(i));
12068 break;
12069 }
12070 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12071 attribute);
12072 break;
12073 }
12074 default:
12075 {
12076 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12077 attribute);
12078 break;
12079 }
12080 }
12081 }
12082 image=MorphImages(image,number_frames,exception);
12083 if (image == (Image *) NULL)
12084 goto PerlException;
12085 for ( ; image; image=image->next)
12086 {
12087 AddImageToRegistry(sv,image);
12088 rv=newRV(sv);
12089 av_push(av,sv_bless(rv,hv));
12090 SvREFCNT_dec(sv);
12091 }
12092 exception=DestroyExceptionInfo(exception);
12093 ST(0)=av_reference;
12094 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12095 XSRETURN(1);
12096
12097 PerlException:
12098 InheritPerlException(exception,perl_exception);
12099 exception=DestroyExceptionInfo(exception);
12100 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12101 SvPOK_on(perl_exception);
12102 ST(0)=sv_2mortal(perl_exception);
12103 XSRETURN(1);
12104 }
12105
12106 #
12107 ###############################################################################
12108 # #
12109 # #
12110 # #
12111 # M o s a i c #
12112 # #
12113 # #
12114 # #
12115 ###############################################################################
12116 #
12117 #
12118 void
Mosaic(ref)12119 Mosaic(ref)
12120 Image::Magick ref=NO_INIT
12121 ALIAS:
12122 MosaicImage = 1
12123 mosaic = 2
12124 mosaicimage = 3
12125 PPCODE:
12126 {
12127 AV
12128 *av;
12129
12130 ExceptionInfo
12131 *exception;
12132
12133 HV
12134 *hv;
12135
12136 Image
12137 *image;
12138
12139 struct PackageInfo
12140 *info;
12141
12142 SV
12143 *perl_exception,
12144 *reference,
12145 *rv,
12146 *sv;
12147
12148 PERL_UNUSED_VAR(ref);
12149 PERL_UNUSED_VAR(ix);
12150 exception=AcquireExceptionInfo();
12151 perl_exception=newSVpv("",0);
12152 sv=NULL;
12153 if (sv_isobject(ST(0)) == 0)
12154 {
12155 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12156 PackageName);
12157 goto PerlException;
12158 }
12159 reference=SvRV(ST(0));
12160 hv=SvSTASH(reference);
12161 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12162 if (image == (Image *) NULL)
12163 {
12164 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12165 PackageName);
12166 goto PerlException;
12167 }
12168 image=MergeImageLayers(image,MosaicLayer,exception);
12169 /*
12170 Create blessed Perl array for the returned image.
12171 */
12172 av=newAV();
12173 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12174 SvREFCNT_dec(av);
12175 AddImageToRegistry(sv,image);
12176 rv=newRV(sv);
12177 av_push(av,sv_bless(rv,hv));
12178 SvREFCNT_dec(sv);
12179 (void) CopyMagickString(info->image_info->filename,image->filename,
12180 MagickPathExtent);
12181 SetImageInfo(info->image_info,0,exception);
12182 exception=DestroyExceptionInfo(exception);
12183 SvREFCNT_dec(perl_exception);
12184 XSRETURN(1);
12185
12186 PerlException:
12187 InheritPerlException(exception,perl_exception);
12188 exception=DestroyExceptionInfo(exception);
12189 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12190 SvPOK_on(perl_exception); /* return messages in string context */
12191 ST(0)=sv_2mortal(perl_exception);
12192 XSRETURN(1);
12193 }
12194
12195 #
12196 ###############################################################################
12197 # #
12198 # #
12199 # #
12200 # P i n g #
12201 # #
12202 # #
12203 # #
12204 ###############################################################################
12205 #
12206 #
12207 void
Ping(ref,...)12208 Ping(ref,...)
12209 Image::Magick ref=NO_INIT
12210 ALIAS:
12211 PingImage = 1
12212 ping = 2
12213 pingimage = 3
12214 PPCODE:
12215 {
12216 AV
12217 *av;
12218
12219 char
12220 **keep,
12221 **list;
12222
12223 ExceptionInfo
12224 *exception;
12225
12226 Image
12227 *image,
12228 *next;
12229
12230 int
12231 n;
12232
12233 MagickBooleanType
12234 status;
12235
12236 register char
12237 **p;
12238
12239 register ssize_t
12240 i;
12241
12242 ssize_t
12243 ac;
12244
12245 STRLEN
12246 *length;
12247
12248 struct PackageInfo
12249 *info,
12250 *package_info;
12251
12252 SV
12253 *perl_exception,
12254 *reference;
12255
12256 size_t
12257 count;
12258
12259 PERL_UNUSED_VAR(ref);
12260 PERL_UNUSED_VAR(ix);
12261 exception=AcquireExceptionInfo();
12262 perl_exception=newSVpv("",0);
12263 package_info=(struct PackageInfo *) NULL;
12264 ac=(items < 2) ? 1 : items-1;
12265 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12266 keep=list;
12267 length=(STRLEN *) NULL;
12268 if (list == (char **) NULL)
12269 {
12270 ThrowPerlException(exception,ResourceLimitError,
12271 "MemoryAllocationFailed",PackageName);
12272 goto PerlException;
12273 }
12274 keep=list;
12275 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12276 if (length == (STRLEN *) NULL)
12277 {
12278 ThrowPerlException(exception,ResourceLimitError,
12279 "MemoryAllocationFailed",PackageName);
12280 goto PerlException;
12281 }
12282 if (sv_isobject(ST(0)) == 0)
12283 {
12284 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12285 PackageName);
12286 goto PerlException;
12287 }
12288 reference=SvRV(ST(0));
12289 if (SvTYPE(reference) != SVt_PVAV)
12290 {
12291 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12292 PackageName);
12293 goto PerlException;
12294 }
12295 av=(AV *) reference;
12296 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12297 exception);
12298 package_info=ClonePackageInfo(info,exception);
12299 n=1;
12300 if (items <= 1)
12301 *list=(char *) (*package_info->image_info->filename ?
12302 package_info->image_info->filename : "XC:black");
12303 else
12304 for (n=0, i=0; i < ac; i++)
12305 {
12306 list[n]=(char *) SvPV(ST(i+1),length[n]);
12307 if ((items >= 3) && strEQcase(list[n],"blob"))
12308 {
12309 void
12310 *blob;
12311
12312 i++;
12313 blob=(void *) (SvPV(ST(i+1),length[n]));
12314 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12315 }
12316 if ((items >= 3) && strEQcase(list[n],"filename"))
12317 continue;
12318 if ((items >= 3) && strEQcase(list[n],"file"))
12319 {
12320 FILE
12321 *file;
12322
12323 PerlIO
12324 *io_info;
12325
12326 i++;
12327 io_info=IoIFP(sv_2io(ST(i+1)));
12328 if (io_info == (PerlIO *) NULL)
12329 {
12330 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12331 PackageName);
12332 continue;
12333 }
12334 file=PerlIO_findFILE(io_info);
12335 if (file == (FILE *) NULL)
12336 {
12337 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12338 PackageName);
12339 continue;
12340 }
12341 SetImageInfoFile(package_info->image_info,file);
12342 }
12343 if ((items >= 3) && strEQcase(list[n],"magick"))
12344 continue;
12345 n++;
12346 }
12347 list[n]=(char *) NULL;
12348 keep=list;
12349 status=ExpandFilenames(&n,&list);
12350 if (status == MagickFalse)
12351 {
12352 ThrowPerlException(exception,ResourceLimitError,
12353 "MemoryAllocationFailed",PackageName);
12354 goto PerlException;
12355 }
12356 count=0;
12357 for (i=0; i < n; i++)
12358 {
12359 (void) CopyMagickString(package_info->image_info->filename,list[i],
12360 MagickPathExtent);
12361 image=PingImage(package_info->image_info,exception);
12362 if (image == (Image *) NULL)
12363 break;
12364 if ((package_info->image_info->file != (FILE *) NULL) ||
12365 (package_info->image_info->blob != (void *) NULL))
12366 DisassociateImageStream(image);
12367 count+=GetImageListLength(image);
12368 EXTEND(sp,4*count);
12369 for (next=image; next; next=next->next)
12370 {
12371 PUSHs(sv_2mortal(newSViv(next->columns)));
12372 PUSHs(sv_2mortal(newSViv(next->rows)));
12373 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12374 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12375 }
12376 image=DestroyImageList(image);
12377 }
12378 /*
12379 Free resources.
12380 */
12381 for (i=0; i < n; i++)
12382 if (list[i] != (char *) NULL)
12383 for (p=keep; list[i] != *p++; )
12384 if (*p == NULL)
12385 {
12386 list[i]=(char *) RelinquishMagickMemory(list[i]);
12387 break;
12388 }
12389
12390 PerlException:
12391 if (package_info != (struct PackageInfo *) NULL)
12392 DestroyPackageInfo(package_info);
12393 if (list && (list != keep))
12394 list=(char **) RelinquishMagickMemory(list);
12395 if (keep)
12396 keep=(char **) RelinquishMagickMemory(keep);
12397 if (length)
12398 length=(STRLEN *) RelinquishMagickMemory(length);
12399 InheritPerlException(exception,perl_exception);
12400 exception=DestroyExceptionInfo(exception);
12401 SvREFCNT_dec(perl_exception); /* throw away all errors */
12402 }
12403
12404 #
12405 ###############################################################################
12406 # #
12407 # #
12408 # #
12409 # P r e v i e w #
12410 # #
12411 # #
12412 # #
12413 ###############################################################################
12414 #
12415 #
12416 void
Preview(ref,...)12417 Preview(ref,...)
12418 Image::Magick ref=NO_INIT
12419 ALIAS:
12420 PreviewImage = 1
12421 preview = 2
12422 previewimage = 3
12423 PPCODE:
12424 {
12425 AV
12426 *av;
12427
12428 ExceptionInfo
12429 *exception;
12430
12431 HV
12432 *hv;
12433
12434 Image
12435 *image,
12436 *preview_image;
12437
12438 PreviewType
12439 preview_type;
12440
12441 struct PackageInfo
12442 *info;
12443
12444 SV
12445 *av_reference,
12446 *perl_exception,
12447 *reference,
12448 *rv,
12449 *sv;
12450
12451 PERL_UNUSED_VAR(ref);
12452 PERL_UNUSED_VAR(ix);
12453 exception=AcquireExceptionInfo();
12454 perl_exception=newSVpv("",0);
12455 sv=NULL;
12456 av=NULL;
12457 if (sv_isobject(ST(0)) == 0)
12458 {
12459 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12460 PackageName);
12461 goto PerlException;
12462 }
12463 reference=SvRV(ST(0));
12464 hv=SvSTASH(reference);
12465 av=newAV();
12466 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12467 SvREFCNT_dec(av);
12468 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12469 if (image == (Image *) NULL)
12470 {
12471 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12472 PackageName);
12473 goto PerlException;
12474 }
12475 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12476 preview_type=GammaPreview;
12477 if (items > 1)
12478 preview_type=(PreviewType)
12479 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12480 for ( ; image; image=image->next)
12481 {
12482 preview_image=PreviewImage(image,preview_type,exception);
12483 if (preview_image == (Image *) NULL)
12484 goto PerlException;
12485 AddImageToRegistry(sv,preview_image);
12486 rv=newRV(sv);
12487 av_push(av,sv_bless(rv,hv));
12488 SvREFCNT_dec(sv);
12489 }
12490 exception=DestroyExceptionInfo(exception);
12491 ST(0)=av_reference;
12492 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12493 XSRETURN(1);
12494
12495 PerlException:
12496 InheritPerlException(exception,perl_exception);
12497 exception=DestroyExceptionInfo(exception);
12498 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12499 SvPOK_on(perl_exception);
12500 ST(0)=sv_2mortal(perl_exception);
12501 XSRETURN(1);
12502 }
12503
12504 #
12505 ###############################################################################
12506 # #
12507 # #
12508 # #
12509 # Q u e r y C o l o r #
12510 # #
12511 # #
12512 # #
12513 ###############################################################################
12514 #
12515 #
12516 void
QueryColor(ref,...)12517 QueryColor(ref,...)
12518 Image::Magick ref=NO_INIT
12519 ALIAS:
12520 querycolor = 1
12521 PPCODE:
12522 {
12523 char
12524 *name;
12525
12526 ExceptionInfo
12527 *exception;
12528
12529 PixelInfo
12530 color;
12531
12532 register ssize_t
12533 i;
12534
12535 SV
12536 *perl_exception;
12537
12538 PERL_UNUSED_VAR(ref);
12539 PERL_UNUSED_VAR(ix);
12540 exception=AcquireExceptionInfo();
12541 perl_exception=newSVpv("",0);
12542 if (items == 1)
12543 {
12544 const ColorInfo
12545 **colorlist;
12546
12547 size_t
12548 colors;
12549
12550 colorlist=GetColorInfoList("*",&colors,exception);
12551 EXTEND(sp,colors);
12552 for (i=0; i < (ssize_t) colors; i++)
12553 {
12554 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12555 }
12556 colorlist=(const ColorInfo **)
12557 RelinquishMagickMemory((ColorInfo **) colorlist);
12558 goto PerlException;
12559 }
12560 EXTEND(sp,5*items);
12561 for (i=1; i < items; i++)
12562 {
12563 name=(char *) SvPV(ST(i),na);
12564 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12565 {
12566 PUSHs(&sv_undef);
12567 continue;
12568 }
12569 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12570 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12571 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12572 if (color.colorspace == CMYKColorspace)
12573 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
12574 if (color.alpha_trait != UndefinedPixelTrait)
12575 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12576 }
12577
12578 PerlException:
12579 InheritPerlException(exception,perl_exception);
12580 exception=DestroyExceptionInfo(exception);
12581 SvREFCNT_dec(perl_exception);
12582 }
12583
12584 #
12585 ###############################################################################
12586 # #
12587 # #
12588 # #
12589 # Q u e r y C o l o r N a m e #
12590 # #
12591 # #
12592 # #
12593 ###############################################################################
12594 #
12595 #
12596 void
QueryColorname(ref,...)12597 QueryColorname(ref,...)
12598 Image::Magick ref=NO_INIT
12599 ALIAS:
12600 querycolorname = 1
12601 PPCODE:
12602 {
12603 AV
12604 *av;
12605
12606 char
12607 message[MagickPathExtent];
12608
12609 ExceptionInfo
12610 *exception;
12611
12612 Image
12613 *image;
12614
12615 PixelInfo
12616 target_color;
12617
12618 register ssize_t
12619 i;
12620
12621 struct PackageInfo
12622 *info;
12623
12624 SV
12625 *perl_exception,
12626 *reference; /* reference is the SV* of ref=SvIV(reference) */
12627
12628 PERL_UNUSED_VAR(ref);
12629 PERL_UNUSED_VAR(ix);
12630 exception=AcquireExceptionInfo();
12631 perl_exception=newSVpv("",0);
12632 reference=SvRV(ST(0));
12633 av=(AV *) reference;
12634 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12635 exception);
12636 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12637 if (image == (Image *) NULL)
12638 {
12639 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12640 PackageName);
12641 goto PerlException;
12642 }
12643 EXTEND(sp,items);
12644 for (i=1; i < items; i++)
12645 {
12646 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12647 exception);
12648 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12649 exception);
12650 PUSHs(sv_2mortal(newSVpv(message,0)));
12651 }
12652
12653 PerlException:
12654 InheritPerlException(exception,perl_exception);
12655 exception=DestroyExceptionInfo(exception);
12656 SvREFCNT_dec(perl_exception);
12657 }
12658
12659 #
12660 ###############################################################################
12661 # #
12662 # #
12663 # #
12664 # Q u e r y F o n t #
12665 # #
12666 # #
12667 # #
12668 ###############################################################################
12669 #
12670 #
12671 void
QueryFont(ref,...)12672 QueryFont(ref,...)
12673 Image::Magick ref=NO_INIT
12674 ALIAS:
12675 queryfont = 1
12676 PPCODE:
12677 {
12678 char
12679 *name,
12680 message[MagickPathExtent];
12681
12682 ExceptionInfo
12683 *exception;
12684
12685 register ssize_t
12686 i;
12687
12688 SV
12689 *perl_exception;
12690
12691 volatile const TypeInfo
12692 *type_info;
12693
12694 PERL_UNUSED_VAR(ref);
12695 PERL_UNUSED_VAR(ix);
12696 exception=AcquireExceptionInfo();
12697 perl_exception=newSVpv("",0);
12698 if (items == 1)
12699 {
12700 const TypeInfo
12701 **typelist;
12702
12703 size_t
12704 types;
12705
12706 typelist=GetTypeInfoList("*",&types,exception);
12707 EXTEND(sp,types);
12708 for (i=0; i < (ssize_t) types; i++)
12709 {
12710 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12711 }
12712 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12713 typelist);
12714 goto PerlException;
12715 }
12716 EXTEND(sp,10*items);
12717 for (i=1; i < items; i++)
12718 {
12719 name=(char *) SvPV(ST(i),na);
12720 type_info=GetTypeInfo(name,exception);
12721 if (type_info == (TypeInfo *) NULL)
12722 {
12723 PUSHs(&sv_undef);
12724 continue;
12725 }
12726 if (type_info->name == (char *) NULL)
12727 PUSHs(&sv_undef);
12728 else
12729 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12730 if (type_info->description == (char *) NULL)
12731 PUSHs(&sv_undef);
12732 else
12733 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12734 if (type_info->family == (char *) NULL)
12735 PUSHs(&sv_undef);
12736 else
12737 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12738 if (type_info->style == UndefinedStyle)
12739 PUSHs(&sv_undef);
12740 else
12741 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12742 type_info->style),0)));
12743 if (type_info->stretch == UndefinedStretch)
12744 PUSHs(&sv_undef);
12745 else
12746 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12747 type_info->stretch),0)));
12748 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
12749 type_info->weight);
12750 PUSHs(sv_2mortal(newSVpv(message,0)));
12751 if (type_info->encoding == (char *) NULL)
12752 PUSHs(&sv_undef);
12753 else
12754 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12755 if (type_info->foundry == (char *) NULL)
12756 PUSHs(&sv_undef);
12757 else
12758 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12759 if (type_info->format == (char *) NULL)
12760 PUSHs(&sv_undef);
12761 else
12762 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12763 if (type_info->metrics == (char *) NULL)
12764 PUSHs(&sv_undef);
12765 else
12766 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12767 if (type_info->glyphs == (char *) NULL)
12768 PUSHs(&sv_undef);
12769 else
12770 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12771 }
12772
12773 PerlException:
12774 InheritPerlException(exception,perl_exception);
12775 exception=DestroyExceptionInfo(exception);
12776 SvREFCNT_dec(perl_exception);
12777 }
12778
12779 #
12780 ###############################################################################
12781 # #
12782 # #
12783 # #
12784 # Q u e r y F o n t M e t r i c s #
12785 # #
12786 # #
12787 # #
12788 ###############################################################################
12789 #
12790 #
12791 void
QueryFontMetrics(ref,...)12792 QueryFontMetrics(ref,...)
12793 Image::Magick ref=NO_INIT
12794 ALIAS:
12795 queryfontmetrics = 1
12796 PPCODE:
12797 {
12798 AffineMatrix
12799 affine,
12800 current;
12801
12802 AV
12803 *av;
12804
12805 char
12806 *attribute;
12807
12808 double
12809 x,
12810 y;
12811
12812 DrawInfo
12813 *draw_info;
12814
12815 ExceptionInfo
12816 *exception;
12817
12818 GeometryInfo
12819 geometry_info;
12820
12821 Image
12822 *image;
12823
12824 MagickBooleanType
12825 status;
12826
12827 MagickStatusType
12828 flags;
12829
12830 register ssize_t
12831 i;
12832
12833 ssize_t
12834 type;
12835
12836 struct PackageInfo
12837 *info,
12838 *package_info;
12839
12840 SV
12841 *perl_exception,
12842 *reference; /* reference is the SV* of ref=SvIV(reference) */
12843
12844 TypeMetric
12845 metrics;
12846
12847 PERL_UNUSED_VAR(ref);
12848 PERL_UNUSED_VAR(ix);
12849 exception=AcquireExceptionInfo();
12850 package_info=(struct PackageInfo *) NULL;
12851 perl_exception=newSVpv("",0);
12852 reference=SvRV(ST(0));
12853 av=(AV *) reference;
12854 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12855 exception);
12856 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12857 if (image == (Image *) NULL)
12858 {
12859 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12860 PackageName);
12861 goto PerlException;
12862 }
12863 package_info=ClonePackageInfo(info,exception);
12864 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12865 CloneString(&draw_info->text,"");
12866 current=draw_info->affine;
12867 GetAffineMatrix(&affine);
12868 x=0.0;
12869 y=0.0;
12870 EXTEND(sp,7*items);
12871 for (i=2; i < items; i+=2)
12872 {
12873 attribute=(char *) SvPV(ST(i-1),na);
12874 switch (*attribute)
12875 {
12876 case 'A':
12877 case 'a':
12878 {
12879 if (LocaleCompare(attribute,"antialias") == 0)
12880 {
12881 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12882 SvPV(ST(i),na));
12883 if (type < 0)
12884 {
12885 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12886 SvPV(ST(i),na));
12887 break;
12888 }
12889 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12890 break;
12891 }
12892 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12893 attribute);
12894 break;
12895 }
12896 case 'd':
12897 case 'D':
12898 {
12899 if (LocaleCompare(attribute,"density") == 0)
12900 {
12901 CloneString(&draw_info->density,SvPV(ST(i),na));
12902 break;
12903 }
12904 if (LocaleCompare(attribute,"direction") == 0)
12905 {
12906 draw_info->direction=(DirectionType) ParseCommandOption(
12907 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12908 break;
12909 }
12910 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12911 attribute);
12912 break;
12913 }
12914 case 'e':
12915 case 'E':
12916 {
12917 if (LocaleCompare(attribute,"encoding") == 0)
12918 {
12919 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12920 break;
12921 }
12922 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12923 attribute);
12924 break;
12925 }
12926 case 'f':
12927 case 'F':
12928 {
12929 if (LocaleCompare(attribute,"family") == 0)
12930 {
12931 CloneString(&draw_info->family,SvPV(ST(i),na));
12932 break;
12933 }
12934 if (LocaleCompare(attribute,"fill") == 0)
12935 {
12936 if (info)
12937 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12938 &draw_info->fill,exception);
12939 break;
12940 }
12941 if (LocaleCompare(attribute,"font") == 0)
12942 {
12943 CloneString(&draw_info->font,SvPV(ST(i),na));
12944 break;
12945 }
12946 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12947 attribute);
12948 break;
12949 }
12950 case 'g':
12951 case 'G':
12952 {
12953 if (LocaleCompare(attribute,"geometry") == 0)
12954 {
12955 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12956 break;
12957 }
12958 if (LocaleCompare(attribute,"gravity") == 0)
12959 {
12960 draw_info->gravity=(GravityType) ParseCommandOption(
12961 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12962 break;
12963 }
12964 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12965 attribute);
12966 break;
12967 }
12968 case 'i':
12969 case 'I':
12970 {
12971 if (LocaleCompare(attribute,"interline-spacing") == 0)
12972 {
12973 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12974 draw_info->interline_spacing=geometry_info.rho;
12975 break;
12976 }
12977 if (LocaleCompare(attribute,"interword-spacing") == 0)
12978 {
12979 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12980 draw_info->interword_spacing=geometry_info.rho;
12981 break;
12982 }
12983 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12984 attribute);
12985 break;
12986 }
12987 case 'k':
12988 case 'K':
12989 {
12990 if (LocaleCompare(attribute,"kerning") == 0)
12991 {
12992 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12993 draw_info->kerning=geometry_info.rho;
12994 break;
12995 }
12996 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12997 attribute);
12998 break;
12999 }
13000 case 'p':
13001 case 'P':
13002 {
13003 if (LocaleCompare(attribute,"pointsize") == 0)
13004 {
13005 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13006 draw_info->pointsize=geometry_info.rho;
13007 break;
13008 }
13009 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13010 attribute);
13011 break;
13012 }
13013 case 'r':
13014 case 'R':
13015 {
13016 if (LocaleCompare(attribute,"rotate") == 0)
13017 {
13018 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13019 affine.rx=geometry_info.rho;
13020 affine.ry=geometry_info.sigma;
13021 if ((flags & SigmaValue) == 0)
13022 affine.ry=affine.rx;
13023 break;
13024 }
13025 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13026 attribute);
13027 break;
13028 }
13029 case 's':
13030 case 'S':
13031 {
13032 if (LocaleCompare(attribute,"scale") == 0)
13033 {
13034 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13035 affine.sx=geometry_info.rho;
13036 affine.sy=geometry_info.sigma;
13037 if ((flags & SigmaValue) == 0)
13038 affine.sy=affine.sx;
13039 break;
13040 }
13041 if (LocaleCompare(attribute,"skew") == 0)
13042 {
13043 double
13044 x_angle,
13045 y_angle;
13046
13047 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13048 x_angle=geometry_info.rho;
13049 y_angle=geometry_info.sigma;
13050 if ((flags & SigmaValue) == 0)
13051 y_angle=x_angle;
13052 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13053 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13054 break;
13055 }
13056 if (LocaleCompare(attribute,"stroke") == 0)
13057 {
13058 if (info)
13059 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13060 &draw_info->stroke,exception);
13061 break;
13062 }
13063 if (LocaleCompare(attribute,"style") == 0)
13064 {
13065 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13066 SvPV(ST(i),na));
13067 if (type < 0)
13068 {
13069 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13070 SvPV(ST(i),na));
13071 break;
13072 }
13073 draw_info->style=(StyleType) type;
13074 break;
13075 }
13076 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13077 attribute);
13078 break;
13079 }
13080 case 't':
13081 case 'T':
13082 {
13083 if (LocaleCompare(attribute,"text") == 0)
13084 {
13085 CloneString(&draw_info->text,SvPV(ST(i),na));
13086 break;
13087 }
13088 if (LocaleCompare(attribute,"translate") == 0)
13089 {
13090 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13091 affine.tx=geometry_info.rho;
13092 affine.ty=geometry_info.sigma;
13093 if ((flags & SigmaValue) == 0)
13094 affine.ty=affine.tx;
13095 break;
13096 }
13097 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13098 attribute);
13099 break;
13100 }
13101 case 'w':
13102 case 'W':
13103 {
13104 if (LocaleCompare(attribute,"weight") == 0)
13105 {
13106 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13107 draw_info->weight=(size_t) geometry_info.rho;
13108 break;
13109 }
13110 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13111 attribute);
13112 break;
13113 }
13114 case 'x':
13115 case 'X':
13116 {
13117 if (LocaleCompare(attribute,"x") == 0)
13118 {
13119 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13120 x=geometry_info.rho;
13121 break;
13122 }
13123 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13124 attribute);
13125 break;
13126 }
13127 case 'y':
13128 case 'Y':
13129 {
13130 if (LocaleCompare(attribute,"y") == 0)
13131 {
13132 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13133 y=geometry_info.rho;
13134 break;
13135 }
13136 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13137 attribute);
13138 break;
13139 }
13140 default:
13141 {
13142 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13143 attribute);
13144 break;
13145 }
13146 }
13147 }
13148 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13149 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13150 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13151 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13152 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13153 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13154 if (draw_info->geometry == (char *) NULL)
13155 {
13156 draw_info->geometry=AcquireString((char *) NULL);
13157 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
13158 "%.20g,%.20g",x,y);
13159 }
13160 status=GetTypeMetrics(image,draw_info,&metrics,exception);
13161 (void) CatchImageException(image);
13162 if (status == MagickFalse)
13163 PUSHs(&sv_undef);
13164 else
13165 {
13166 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13167 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13168 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13169 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13170 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13171 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13172 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13173 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13174 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13175 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13176 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13177 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13178 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13179 }
13180 draw_info=DestroyDrawInfo(draw_info);
13181
13182 PerlException:
13183 if (package_info != (struct PackageInfo *) NULL)
13184 DestroyPackageInfo(package_info);
13185 InheritPerlException(exception,perl_exception);
13186 exception=DestroyExceptionInfo(exception);
13187 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13188 }
13189
13190 #
13191 ###############################################################################
13192 # #
13193 # #
13194 # #
13195 # 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 #
13196 # #
13197 # #
13198 # #
13199 ###############################################################################
13200 #
13201 #
13202 void
QueryMultilineFontMetrics(ref,...)13203 QueryMultilineFontMetrics(ref,...)
13204 Image::Magick ref=NO_INIT
13205 ALIAS:
13206 querymultilinefontmetrics = 1
13207 PPCODE:
13208 {
13209 AffineMatrix
13210 affine,
13211 current;
13212
13213 AV
13214 *av;
13215
13216 char
13217 *attribute;
13218
13219 double
13220 x,
13221 y;
13222
13223 DrawInfo
13224 *draw_info;
13225
13226 ExceptionInfo
13227 *exception;
13228
13229 GeometryInfo
13230 geometry_info;
13231
13232 Image
13233 *image;
13234
13235 MagickBooleanType
13236 status;
13237
13238 MagickStatusType
13239 flags;
13240
13241 register ssize_t
13242 i;
13243
13244 ssize_t
13245 type;
13246
13247 struct PackageInfo
13248 *info,
13249 *package_info;
13250
13251 SV
13252 *perl_exception,
13253 *reference; /* reference is the SV* of ref=SvIV(reference) */
13254
13255 TypeMetric
13256 metrics;
13257
13258 PERL_UNUSED_VAR(ref);
13259 PERL_UNUSED_VAR(ix);
13260 exception=AcquireExceptionInfo();
13261 package_info=(struct PackageInfo *) NULL;
13262 perl_exception=newSVpv("",0);
13263 reference=SvRV(ST(0));
13264 av=(AV *) reference;
13265 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13266 exception);
13267 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13268 if (image == (Image *) NULL)
13269 {
13270 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13271 PackageName);
13272 goto PerlException;
13273 }
13274 package_info=ClonePackageInfo(info,exception);
13275 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13276 CloneString(&draw_info->text,"");
13277 current=draw_info->affine;
13278 GetAffineMatrix(&affine);
13279 x=0.0;
13280 y=0.0;
13281 EXTEND(sp,7*items);
13282 for (i=2; i < items; i+=2)
13283 {
13284 attribute=(char *) SvPV(ST(i-1),na);
13285 switch (*attribute)
13286 {
13287 case 'A':
13288 case 'a':
13289 {
13290 if (LocaleCompare(attribute,"antialias") == 0)
13291 {
13292 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13293 SvPV(ST(i),na));
13294 if (type < 0)
13295 {
13296 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13297 SvPV(ST(i),na));
13298 break;
13299 }
13300 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13301 break;
13302 }
13303 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13304 attribute);
13305 break;
13306 }
13307 case 'd':
13308 case 'D':
13309 {
13310 if (LocaleCompare(attribute,"density") == 0)
13311 {
13312 CloneString(&draw_info->density,SvPV(ST(i),na));
13313 break;
13314 }
13315 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13316 attribute);
13317 break;
13318 }
13319 case 'e':
13320 case 'E':
13321 {
13322 if (LocaleCompare(attribute,"encoding") == 0)
13323 {
13324 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13325 break;
13326 }
13327 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13328 attribute);
13329 break;
13330 }
13331 case 'f':
13332 case 'F':
13333 {
13334 if (LocaleCompare(attribute,"family") == 0)
13335 {
13336 CloneString(&draw_info->family,SvPV(ST(i),na));
13337 break;
13338 }
13339 if (LocaleCompare(attribute,"fill") == 0)
13340 {
13341 if (info)
13342 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13343 &draw_info->fill,exception);
13344 break;
13345 }
13346 if (LocaleCompare(attribute,"font") == 0)
13347 {
13348 CloneString(&draw_info->font,SvPV(ST(i),na));
13349 break;
13350 }
13351 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13352 attribute);
13353 break;
13354 }
13355 case 'g':
13356 case 'G':
13357 {
13358 if (LocaleCompare(attribute,"geometry") == 0)
13359 {
13360 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13361 break;
13362 }
13363 if (LocaleCompare(attribute,"gravity") == 0)
13364 {
13365 draw_info->gravity=(GravityType) ParseCommandOption(
13366 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13367 break;
13368 }
13369 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13370 attribute);
13371 break;
13372 }
13373 case 'p':
13374 case 'P':
13375 {
13376 if (LocaleCompare(attribute,"pointsize") == 0)
13377 {
13378 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13379 draw_info->pointsize=geometry_info.rho;
13380 break;
13381 }
13382 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13383 attribute);
13384 break;
13385 }
13386 case 'r':
13387 case 'R':
13388 {
13389 if (LocaleCompare(attribute,"rotate") == 0)
13390 {
13391 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13392 affine.rx=geometry_info.rho;
13393 affine.ry=geometry_info.sigma;
13394 if ((flags & SigmaValue) == 0)
13395 affine.ry=affine.rx;
13396 break;
13397 }
13398 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13399 attribute);
13400 break;
13401 }
13402 case 's':
13403 case 'S':
13404 {
13405 if (LocaleCompare(attribute,"scale") == 0)
13406 {
13407 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13408 affine.sx=geometry_info.rho;
13409 affine.sy=geometry_info.sigma;
13410 if ((flags & SigmaValue) == 0)
13411 affine.sy=affine.sx;
13412 break;
13413 }
13414 if (LocaleCompare(attribute,"skew") == 0)
13415 {
13416 double
13417 x_angle,
13418 y_angle;
13419
13420 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13421 x_angle=geometry_info.rho;
13422 y_angle=geometry_info.sigma;
13423 if ((flags & SigmaValue) == 0)
13424 y_angle=x_angle;
13425 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13426 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13427 break;
13428 }
13429 if (LocaleCompare(attribute,"stroke") == 0)
13430 {
13431 if (info)
13432 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13433 &draw_info->stroke,exception);
13434 break;
13435 }
13436 if (LocaleCompare(attribute,"style") == 0)
13437 {
13438 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13439 SvPV(ST(i),na));
13440 if (type < 0)
13441 {
13442 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13443 SvPV(ST(i),na));
13444 break;
13445 }
13446 draw_info->style=(StyleType) type;
13447 break;
13448 }
13449 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13450 attribute);
13451 break;
13452 }
13453 case 't':
13454 case 'T':
13455 {
13456 if (LocaleCompare(attribute,"text") == 0)
13457 {
13458 CloneString(&draw_info->text,SvPV(ST(i),na));
13459 break;
13460 }
13461 if (LocaleCompare(attribute,"translate") == 0)
13462 {
13463 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13464 affine.tx=geometry_info.rho;
13465 affine.ty=geometry_info.sigma;
13466 if ((flags & SigmaValue) == 0)
13467 affine.ty=affine.tx;
13468 break;
13469 }
13470 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13471 attribute);
13472 break;
13473 }
13474 case 'w':
13475 case 'W':
13476 {
13477 if (LocaleCompare(attribute,"weight") == 0)
13478 {
13479 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13480 draw_info->weight=(size_t) geometry_info.rho;
13481 break;
13482 }
13483 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13484 attribute);
13485 break;
13486 }
13487 case 'x':
13488 case 'X':
13489 {
13490 if (LocaleCompare(attribute,"x") == 0)
13491 {
13492 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13493 x=geometry_info.rho;
13494 break;
13495 }
13496 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13497 attribute);
13498 break;
13499 }
13500 case 'y':
13501 case 'Y':
13502 {
13503 if (LocaleCompare(attribute,"y") == 0)
13504 {
13505 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13506 y=geometry_info.rho;
13507 break;
13508 }
13509 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13510 attribute);
13511 break;
13512 }
13513 default:
13514 {
13515 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13516 attribute);
13517 break;
13518 }
13519 }
13520 }
13521 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13522 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13523 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13524 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13525 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13526 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13527 if (draw_info->geometry == (char *) NULL)
13528 {
13529 draw_info->geometry=AcquireString((char *) NULL);
13530 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
13531 "%.20g,%.20g",x,y);
13532 }
13533 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13534 (void) CatchException(exception);
13535 if (status == MagickFalse)
13536 PUSHs(&sv_undef);
13537 else
13538 {
13539 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13540 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13541 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13542 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13543 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13544 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13545 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13546 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13547 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13548 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13549 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13550 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13551 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13552 }
13553 draw_info=DestroyDrawInfo(draw_info);
13554
13555 PerlException:
13556 if (package_info != (struct PackageInfo *) NULL)
13557 DestroyPackageInfo(package_info);
13558 InheritPerlException(exception,perl_exception);
13559 exception=DestroyExceptionInfo(exception);
13560 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13561 }
13562
13563 #
13564 ###############################################################################
13565 # #
13566 # #
13567 # #
13568 # Q u e r y F o r m a t #
13569 # #
13570 # #
13571 # #
13572 ###############################################################################
13573 #
13574 #
13575 void
QueryFormat(ref,...)13576 QueryFormat(ref,...)
13577 Image::Magick ref=NO_INIT
13578 ALIAS:
13579 queryformat = 1
13580 PPCODE:
13581 {
13582 char
13583 *name;
13584
13585 ExceptionInfo
13586 *exception;
13587
13588 register ssize_t
13589 i;
13590
13591 SV
13592 *perl_exception;
13593
13594 volatile const MagickInfo
13595 *magick_info;
13596
13597 PERL_UNUSED_VAR(ref);
13598 PERL_UNUSED_VAR(ix);
13599 exception=AcquireExceptionInfo();
13600 perl_exception=newSVpv("",0);
13601 if (items == 1)
13602 {
13603 char
13604 format[MagickPathExtent];
13605
13606 const MagickInfo
13607 **format_list;
13608
13609 size_t
13610 types;
13611
13612 format_list=GetMagickInfoList("*",&types,exception);
13613 EXTEND(sp,types);
13614 for (i=0; i < (ssize_t) types; i++)
13615 {
13616 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
13617 LocaleLower(format);
13618 PUSHs(sv_2mortal(newSVpv(format,0)));
13619 }
13620 format_list=(const MagickInfo **)
13621 RelinquishMagickMemory((MagickInfo *) format_list);
13622 goto PerlException;
13623 }
13624 EXTEND(sp,8*items);
13625 for (i=1; i < items; i++)
13626 {
13627 name=(char *) SvPV(ST(i),na);
13628 magick_info=GetMagickInfo(name,exception);
13629 if (magick_info == (const MagickInfo *) NULL)
13630 {
13631 PUSHs(&sv_undef);
13632 continue;
13633 }
13634 if (magick_info->description == (char *) NULL)
13635 PUSHs(&sv_undef);
13636 else
13637 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13638 if (magick_info->magick_module == (char *) NULL)
13639 PUSHs(&sv_undef);
13640 else
13641 PUSHs(sv_2mortal(newSVpv(magick_info->magick_module,0)));
13642 }
13643
13644 PerlException:
13645 InheritPerlException(exception,perl_exception);
13646 exception=DestroyExceptionInfo(exception);
13647 SvREFCNT_dec(perl_exception);
13648 }
13649
13650 #
13651 ###############################################################################
13652 # #
13653 # #
13654 # #
13655 # Q u e r y O p t i o n #
13656 # #
13657 # #
13658 # #
13659 ###############################################################################
13660 #
13661 #
13662 void
QueryOption(ref,...)13663 QueryOption(ref,...)
13664 Image::Magick ref=NO_INIT
13665 ALIAS:
13666 queryoption = 1
13667 PPCODE:
13668 {
13669 char
13670 **options;
13671
13672 ExceptionInfo
13673 *exception;
13674
13675 register ssize_t
13676 i;
13677
13678 ssize_t
13679 j,
13680 option;
13681
13682 SV
13683 *perl_exception;
13684
13685 PERL_UNUSED_VAR(ref);
13686 PERL_UNUSED_VAR(ix);
13687 exception=AcquireExceptionInfo();
13688 perl_exception=newSVpv("",0);
13689 EXTEND(sp,8*items);
13690 for (i=1; i < items; i++)
13691 {
13692 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13693 SvPV(ST(i),na));
13694 options=GetCommandOptions((CommandOption) option);
13695 if (options == (char **) NULL)
13696 PUSHs(&sv_undef);
13697 else
13698 {
13699 for (j=0; options[j] != (char *) NULL; j++)
13700 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13701 options=DestroyStringList(options);
13702 }
13703 }
13704
13705 InheritPerlException(exception,perl_exception);
13706 exception=DestroyExceptionInfo(exception);
13707 SvREFCNT_dec(perl_exception);
13708 }
13709
13710 #
13711 ###############################################################################
13712 # #
13713 # #
13714 # #
13715 # R e a d #
13716 # #
13717 # #
13718 # #
13719 ###############################################################################
13720 #
13721 #
13722 void
Read(ref,...)13723 Read(ref,...)
13724 Image::Magick ref=NO_INIT
13725 ALIAS:
13726 ReadImage = 1
13727 read = 2
13728 readimage = 3
13729 PPCODE:
13730 {
13731 AV
13732 *av;
13733
13734 char
13735 **keep,
13736 **list;
13737
13738 ExceptionInfo
13739 *exception;
13740
13741 HV
13742 *hv;
13743
13744 Image
13745 *image;
13746
13747 int
13748 n;
13749
13750 MagickBooleanType
13751 status;
13752
13753 register char
13754 **p;
13755
13756 register ssize_t
13757 i;
13758
13759 ssize_t
13760 ac,
13761 number_images;
13762
13763 STRLEN
13764 *length;
13765
13766 struct PackageInfo
13767 *info,
13768 *package_info;
13769
13770 SV
13771 *perl_exception, /* Perl variable for storing messages */
13772 *reference,
13773 *rv,
13774 *sv;
13775
13776 PERL_UNUSED_VAR(ref);
13777 PERL_UNUSED_VAR(ix);
13778 exception=AcquireExceptionInfo();
13779 perl_exception=newSVpv("",0);
13780 sv=NULL;
13781 package_info=(struct PackageInfo *) NULL;
13782 number_images=0;
13783 ac=(items < 2) ? 1 : items-1;
13784 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13785 keep=list;
13786 length=(STRLEN *) NULL;
13787 if (list == (char **) NULL)
13788 {
13789 ThrowPerlException(exception,ResourceLimitError,
13790 "MemoryAllocationFailed",PackageName);
13791 goto PerlException;
13792 }
13793 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13794 if (length == (STRLEN *) NULL)
13795 {
13796 ThrowPerlException(exception,ResourceLimitError,
13797 "MemoryAllocationFailed",PackageName);
13798 goto PerlException;
13799 }
13800 if (sv_isobject(ST(0)) == 0)
13801 {
13802 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13803 PackageName);
13804 goto PerlException;
13805 }
13806 reference=SvRV(ST(0));
13807 hv=SvSTASH(reference);
13808 if (SvTYPE(reference) != SVt_PVAV)
13809 {
13810 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13811 PackageName);
13812 goto PerlException;
13813 }
13814 av=(AV *) reference;
13815 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13816 exception);
13817 package_info=ClonePackageInfo(info,exception);
13818 n=1;
13819 if (items <= 1)
13820 *list=(char *) (*package_info->image_info->filename ?
13821 package_info->image_info->filename : "XC:black");
13822 else
13823 for (n=0, i=0; i < ac; i++)
13824 {
13825 list[n]=(char *) SvPV(ST(i+1),length[n]);
13826 if ((items >= 3) && strEQcase(list[n],"blob"))
13827 {
13828 void
13829 *blob;
13830
13831 i++;
13832 blob=(void *) (SvPV(ST(i+1),length[n]));
13833 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13834 }
13835 if ((items >= 3) && strEQcase(list[n],"filename"))
13836 continue;
13837 if ((items >= 3) && strEQcase(list[n],"file"))
13838 {
13839 FILE
13840 *file;
13841
13842 PerlIO
13843 *io_info;
13844
13845 i++;
13846 io_info=IoIFP(sv_2io(ST(i+1)));
13847 if (io_info == (PerlIO *) NULL)
13848 {
13849 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13850 PackageName);
13851 continue;
13852 }
13853 file=PerlIO_findFILE(io_info);
13854 if (file == (FILE *) NULL)
13855 {
13856 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13857 PackageName);
13858 continue;
13859 }
13860 SetImageInfoFile(package_info->image_info,file);
13861 }
13862 if ((items >= 3) && strEQcase(list[n],"magick"))
13863 continue;
13864 n++;
13865 }
13866 list[n]=(char *) NULL;
13867 keep=list;
13868 status=ExpandFilenames(&n,&list);
13869 if (status == MagickFalse)
13870 {
13871 ThrowPerlException(exception,ResourceLimitError,
13872 "MemoryAllocationFailed",PackageName);
13873 goto PerlException;
13874 }
13875 number_images=0;
13876 for (i=0; i < n; i++)
13877 {
13878 if ((package_info->image_info->file == (FILE *) NULL) &&
13879 (package_info->image_info->blob == (void *) NULL))
13880 image=ReadImages(package_info->image_info,list[i],exception);
13881 else
13882 {
13883 image=ReadImages(package_info->image_info,
13884 package_info->image_info->filename,exception);
13885 if (image != (Image *) NULL)
13886 DisassociateImageStream(image);
13887 }
13888 if (image == (Image *) NULL)
13889 break;
13890 for ( ; image; image=image->next)
13891 {
13892 AddImageToRegistry(sv,image);
13893 rv=newRV(sv);
13894 av_push(av,sv_bless(rv,hv));
13895 SvREFCNT_dec(sv);
13896 number_images++;
13897 }
13898 }
13899 /*
13900 Free resources.
13901 */
13902 for (i=0; i < n; i++)
13903 if (list[i] != (char *) NULL)
13904 for (p=keep; list[i] != *p++; )
13905 if (*p == (char *) NULL)
13906 {
13907 list[i]=(char *) RelinquishMagickMemory(list[i]);
13908 break;
13909 }
13910
13911 PerlException:
13912 if (package_info != (struct PackageInfo *) NULL)
13913 DestroyPackageInfo(package_info);
13914 if (list && (list != keep))
13915 list=(char **) RelinquishMagickMemory(list);
13916 if (keep)
13917 keep=(char **) RelinquishMagickMemory(keep);
13918 if (length)
13919 length=(STRLEN *) RelinquishMagickMemory(length);
13920 InheritPerlException(exception,perl_exception);
13921 exception=DestroyExceptionInfo(exception);
13922 sv_setiv(perl_exception,(IV) number_images);
13923 SvPOK_on(perl_exception);
13924 ST(0)=sv_2mortal(perl_exception);
13925 XSRETURN(1);
13926 }
13927
13928 #
13929 ###############################################################################
13930 # #
13931 # #
13932 # #
13933 # R e m o t e #
13934 # #
13935 # #
13936 # #
13937 ###############################################################################
13938 #
13939 #
13940 void
Remote(ref,...)13941 Remote(ref,...)
13942 Image::Magick ref=NO_INIT
13943 ALIAS:
13944 RemoteCommand = 1
13945 remote = 2
13946 remoteCommand = 3
13947 PPCODE:
13948 {
13949 AV
13950 *av;
13951
13952 ExceptionInfo
13953 *exception;
13954
13955 register ssize_t
13956 i;
13957
13958 SV
13959 *perl_exception,
13960 *reference;
13961
13962 struct PackageInfo
13963 *info;
13964
13965 PERL_UNUSED_VAR(ref);
13966 PERL_UNUSED_VAR(ix);
13967 exception=AcquireExceptionInfo();
13968 perl_exception=newSVpv("",0);
13969 reference=SvRV(ST(0));
13970 av=(AV *) reference;
13971 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13972 exception);
13973 for (i=1; i < items; i++)
13974 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13975 SvPV(ST(i),na),exception);
13976 InheritPerlException(exception,perl_exception);
13977 exception=DestroyExceptionInfo(exception);
13978 SvREFCNT_dec(perl_exception); /* throw away all errors */
13979 }
13980
13981 #
13982 ###############################################################################
13983 # #
13984 # #
13985 # #
13986 # S e t #
13987 # #
13988 # #
13989 # #
13990 ###############################################################################
13991 #
13992 #
13993 void
Set(ref,...)13994 Set(ref,...)
13995 Image::Magick ref=NO_INIT
13996 ALIAS:
13997 SetAttributes = 1
13998 SetAttribute = 2
13999 set = 3
14000 setattributes = 4
14001 setattribute = 5
14002 PPCODE:
14003 {
14004 ExceptionInfo
14005 *exception;
14006
14007 Image
14008 *image;
14009
14010 register ssize_t
14011 i;
14012
14013 struct PackageInfo
14014 *info;
14015
14016 SV
14017 *perl_exception,
14018 *reference; /* reference is the SV* of ref=SvIV(reference) */
14019
14020 PERL_UNUSED_VAR(ref);
14021 PERL_UNUSED_VAR(ix);
14022 exception=AcquireExceptionInfo();
14023 perl_exception=newSVpv("",0);
14024 if (sv_isobject(ST(0)) == 0)
14025 {
14026 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14027 PackageName);
14028 goto PerlException;
14029 }
14030 reference=SvRV(ST(0));
14031 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14032 if (items == 2)
14033 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
14034 else
14035 for (i=2; i < items; i+=2)
14036 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
14037
14038 PerlException:
14039 InheritPerlException(exception,perl_exception);
14040 exception=DestroyExceptionInfo(exception);
14041 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
14042 SvPOK_on(perl_exception);
14043 ST(0)=sv_2mortal(perl_exception);
14044 XSRETURN(1);
14045 }
14046
14047 #
14048 ###############################################################################
14049 # #
14050 # #
14051 # #
14052 # S e t P i x e l #
14053 # #
14054 # #
14055 # #
14056 ###############################################################################
14057 #
14058 #
14059 void
SetPixel(ref,...)14060 SetPixel(ref,...)
14061 Image::Magick ref=NO_INIT
14062 ALIAS:
14063 setpixel = 1
14064 setPixel = 2
14065 PPCODE:
14066 {
14067 AV
14068 *av;
14069
14070 char
14071 *attribute;
14072
14073 ChannelType
14074 channel,
14075 channel_mask;
14076
14077 ExceptionInfo
14078 *exception;
14079
14080 Image
14081 *image;
14082
14083 MagickBooleanType
14084 normalize;
14085
14086 RectangleInfo
14087 region;
14088
14089 register ssize_t
14090 i;
14091
14092 register Quantum
14093 *q;
14094
14095 ssize_t
14096 option;
14097
14098 struct PackageInfo
14099 *info;
14100
14101 SV
14102 *perl_exception,
14103 *reference; /* reference is the SV* of ref=SvIV(reference) */
14104
14105 PERL_UNUSED_VAR(ref);
14106 PERL_UNUSED_VAR(ix);
14107 exception=AcquireExceptionInfo();
14108 perl_exception=newSVpv("",0);
14109 reference=SvRV(ST(0));
14110 av=(AV *) reference;
14111 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14112 exception);
14113 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14114 if (image == (Image *) NULL)
14115 {
14116 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14117 PackageName);
14118 goto PerlException;
14119 }
14120 av=(AV *) NULL;
14121 normalize=MagickTrue;
14122 region.x=0;
14123 region.y=0;
14124 region.width=image->columns;
14125 region.height=1;
14126 if (items == 1)
14127 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion);
14128 channel=DefaultChannels;
14129 for (i=2; i < items; i+=2)
14130 {
14131 attribute=(char *) SvPV(ST(i-1),na);
14132 switch (*attribute)
14133 {
14134 case 'C':
14135 case 'c':
14136 {
14137 if (LocaleCompare(attribute,"channel") == 0)
14138 {
14139 ssize_t
14140 option;
14141
14142 option=ParseChannelOption(SvPV(ST(i),na));
14143 if (option < 0)
14144 {
14145 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14146 SvPV(ST(i),na));
14147 return;
14148 }
14149 channel=(ChannelType) option;
14150 break;
14151 }
14152 if (LocaleCompare(attribute,"color") == 0)
14153 {
14154 if (SvTYPE(ST(i)) != SVt_RV)
14155 {
14156 char
14157 message[MagickPathExtent];
14158
14159 (void) FormatLocaleString(message,MagickPathExtent,
14160 "invalid %.60s value",attribute);
14161 ThrowPerlException(exception,OptionError,message,
14162 SvPV(ST(i),na));
14163 }
14164 av=(AV *) SvRV(ST(i));
14165 break;
14166 }
14167 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14168 attribute);
14169 break;
14170 }
14171 case 'g':
14172 case 'G':
14173 {
14174 if (LocaleCompare(attribute,"geometry") == 0)
14175 {
14176 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion);
14177 break;
14178 }
14179 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14180 attribute);
14181 break;
14182 }
14183 case 'N':
14184 case 'n':
14185 {
14186 if (LocaleCompare(attribute,"normalize") == 0)
14187 {
14188 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14189 SvPV(ST(i),na));
14190 if (option < 0)
14191 {
14192 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14193 SvPV(ST(i),na));
14194 break;
14195 }
14196 normalize=option != 0 ? MagickTrue : MagickFalse;
14197 break;
14198 }
14199 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14200 attribute);
14201 break;
14202 }
14203 case 'x':
14204 case 'X':
14205 {
14206 if (LocaleCompare(attribute,"x") == 0)
14207 {
14208 region.x=SvIV(ST(i));
14209 break;
14210 }
14211 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14212 attribute);
14213 break;
14214 }
14215 case 'y':
14216 case 'Y':
14217 {
14218 if (LocaleCompare(attribute,"y") == 0)
14219 {
14220 region.y=SvIV(ST(i));
14221 break;
14222 }
14223 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14224 attribute);
14225 break;
14226 }
14227 default:
14228 {
14229 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14230 attribute);
14231 break;
14232 }
14233 }
14234 }
14235 (void) SetImageStorageClass(image,DirectClass,exception);
14236 channel_mask=SetImageChannelMask(image,channel);
14237 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14238 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14239 (SvTYPE(av) != SVt_PVAV))
14240 PUSHs(&sv_undef);
14241 else
14242 {
14243 double
14244 scale;
14245
14246 register ssize_t
14247 i;
14248
14249 i=0;
14250 scale=1.0;
14251 if (normalize != MagickFalse)
14252 scale=QuantumRange;
14253 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14254 (i <= av_len(av)))
14255 {
14256 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14257 av_fetch(av,i,0)))),q);
14258 i++;
14259 }
14260 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14261 (i <= av_len(av)))
14262 {
14263 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14264 av_fetch(av,i,0)))),q);
14265 i++;
14266 }
14267 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14268 (i <= av_len(av)))
14269 {
14270 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14271 av_fetch(av,i,0)))),q);
14272 i++;
14273 }
14274 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14275 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14276 {
14277 SetPixelBlack(image,ClampToQuantum(scale*
14278 SvNV(*(av_fetch(av,i,0)))),q);
14279 i++;
14280 }
14281 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14282 (i <= av_len(av)))
14283 {
14284 SetPixelAlpha(image,ClampToQuantum(scale*
14285 SvNV(*(av_fetch(av,i,0)))),q);
14286 i++;
14287 }
14288 (void) SyncAuthenticPixels(image,exception);
14289 }
14290 (void) SetImageChannelMask(image,channel_mask);
14291
14292 PerlException:
14293 InheritPerlException(exception,perl_exception);
14294 exception=DestroyExceptionInfo(exception);
14295 SvREFCNT_dec(perl_exception);
14296 }
14297
14298 #
14299 ###############################################################################
14300 # #
14301 # #
14302 # #
14303 # S e t P i x e l s #
14304 # #
14305 # #
14306 # #
14307 ###############################################################################
14308 #
14309 #
14310 void
SetPixels(ref,...)14311 SetPixels(ref,...)
14312 Image::Magick ref=NO_INIT
14313 ALIAS:
14314 setpixels = 1
14315 setPixels = 2
14316 PPCODE:
14317 {
14318 AV
14319 *av;
14320
14321 char
14322 *attribute;
14323
14324 ChannelType
14325 channel,
14326 channel_mask;
14327
14328 ExceptionInfo
14329 *exception;
14330
14331 Image
14332 *image;
14333
14334 RectangleInfo
14335 region;
14336
14337 register ssize_t
14338 i;
14339
14340 register Quantum
14341 *q;
14342
14343 struct PackageInfo
14344 *info;
14345
14346 SV
14347 *perl_exception,
14348 *reference; /* reference is the SV* of ref=SvIV(reference) */
14349
14350 PERL_UNUSED_VAR(ref);
14351 PERL_UNUSED_VAR(ix);
14352 exception=AcquireExceptionInfo();
14353 perl_exception=newSVpv("",0);
14354 reference=SvRV(ST(0));
14355 av=(AV *) reference;
14356 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14357 exception);
14358 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14359 if (image == (Image *) NULL)
14360 {
14361 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14362 PackageName);
14363 goto PerlException;
14364 }
14365 av=(AV *) NULL;
14366 region.x=0;
14367 region.y=0;
14368 region.width=image->columns;
14369 region.height=1;
14370 if (items == 1)
14371 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion);
14372 channel=DefaultChannels;
14373 for (i=2; i < items; i+=2)
14374 {
14375 attribute=(char *) SvPV(ST(i-1),na);
14376 switch (*attribute)
14377 {
14378 case 'C':
14379 case 'c':
14380 {
14381 if (LocaleCompare(attribute,"channel") == 0)
14382 {
14383 ssize_t
14384 option;
14385
14386 option=ParseChannelOption(SvPV(ST(i),na));
14387 if (option < 0)
14388 {
14389 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14390 SvPV(ST(i),na));
14391 return;
14392 }
14393 channel=(ChannelType) option;
14394 break;
14395 }
14396 if (LocaleCompare(attribute,"color") == 0)
14397 {
14398 if (SvTYPE(ST(i)) != SVt_RV)
14399 {
14400 char
14401 message[MagickPathExtent];
14402
14403 (void) FormatLocaleString(message,MagickPathExtent,
14404 "invalid %.60s value",attribute);
14405 ThrowPerlException(exception,OptionError,message,
14406 SvPV(ST(i),na));
14407 }
14408 av=(AV *) SvRV(ST(i));
14409 break;
14410 }
14411 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14412 attribute);
14413 break;
14414 }
14415 case 'g':
14416 case 'G':
14417 {
14418 if (LocaleCompare(attribute,"geometry") == 0)
14419 {
14420 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion);
14421 break;
14422 }
14423 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14424 attribute);
14425 break;
14426 }
14427 case 'h':
14428 case 'H':
14429 {
14430 if (LocaleCompare(attribute,"height") == 0)
14431 {
14432 region.height=SvIV(ST(i));
14433 break;
14434 }
14435 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14436 attribute);
14437 break;
14438 }
14439 case 'w':
14440 case 'W':
14441 {
14442 if (LocaleCompare(attribute,"width") == 0)
14443 {
14444 region.width=SvIV(ST(i));
14445 break;
14446 }
14447 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14448 attribute);
14449 break;
14450 }
14451 case 'x':
14452 case 'X':
14453 {
14454 if (LocaleCompare(attribute,"x") == 0)
14455 {
14456 region.x=SvIV(ST(i));
14457 break;
14458 }
14459 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14460 attribute);
14461 break;
14462 }
14463 case 'y':
14464 case 'Y':
14465 {
14466 if (LocaleCompare(attribute,"y") == 0)
14467 {
14468 region.y=SvIV(ST(i));
14469 break;
14470 }
14471 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14472 attribute);
14473 break;
14474 }
14475 default:
14476 {
14477 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14478 attribute);
14479 break;
14480 }
14481 }
14482 }
14483 (void) SetImageStorageClass(image,DirectClass,exception);
14484 channel_mask=SetImageChannelMask(image,channel);
14485 q=GetAuthenticPixels(image,region.x,region.y,region.width,region.height,
14486 exception);
14487 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14488 (SvTYPE(av) != SVt_PVAV))
14489 PUSHs(&sv_undef);
14490 else
14491 {
14492 double
14493 scale;
14494
14495 register ssize_t
14496 i,
14497 n,
14498 number_pixels;
14499
14500 i=0;
14501 n=0;
14502 scale=(double) QuantumRange;
14503 number_pixels=region.width*region.height;
14504 while ((n < number_pixels) && (i < av_len(av)))
14505 {
14506 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14507 (i <= av_len(av)))
14508 {
14509 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14510 av_fetch(av,i,0)))),q);
14511 i++;
14512 }
14513 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14514 (i <= av_len(av)))
14515 {
14516 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14517 av_fetch(av,i,0)))),q);
14518 i++;
14519 }
14520 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14521 (i <= av_len(av)))
14522 {
14523 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14524 av_fetch(av,i,0)))),q);
14525 i++;
14526 }
14527 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14528 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14529 {
14530 SetPixelBlack(image,ClampToQuantum(scale*
14531 SvNV(*(av_fetch(av,i,0)))),q);
14532 i++;
14533 }
14534 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14535 (i <= av_len(av)))
14536 {
14537 SetPixelAlpha(image,ClampToQuantum(scale*
14538 SvNV(*(av_fetch(av,i,0)))),q);
14539 i++;
14540 }
14541 n++;
14542 q+=image->number_channels;
14543 }
14544 (void) SyncAuthenticPixels(image,exception);
14545 }
14546 (void) SetImageChannelMask(image,channel_mask);
14547
14548 PerlException:
14549 InheritPerlException(exception,perl_exception);
14550 exception=DestroyExceptionInfo(exception);
14551 SvREFCNT_dec(perl_exception);
14552 }
14553
14554 #
14555 ###############################################################################
14556 # #
14557 # #
14558 # #
14559 # S m u s h #
14560 # #
14561 # #
14562 # #
14563 ###############################################################################
14564 #
14565 #
14566 void
Smush(ref,...)14567 Smush(ref,...)
14568 Image::Magick ref=NO_INIT
14569 ALIAS:
14570 SmushImage = 1
14571 smush = 2
14572 smushimage = 3
14573 PPCODE:
14574 {
14575 AV
14576 *av;
14577
14578 char
14579 *attribute;
14580
14581 ExceptionInfo
14582 *exception;
14583
14584 HV
14585 *hv;
14586
14587 Image
14588 *image;
14589
14590 register ssize_t
14591 i;
14592
14593 ssize_t
14594 offset,
14595 stack;
14596
14597 struct PackageInfo
14598 *info;
14599
14600 SV
14601 *av_reference,
14602 *perl_exception,
14603 *reference,
14604 *rv,
14605 *sv;
14606
14607 PERL_UNUSED_VAR(ref);
14608 PERL_UNUSED_VAR(ix);
14609 exception=AcquireExceptionInfo();
14610 perl_exception=newSVpv("",0);
14611 sv=NULL;
14612 attribute=NULL;
14613 av=NULL;
14614 if (sv_isobject(ST(0)) == 0)
14615 {
14616 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14617 PackageName);
14618 goto PerlException;
14619 }
14620 reference=SvRV(ST(0));
14621 hv=SvSTASH(reference);
14622 av=newAV();
14623 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14624 SvREFCNT_dec(av);
14625 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14626 if (image == (Image *) NULL)
14627 {
14628 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14629 PackageName);
14630 goto PerlException;
14631 }
14632 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14633 /*
14634 Get options.
14635 */
14636 offset=0;
14637 stack=MagickTrue;
14638 for (i=2; i < items; i+=2)
14639 {
14640 attribute=(char *) SvPV(ST(i-1),na);
14641 switch (*attribute)
14642 {
14643 case 'O':
14644 case 'o':
14645 {
14646 if (LocaleCompare(attribute,"offset") == 0)
14647 {
14648 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14649 break;
14650 }
14651 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14652 attribute);
14653 break;
14654 }
14655 case 'S':
14656 case 's':
14657 {
14658 if (LocaleCompare(attribute,"stack") == 0)
14659 {
14660 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14661 SvPV(ST(i),na));
14662 if (stack < 0)
14663 {
14664 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14665 SvPV(ST(i),na));
14666 return;
14667 }
14668 break;
14669 }
14670 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14671 attribute);
14672 break;
14673 }
14674 default:
14675 {
14676 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14677 attribute);
14678 break;
14679 }
14680 }
14681 }
14682 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14683 exception);
14684 if (image == (Image *) NULL)
14685 goto PerlException;
14686 for ( ; image; image=image->next)
14687 {
14688 AddImageToRegistry(sv,image);
14689 rv=newRV(sv);
14690 av_push(av,sv_bless(rv,hv));
14691 SvREFCNT_dec(sv);
14692 }
14693 exception=DestroyExceptionInfo(exception);
14694 ST(0)=av_reference;
14695 SvREFCNT_dec(perl_exception);
14696 XSRETURN(1);
14697
14698 PerlException:
14699 InheritPerlException(exception,perl_exception);
14700 exception=DestroyExceptionInfo(exception);
14701 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14702 SvPOK_on(perl_exception);
14703 ST(0)=sv_2mortal(perl_exception);
14704 XSRETURN(1);
14705 }
14706
14707 #
14708 ###############################################################################
14709 # #
14710 # #
14711 # #
14712 # S t a t i s t i c s #
14713 # #
14714 # #
14715 # #
14716 ###############################################################################
14717 #
14718 #
14719 void
Statistics(ref,...)14720 Statistics(ref,...)
14721 Image::Magick ref=NO_INIT
14722 ALIAS:
14723 StatisticsImage = 1
14724 statistics = 2
14725 statisticsimage = 3
14726 PPCODE:
14727 {
14728 #define ChannelStatistics(channel) \
14729 { \
14730 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14731 (double) channel_statistics[channel].depth); \
14732 PUSHs(sv_2mortal(newSVpv(message,0))); \
14733 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14734 channel_statistics[channel].minima/QuantumRange); \
14735 PUSHs(sv_2mortal(newSVpv(message,0))); \
14736 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14737 channel_statistics[channel].maxima/QuantumRange); \
14738 PUSHs(sv_2mortal(newSVpv(message,0))); \
14739 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14740 channel_statistics[channel].mean/QuantumRange); \
14741 PUSHs(sv_2mortal(newSVpv(message,0))); \
14742 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14743 channel_statistics[channel].standard_deviation/QuantumRange); \
14744 PUSHs(sv_2mortal(newSVpv(message,0))); \
14745 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14746 channel_statistics[channel].kurtosis); \
14747 PUSHs(sv_2mortal(newSVpv(message,0))); \
14748 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14749 channel_statistics[channel].skewness); \
14750 PUSHs(sv_2mortal(newSVpv(message,0))); \
14751 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14752 channel_statistics[channel].entropy); \
14753 PUSHs(sv_2mortal(newSVpv(message,0))); \
14754 }
14755
14756 AV
14757 *av;
14758
14759 char
14760 message[MagickPathExtent];
14761
14762 ChannelStatistics
14763 *channel_statistics;
14764
14765 ExceptionInfo
14766 *exception;
14767
14768 Image
14769 *image;
14770
14771 ssize_t
14772 count;
14773
14774 struct PackageInfo
14775 *info;
14776
14777 SV
14778 *perl_exception,
14779 *reference;
14780
14781 PERL_UNUSED_VAR(ref);
14782 PERL_UNUSED_VAR(ix);
14783 exception=AcquireExceptionInfo();
14784 perl_exception=newSVpv("",0);
14785 av=NULL;
14786 if (sv_isobject(ST(0)) == 0)
14787 {
14788 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14789 PackageName);
14790 goto PerlException;
14791 }
14792 reference=SvRV(ST(0));
14793 av=newAV();
14794 SvREFCNT_dec(av);
14795 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14796 if (image == (Image *) NULL)
14797 {
14798 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14799 PackageName);
14800 goto PerlException;
14801 }
14802 count=0;
14803 for ( ; image; image=image->next)
14804 {
14805 register size_t
14806 i;
14807
14808 channel_statistics=GetImageStatistics(image,exception);
14809 if (channel_statistics == (ChannelStatistics *) NULL)
14810 continue;
14811 count++;
14812 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
14813 {
14814 PixelChannel channel=GetPixelChannelChannel(image,i);
14815 PixelTrait traits=GetPixelChannelTraits(image,channel);
14816 if (traits == UndefinedPixelTrait)
14817 continue;
14818 EXTEND(sp,8*(i+1)*count);
14819 ChannelStatistics(channel);
14820 }
14821 EXTEND(sp,8*(i+1)*count);
14822 ChannelStatistics(CompositePixelChannel);
14823 channel_statistics=(ChannelStatistics *)
14824 RelinquishMagickMemory(channel_statistics);
14825 }
14826
14827 PerlException:
14828 InheritPerlException(exception,perl_exception);
14829 exception=DestroyExceptionInfo(exception);
14830 SvREFCNT_dec(perl_exception);
14831 }
14832
14833 #
14834 ###############################################################################
14835 # #
14836 # #
14837 # #
14838 # S y n c A u t h e n t i c P i x e l s #
14839 # #
14840 # #
14841 # #
14842 ###############################################################################
14843 #
14844 #
14845 void
SyncAuthenticPixels(ref,...)14846 SyncAuthenticPixels(ref,...)
14847 Image::Magick ref = NO_INIT
14848 ALIAS:
14849 Syncauthenticpixels = 1
14850 SyncImagePixels = 2
14851 syncimagepixels = 3
14852 CODE:
14853 {
14854 ExceptionInfo
14855 *exception;
14856
14857 Image
14858 *image;
14859
14860 MagickBooleanType
14861 status;
14862
14863 struct PackageInfo
14864 *info;
14865
14866 SV
14867 *perl_exception,
14868 *reference;
14869
14870 PERL_UNUSED_VAR(ref);
14871 PERL_UNUSED_VAR(ix);
14872 exception=AcquireExceptionInfo();
14873 perl_exception=newSVpv("",0);
14874 if (sv_isobject(ST(0)) == 0)
14875 {
14876 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14877 PackageName);
14878 goto PerlException;
14879 }
14880
14881 reference=SvRV(ST(0));
14882 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14883 if (image == (Image *) NULL)
14884 {
14885 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14886 PackageName);
14887 goto PerlException;
14888 }
14889
14890 status=SyncAuthenticPixels(image,exception);
14891 if (status != MagickFalse)
14892 return;
14893
14894 PerlException:
14895 InheritPerlException(exception,perl_exception);
14896 exception=DestroyExceptionInfo(exception);
14897 SvREFCNT_dec(perl_exception); /* throw away all errors */
14898 }
14899
14900 #
14901 ###############################################################################
14902 # #
14903 # #
14904 # #
14905 # W r i t e #
14906 # #
14907 # #
14908 # #
14909 ###############################################################################
14910 #
14911 #
14912 void
Write(ref,...)14913 Write(ref,...)
14914 Image::Magick ref=NO_INIT
14915 ALIAS:
14916 WriteImage = 1
14917 write = 2
14918 writeimage = 3
14919 PPCODE:
14920 {
14921 char
14922 filename[MagickPathExtent];
14923
14924 ExceptionInfo
14925 *exception;
14926
14927 Image
14928 *image,
14929 *next;
14930
14931 register ssize_t
14932 i;
14933
14934 ssize_t
14935 number_images,
14936 scene;
14937
14938 struct PackageInfo
14939 *info,
14940 *package_info;
14941
14942 SV
14943 *perl_exception,
14944 *reference;
14945
14946 PERL_UNUSED_VAR(ref);
14947 PERL_UNUSED_VAR(ix);
14948 exception=AcquireExceptionInfo();
14949 perl_exception=newSVpv("",0);
14950 number_images=0;
14951 package_info=(struct PackageInfo *) NULL;
14952 if (sv_isobject(ST(0)) == 0)
14953 {
14954 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14955 PackageName);
14956 goto PerlException;
14957 }
14958 reference=SvRV(ST(0));
14959 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14960 if (image == (Image *) NULL)
14961 {
14962 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14963 PackageName);
14964 goto PerlException;
14965 }
14966 scene=0;
14967 for (next=image; next; next=next->next)
14968 next->scene=scene++;
14969 package_info=ClonePackageInfo(info,exception);
14970 if (items == 2)
14971 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14972 else
14973 if (items > 2)
14974 for (i=2; i < items; i+=2)
14975 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14976 exception);
14977 (void) CopyMagickString(filename,package_info->image_info->filename,
14978 MagickPathExtent);
14979 for (next=image; next; next=next->next)
14980 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
14981 *package_info->image_info->magick='\0';
14982 SetImageInfo(package_info->image_info,(unsigned int)
14983 GetImageListLength(image),exception);
14984 for (next=image; next; next=next->next)
14985 {
14986 (void) WriteImage(package_info->image_info,next,exception);
14987 number_images++;
14988 if (package_info->image_info->adjoin)
14989 break;
14990 }
14991
14992 PerlException:
14993 if (package_info != (struct PackageInfo *) NULL)
14994 DestroyPackageInfo(package_info);
14995 InheritPerlException(exception,perl_exception);
14996 exception=DestroyExceptionInfo(exception);
14997 sv_setiv(perl_exception,(IV) number_images);
14998 SvPOK_on(perl_exception);
14999 ST(0)=sv_2mortal(perl_exception);
15000 XSRETURN(1);
15001 }
15002