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-2016 ImageMagick Studio LLC, a non-profit organization %
27 % dedicated to making software imaging solutions freely available. %
28 % %
29 % You may not use this file except in compliance with the License. You may %
30 % obtain a copy of the License at %
31 % %
32 % http://www.imagemagick.org/script/license.php %
33 % %
34 % Unless required by applicable law or agreed to in writing, software %
35 % distributed under the License is distributed on an "AS IS" BASIS, %
36 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37 % See the License for the specific language governing permissions and %
38 % limitations under the License. %
39 % %
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 %
42 % PerlMagick is an objected-oriented Perl interface to ImageMagick. Use
43 % the module to read, manipulate, or write an image or image sequence from
44 % within a Perl script. This makes PerlMagick suitable for Web CGI scripts.
45 %
46 */
47
48 /*
49 Include declarations.
50 */
51 #if defined(__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 33
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 ArrayReference = (~0),
146 RealReference = (~0)-1,
147 FileReference = (~0)-2,
148 ImageReference = (~0)-3,
149 IntegerReference = (~0)-4,
150 StringReference = (~0)-5
151 } MagickReference;
152
153 typedef struct _Arguments
154 {
155 const char
156 *method;
157
158 ssize_t
159 type;
160 } Arguments;
161
162 struct ArgumentList
163 {
164 ssize_t
165 integer_reference;
166
167 double
168 real_reference;
169
170 const char
171 *string_reference;
172
173 Image
174 *image_reference;
175
176 SV
177 *array_reference;
178
179 FILE
180 *file_reference;
181
182 size_t
183 length;
184 };
185
186 struct PackageInfo
187 {
188 ImageInfo
189 *image_info;
190 };
191
192 typedef void
193 *Image__Magick; /* data type for the Image::Magick package */
194
195 /*
196 Static declarations.
197 */
198 static struct
199 Methods
200 {
201 const char
202 *name;
203
204 Arguments
205 arguments[MaxArguments];
206 } Methods[] =
207 {
208 { "Comment", { {"comment", StringReference} } },
209 { "Label", { {"label", StringReference} } },
210 { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
211 {"channel", MagickChannelOptions} } },
212 { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
213 { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
214 {"height", IntegerReference}, {"fill", StringReference},
215 {"bordercolor", StringReference}, {"color", StringReference},
216 {"compose", MagickComposeOptions} } },
217 { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
218 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
219 { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
220 {"height", IntegerReference}, {"x", IntegerReference},
221 {"y", IntegerReference}, {"gravity", MagickGravityOptions} } },
222 { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
223 {"height", IntegerReference}, {"x", IntegerReference},
224 {"y", IntegerReference}, {"fuzz", StringReference},
225 {"gravity", MagickGravityOptions} } },
226 { "Despeckle", },
227 { "Edge", { {"radius", RealReference} } },
228 { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
229 {"sigma", RealReference} } },
230 { "Enhance", },
231 { "Flip", },
232 { "Flop", },
233 { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
234 {"height", IntegerReference}, {"inner", IntegerReference},
235 {"outer", IntegerReference}, {"fill", StringReference},
236 {"color", StringReference}, {"compose", MagickComposeOptions} } },
237 { "Implode", { {"amount", RealReference},
238 {"interpolate", MagickInterpolateOptions} } },
239 { "Magnify", },
240 { "MedianFilter", { {"geometry", StringReference},
241 {"width", IntegerReference}, {"height", IntegerReference},
242 {"channel", MagickChannelOptions} } },
243 { "Minify", },
244 { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
245 { "ReduceNoise", { {"geometry", StringReference},
246 {"width", IntegerReference},{"height", IntegerReference},
247 {"channel", MagickChannelOptions} } },
248 { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
249 {"y", IntegerReference} } },
250 { "Rotate", { {"degrees", RealReference},
251 {"background", StringReference} } },
252 { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
253 {"height", IntegerReference} } },
254 { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
255 {"height", IntegerReference} } },
256 { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
257 {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
258 { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
259 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
260 { "Shear", { {"geometry", StringReference}, {"x", RealReference},
261 {"y", RealReference}, { "fill", StringReference},
262 {"color", StringReference} } },
263 { "Spread", { {"radius", RealReference},
264 {"interpolate", MagickInterpolateOptions} } },
265 { "Swirl", { {"degrees", RealReference},
266 {"interpolate", MagickInterpolateOptions} } },
267 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
268 {"height", IntegerReference}, {"filter", MagickFilterOptions},
269 {"support", StringReference } } },
270 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
271 {"height", IntegerReference}, {"filter", MagickFilterOptions},
272 {"support", RealReference } } },
273 { "Annotate", { {"text", StringReference}, {"font", StringReference},
274 {"pointsize", RealReference}, {"density", StringReference},
275 {"undercolor", StringReference}, {"stroke", StringReference},
276 {"fill", StringReference}, {"geometry", StringReference},
277 {"sans", StringReference}, {"x", RealReference},
278 {"y", RealReference}, {"gravity", MagickGravityOptions},
279 {"translate", StringReference}, {"scale", StringReference},
280 {"rotate", RealReference}, {"skewX", RealReference},
281 {"skewY", RealReference}, {"strokewidth", RealReference},
282 {"antialias", MagickBooleanOptions}, {"family", StringReference},
283 {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
284 {"weight", IntegerReference}, {"align", MagickAlignOptions},
285 {"encoding", StringReference}, {"affine", ArrayReference},
286 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
287 {"tile", ImageReference}, {"kerning", RealReference},
288 {"interline-spacing", RealReference},
289 {"interword-spacing", RealReference},
290 {"direction", MagickDirectionOptions} } },
291 { "ColorFloodfill", { {"geometry", StringReference},
292 {"x", IntegerReference}, {"y", IntegerReference},
293 {"fill", StringReference}, {"bordercolor", StringReference},
294 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
295 { "Composite", { {"image", ImageReference},
296 {"compose", MagickComposeOptions}, {"geometry", StringReference},
297 {"x", IntegerReference}, {"y", IntegerReference},
298 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
299 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
300 {"color", StringReference}, {"mask", ImageReference},
301 {"channel", MagickChannelOptions},
302 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
303 {"blend", StringReference}, {"crop-to-self", MagickBooleanOptions} } },
304 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
305 { "CycleColormap", { {"display", IntegerReference} } },
306 { "Draw", { {"primitive", MagickPrimitiveOptions},
307 {"points", StringReference}, {"method", MagickMethodOptions},
308 {"stroke", StringReference}, {"fill", StringReference},
309 {"strokewidth", RealReference}, {"font", StringReference},
310 {"bordercolor", StringReference}, {"x", RealReference},
311 {"y", RealReference}, {"translate", StringReference},
312 {"scale", StringReference}, {"rotate", RealReference},
313 {"skewX", RealReference}, {"skewY", RealReference},
314 {"tile", ImageReference}, {"pointsize", RealReference},
315 {"antialias", MagickBooleanOptions}, {"density", StringReference},
316 {"linewidth", RealReference}, {"affine", ArrayReference},
317 {"stroke-dashoffset", RealReference},
318 {"stroke-dasharray", ArrayReference},
319 {"interpolate", MagickInterpolateOptions},
320 {"origin", StringReference}, {"text", StringReference},
321 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
322 {"vector-graphics", StringReference}, {"kerning", RealReference},
323 {"interline-spacing", RealReference},
324 {"interword-spacing", RealReference},
325 {"direction", MagickDirectionOptions} } },
326 { "Equalize", { {"channel", MagickChannelOptions} } },
327 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
328 {"red", RealReference}, {"green", RealReference},
329 {"blue", RealReference} } },
330 { "Map", { {"image", ImageReference},
331 {"dither-method", MagickDitherOptions} } },
332 { "MatteFloodfill", { {"geometry", StringReference},
333 {"x", IntegerReference}, {"y", IntegerReference},
334 {"opacity", StringReference}, {"bordercolor", StringReference},
335 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
336 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
337 {"saturation", RealReference}, {"whiteness", RealReference},
338 {"brightness", RealReference}, {"lightness", RealReference},
339 {"blackness", RealReference} } },
340 { "Negate", { {"gray", MagickBooleanOptions},
341 {"channel", MagickChannelOptions} } },
342 { "Normalize", { {"channel", MagickChannelOptions} } },
343 { "NumberColors", },
344 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
345 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
346 {"invert", MagickBooleanOptions} } },
347 { "Quantize", { {"colors", IntegerReference},
348 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
349 {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
350 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
351 {"dither-method", MagickDitherOptions} } },
352 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
353 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
354 { "Segment", { {"geometry", StringReference},
355 {"cluster-threshold", RealReference},
356 {"smoothing-threshold", RealReference},
357 {"colorspace", MagickColorspaceOptions},
358 {"verbose", MagickBooleanOptions} } },
359 { "Signature", },
360 { "Solarize", { {"geometry", StringReference},
361 {"threshold", StringReference} } },
362 { "Sync", },
363 { "Texture", { {"texture", ImageReference} } },
364 { "Evaluate", { {"value", RealReference},
365 {"operator", MagickEvaluateOptions},
366 {"channel", MagickChannelOptions} } },
367 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
368 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
369 { "Threshold", { {"threshold", StringReference},
370 {"channel", MagickChannelOptions} } },
371 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
372 {"sigma", RealReference} } },
373 { "Trim", { {"fuzz", StringReference} } },
374 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
375 {"wavelength", RealReference},
376 {"interpolate", MagickInterpolateOptions} } },
377 { "Separate", { {"channel", MagickChannelOptions} } },
378 { "Condense", },
379 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
380 {"y", IntegerReference} } },
381 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
382 { "Deconstruct", },
383 { "GaussianBlur", { {"geometry", StringReference},
384 {"radius", RealReference}, {"sigma", RealReference},
385 {"channel", MagickChannelOptions} } },
386 { "Convolve", { {"coefficients", ArrayReference},
387 {"channel", MagickChannelOptions}, {"bias", StringReference},
388 {"kernel", StringReference} } },
389 { "Profile", { {"name", StringReference}, {"profile", StringReference},
390 { "rendering-intent", MagickIntentOptions},
391 { "black-point-compensation", MagickBooleanOptions} } },
392 { "UnsharpMask", { {"geometry", StringReference},
393 {"radius", RealReference}, {"sigma", RealReference},
394 {"gain", RealReference}, {"threshold", RealReference},
395 {"channel", MagickChannelOptions} } },
396 { "MotionBlur", { {"geometry", StringReference},
397 {"radius", RealReference}, {"sigma", RealReference},
398 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
399 { "OrderedDither", { {"threshold", StringReference},
400 {"channel", MagickChannelOptions} } },
401 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
402 {"height", IntegerReference} } },
403 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
404 {"white-point", RealReference}, {"gamma", RealReference},
405 {"channel", MagickChannelOptions}, {"level", StringReference} } },
406 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
407 { "AffineTransform", { {"affine", ArrayReference},
408 {"translate", StringReference}, {"scale", StringReference},
409 {"rotate", RealReference}, {"skewX", RealReference},
410 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
411 {"background", StringReference} } },
412 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
413 { "AdaptiveThreshold", { {"geometry", StringReference},
414 {"width", IntegerReference}, {"height", IntegerReference} } },
415 { "Resample", { {"density", StringReference}, {"x", RealReference},
416 {"y", RealReference}, {"filter", MagickFilterOptions},
417 {"support", RealReference } } },
418 { "Describe", { {"file", FileReference} } },
419 { "BlackThreshold", { {"threshold", StringReference},
420 {"channel", MagickChannelOptions} } },
421 { "WhiteThreshold", { {"threshold", StringReference},
422 {"channel", MagickChannelOptions} } },
423 { "RotationalBlur", { {"geometry", StringReference},
424 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
425 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
426 {"height", IntegerReference} } },
427 { "Strip", },
428 { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
429 { "Channel", { {"channel", MagickChannelOptions} } },
430 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
431 {"height", IntegerReference}, {"x", IntegerReference},
432 {"y", IntegerReference}, {"fuzz", StringReference},
433 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
434 { "Posterize", { {"levels", IntegerReference},
435 {"dither", MagickBooleanOptions} } },
436 { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
437 {"sigma", RealReference}, {"x", IntegerReference},
438 {"y", IntegerReference} } },
439 { "Identify", { {"file", FileReference}, {"features", StringReference},
440 {"unique", MagickBooleanOptions} } },
441 { "SepiaTone", { {"threshold", RealReference} } },
442 { "SigmoidalContrast", { {"geometry", StringReference},
443 {"contrast", RealReference}, {"mid-point", RealReference},
444 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
445 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
446 {"height", IntegerReference}, {"x", IntegerReference},
447 {"y", IntegerReference}, {"fuzz", StringReference},
448 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
449 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
450 {"sigma", RealReference}, {"x", IntegerReference},
451 {"y", IntegerReference}, {"background", StringReference} } },
452 { "ContrastStretch", { {"levels", StringReference},
453 {"black-point", RealReference},{"white-point", RealReference},
454 {"channel", MagickChannelOptions} } },
455 { "Sans0", },
456 { "Sans1", },
457 { "AdaptiveSharpen", { {"geometry", StringReference},
458 {"radius", RealReference}, {"sigma", RealReference},
459 {"bias", RealReference}, {"channel", MagickChannelOptions} } },
460 { "Transpose", },
461 { "Transverse", },
462 { "AutoOrient", },
463 { "AdaptiveBlur", { {"geometry", StringReference},
464 {"radius", RealReference}, {"sigma", RealReference},
465 {"channel", MagickChannelOptions} } },
466 { "Sketch", { {"geometry", StringReference},
467 {"radius", RealReference}, {"sigma", RealReference},
468 {"angle", RealReference} } },
469 { "UniqueColors", },
470 { "AdaptiveResize", { {"geometry", StringReference},
471 {"width", IntegerReference}, {"height", IntegerReference},
472 {"filter", MagickFilterOptions}, {"support", StringReference },
473 {"blur", RealReference } } },
474 { "ClipMask", { {"mask", ImageReference} } },
475 { "LinearStretch", { {"levels", StringReference},
476 {"black-point", RealReference},{"white-point", RealReference} } },
477 { "ColorMatrix", { {"matrix", ArrayReference} } },
478 { "Mask", { {"mask", ImageReference} } },
479 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
480 {"font", StringReference}, {"stroke", StringReference},
481 {"fill", StringReference}, {"strokewidth", RealReference},
482 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
483 {"background", StringReference},
484 {"interpolate", MagickInterpolateOptions} } },
485 { "FloodfillPaint", { {"geometry", StringReference},
486 {"x", IntegerReference}, {"y", IntegerReference},
487 {"fill", StringReference}, {"bordercolor", StringReference},
488 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
489 {"invert", MagickBooleanOptions} } },
490 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
491 {"virtual-pixel", MagickVirtualPixelOptions},
492 {"best-fit", MagickBooleanOptions} } },
493 { "Clut", { {"image", ImageReference},
494 {"interpolate", MagickInterpolateOptions},
495 {"channel", MagickChannelOptions} } },
496 { "LiquidRescale", { {"geometry", StringReference},
497 {"width", IntegerReference}, {"height", IntegerReference},
498 {"delta-x", RealReference}, {"rigidity", RealReference } } },
499 { "Encipher", { {"passphrase", StringReference} } },
500 { "Decipher", { {"passphrase", StringReference} } },
501 { "Deskew", { {"geometry", StringReference},
502 {"threshold", StringReference} } },
503 { "Remap", { {"image", ImageReference},
504 {"dither-method", MagickDitherOptions} } },
505 { "SparseColor", { {"points", ArrayReference},
506 {"method", MagickSparseColorOptions},
507 {"virtual-pixel", MagickVirtualPixelOptions},
508 {"channel", MagickChannelOptions} } },
509 { "Function", { {"parameters", ArrayReference},
510 {"function", MagickFunctionOptions},
511 {"virtual-pixel", MagickVirtualPixelOptions} } },
512 { "SelectiveBlur", { {"geometry", StringReference},
513 {"radius", RealReference}, {"sigma", RealReference},
514 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
515 { "HaldClut", { {"image", ImageReference},
516 {"channel", MagickChannelOptions} } },
517 { "BlueShift", { {"factor", StringReference} } },
518 { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
519 { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
520 { "ColorDecisionList", {
521 {"color-correction-collection", StringReference} } },
522 { "AutoGamma", { {"channel", MagickChannelOptions} } },
523 { "AutoLevel", { {"channel", MagickChannelOptions} } },
524 { "LevelColors", { {"invert", MagickBooleanOptions},
525 {"black-point", StringReference}, {"white-point", StringReference},
526 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
527 { "Clamp", { {"channel", MagickChannelOptions} } },
528 { "BrightnessContrast", { {"levels", StringReference},
529 {"brightness", RealReference},{"contrast", RealReference},
530 {"channel", MagickChannelOptions} } },
531 { "Morphology", { {"kernel", StringReference},
532 {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
533 {"iterations", IntegerReference} } },
534 { "Mode", { {"geometry", StringReference},
535 {"width", IntegerReference},{"height", IntegerReference},
536 {"channel", MagickChannelOptions} } },
537 { "Statistic", { {"geometry", StringReference},
538 {"width", IntegerReference},{"height", IntegerReference},
539 {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
540 { "Perceptible", { {"epsilon", RealReference},
541 {"channel", MagickChannelOptions} } },
542 { "Poly", { {"terms", ArrayReference},
543 {"channel", MagickChannelOptions} } },
544 { "Grayscale", { {"method", MagickNoiseOptions} } },
545 { "CannyEdge", { {"geometry", StringReference},
546 {"radius", RealReference}, {"sigma", RealReference},
547 {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
548 { "HoughLine", { {"geometry", StringReference},
549 {"width", IntegerReference}, {"height", IntegerReference},
550 {"threshold", IntegerReference} } },
551 { "MeanShift", { {"geometry", StringReference},
552 {"width", IntegerReference}, {"height", IntegerReference},
553 {"distance", RealReference} } },
554 { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
555 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
556 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
557 { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
558 {"width", IntegerReference}, {"height", IntegerReference},
559 {"x", IntegerReference}, {"y", IntegerReference},
560 {"gravity", MagickGravityOptions}, {"offset", StringReference},
561 {"dx", IntegerReference}, {"dy", IntegerReference} } },
562 { "Color", { {"color", StringReference} } },
563 { "WaveletDenoise", { {"geometry", StringReference},
564 {"threshold", RealReference}, {"softness", RealReference},
565 {"channel", MagickChannelOptions} } },
566 };
567
568 static SplayTreeInfo
569 *magick_registry = (SplayTreeInfo *) NULL;
570
571 /*
572 Forward declarations.
573 */
574 static Image
575 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
576
577 static ssize_t
578 strEQcase(const char *,const char *);
579
580 /*
581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582 % %
583 % %
584 % %
585 % C l o n e P a c k a g e I n f o %
586 % %
587 % %
588 % %
589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
590 %
591 % ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
592 % a new one.
593 %
594 % The format of the ClonePackageInfo routine is:
595 %
596 % struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
597 % exception)
598 %
599 % A description of each parameter follows:
600 %
601 % o info: a structure of type info.
602 %
603 % o exception: Return any errors or warnings in this structure.
604 %
605 */
ClonePackageInfo(struct PackageInfo * info,ExceptionInfo * exception)606 static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
607 ExceptionInfo *exception)
608 {
609 struct PackageInfo
610 *clone_info;
611
612 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
613 if (clone_info == (struct PackageInfo *) NULL)
614 {
615 ThrowPerlException(exception,ResourceLimitError,
616 "UnableToClonePackageInfo",PackageName);
617 return((struct PackageInfo *) NULL);
618 }
619 if (info == (struct PackageInfo *) NULL)
620 {
621 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
622 return(clone_info);
623 }
624 *clone_info=(*info);
625 clone_info->image_info=CloneImageInfo(info->image_info);
626 return(clone_info);
627 }
628
629 /*
630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
631 % %
632 % %
633 % %
634 % c o n s t a n t %
635 % %
636 % %
637 % %
638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
639 %
640 % constant() returns a double value for the specified name.
641 %
642 % The format of the constant routine is:
643 %
644 % double constant(char *name,ssize_t sans)
645 %
646 % A description of each parameter follows:
647 %
648 % o value: Method constant returns a double value for the specified name.
649 %
650 % o name: The name of the constant.
651 %
652 % o sans: This integer value is not used.
653 %
654 */
constant(char * name,ssize_t sans)655 static double constant(char *name,ssize_t sans)
656 {
657 (void) sans;
658 errno=0;
659 switch (*name)
660 {
661 case 'B':
662 {
663 if (strEQ(name,"BlobError"))
664 return(BlobError);
665 if (strEQ(name,"BlobWarning"))
666 return(BlobWarning);
667 break;
668 }
669 case 'C':
670 {
671 if (strEQ(name,"CacheError"))
672 return(CacheError);
673 if (strEQ(name,"CacheWarning"))
674 return(CacheWarning);
675 if (strEQ(name,"CoderError"))
676 return(CoderError);
677 if (strEQ(name,"CoderWarning"))
678 return(CoderWarning);
679 if (strEQ(name,"ConfigureError"))
680 return(ConfigureError);
681 if (strEQ(name,"ConfigureWarning"))
682 return(ConfigureWarning);
683 if (strEQ(name,"CorruptImageError"))
684 return(CorruptImageError);
685 if (strEQ(name,"CorruptImageWarning"))
686 return(CorruptImageWarning);
687 break;
688 }
689 case 'D':
690 {
691 if (strEQ(name,"DelegateError"))
692 return(DelegateError);
693 if (strEQ(name,"DelegateWarning"))
694 return(DelegateWarning);
695 if (strEQ(name,"DrawError"))
696 return(DrawError);
697 if (strEQ(name,"DrawWarning"))
698 return(DrawWarning);
699 break;
700 }
701 case 'E':
702 {
703 if (strEQ(name,"ErrorException"))
704 return(ErrorException);
705 if (strEQ(name,"ExceptionError"))
706 return(CoderError);
707 if (strEQ(name,"ExceptionWarning"))
708 return(CoderWarning);
709 break;
710 }
711 case 'F':
712 {
713 if (strEQ(name,"FatalErrorException"))
714 return(FatalErrorException);
715 if (strEQ(name,"FileOpenError"))
716 return(FileOpenError);
717 if (strEQ(name,"FileOpenWarning"))
718 return(FileOpenWarning);
719 break;
720 }
721 case 'I':
722 {
723 if (strEQ(name,"ImageError"))
724 return(ImageError);
725 if (strEQ(name,"ImageWarning"))
726 return(ImageWarning);
727 break;
728 }
729 case 'M':
730 {
731 if (strEQ(name,"MaxRGB"))
732 return(QuantumRange);
733 if (strEQ(name,"MissingDelegateError"))
734 return(MissingDelegateError);
735 if (strEQ(name,"MissingDelegateWarning"))
736 return(MissingDelegateWarning);
737 if (strEQ(name,"ModuleError"))
738 return(ModuleError);
739 if (strEQ(name,"ModuleWarning"))
740 return(ModuleWarning);
741 break;
742 }
743 case 'O':
744 {
745 if (strEQ(name,"Opaque"))
746 return(OpaqueAlpha);
747 if (strEQ(name,"OptionError"))
748 return(OptionError);
749 if (strEQ(name,"OptionWarning"))
750 return(OptionWarning);
751 break;
752 }
753 case 'Q':
754 {
755 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
756 return(MAGICKCORE_QUANTUM_DEPTH);
757 if (strEQ(name,"QuantumDepth"))
758 return(MAGICKCORE_QUANTUM_DEPTH);
759 if (strEQ(name,"QuantumRange"))
760 return(QuantumRange);
761 break;
762 }
763 case 'R':
764 {
765 if (strEQ(name,"ResourceLimitError"))
766 return(ResourceLimitError);
767 if (strEQ(name,"ResourceLimitWarning"))
768 return(ResourceLimitWarning);
769 if (strEQ(name,"RegistryError"))
770 return(RegistryError);
771 if (strEQ(name,"RegistryWarning"))
772 return(RegistryWarning);
773 break;
774 }
775 case 'S':
776 {
777 if (strEQ(name,"StreamError"))
778 return(StreamError);
779 if (strEQ(name,"StreamWarning"))
780 return(StreamWarning);
781 if (strEQ(name,"Success"))
782 return(0);
783 break;
784 }
785 case 'T':
786 {
787 if (strEQ(name,"Transparent"))
788 return(TransparentAlpha);
789 if (strEQ(name,"TypeError"))
790 return(TypeError);
791 if (strEQ(name,"TypeWarning"))
792 return(TypeWarning);
793 break;
794 }
795 case 'W':
796 {
797 if (strEQ(name,"WarningException"))
798 return(WarningException);
799 break;
800 }
801 case 'X':
802 {
803 if (strEQ(name,"XServerError"))
804 return(XServerError);
805 if (strEQ(name,"XServerWarning"))
806 return(XServerWarning);
807 break;
808 }
809 }
810 errno=EINVAL;
811 return(0);
812 }
813
814 /*
815 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816 % %
817 % %
818 % %
819 % D e s t r o y P a c k a g e I n f o %
820 % %
821 % %
822 % %
823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824 %
825 % Method DestroyPackageInfo frees a previously created info structure.
826 %
827 % The format of the DestroyPackageInfo routine is:
828 %
829 % DestroyPackageInfo(struct PackageInfo *info)
830 %
831 % A description of each parameter follows:
832 %
833 % o info: a structure of type info.
834 %
835 */
DestroyPackageInfo(struct PackageInfo * info)836 static void DestroyPackageInfo(struct PackageInfo *info)
837 {
838 info->image_info=DestroyImageInfo(info->image_info);
839 info=(struct PackageInfo *) RelinquishMagickMemory(info);
840 }
841
842 /*
843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
844 % %
845 % %
846 % %
847 % G e t L i s t %
848 % %
849 % %
850 % %
851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
852 %
853 % Method GetList is recursively called by SetupList to traverse the
854 % Image__Magick reference. If building an reference_vector (see SetupList),
855 % *current is the current position in *reference_vector and *last is the final
856 % entry in *reference_vector.
857 %
858 % The format of the GetList routine is:
859 %
860 % GetList(info)
861 %
862 % A description of each parameter follows:
863 %
864 % o info: a structure of type info.
865 %
866 */
GetList(pTHX_ SV * reference,SV *** reference_vector,ssize_t * current,ssize_t * last,ExceptionInfo * exception)867 static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
868 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
869 {
870 Image
871 *image;
872
873 if (reference == (SV *) NULL)
874 return(NULL);
875 switch (SvTYPE(reference))
876 {
877 case SVt_PVAV:
878 {
879 AV
880 *av;
881
882 Image
883 *head,
884 *previous;
885
886 register ssize_t
887 i;
888
889 ssize_t
890 n;
891
892 /*
893 Array of images.
894 */
895 previous=(Image *) NULL;
896 head=(Image *) NULL;
897 av=(AV *) reference;
898 n=av_len(av);
899 for (i=0; i <= n; i++)
900 {
901 SV
902 **rv;
903
904 rv=av_fetch(av,i,0);
905 if (rv && *rv && sv_isobject(*rv))
906 {
907 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
908 exception);
909 if (image == (Image *) NULL)
910 continue;
911 if (image == previous)
912 {
913 image=CloneImage(image,0,0,MagickTrue,exception);
914 if (image == (Image *) NULL)
915 return(NULL);
916 }
917 image->previous=previous;
918 *(previous ? &previous->next : &head)=image;
919 for (previous=image; previous->next; previous=previous->next) ;
920 }
921 }
922 return(head);
923 }
924 case SVt_PVMG:
925 {
926 /*
927 Blessed scalar, one image.
928 */
929 image=INT2PTR(Image *,SvIV(reference));
930 if (image == (Image *) NULL)
931 return(NULL);
932 image->previous=(Image *) NULL;
933 image->next=(Image *) NULL;
934 if (reference_vector)
935 {
936 if (*current == *last)
937 {
938 *last+=256;
939 if (*reference_vector == (SV **) NULL)
940 *reference_vector=(SV **) AcquireQuantumMemory(*last,
941 sizeof(*reference_vector));
942 else
943 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
944 *last,sizeof(*reference_vector));
945 }
946 if (*reference_vector == (SV **) NULL)
947 {
948 ThrowPerlException(exception,ResourceLimitError,
949 "MemoryAllocationFailed",PackageName);
950 return((Image *) NULL);
951 }
952 (*reference_vector)[*current]=reference;
953 (*reference_vector)[++(*current)]=NULL;
954 }
955 return(image);
956 }
957 default:
958 break;
959 }
960 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
961 (double) SvTYPE(reference));
962 return((Image *) NULL);
963 }
964
965 /*
966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
967 % %
968 % %
969 % %
970 % G e t P a c k a g e I n f o %
971 % %
972 % %
973 % %
974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
975 %
976 % Method GetPackageInfo looks up or creates an info structure for the given
977 % Image__Magick reference. If it does create a new one, the information in
978 % package_info is used to initialize it.
979 %
980 % The format of the GetPackageInfo routine is:
981 %
982 % struct PackageInfo *GetPackageInfo(void *reference,
983 % struct PackageInfo *package_info,ExceptionInfo *exception)
984 %
985 % A description of each parameter follows:
986 %
987 % o info: a structure of type info.
988 %
989 % o exception: Return any errors or warnings in this structure.
990 %
991 */
GetPackageInfo(pTHX_ void * reference,struct PackageInfo * package_info,ExceptionInfo * exception)992 static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
993 struct PackageInfo *package_info,ExceptionInfo *exception)
994 {
995 char
996 message[MagickPathExtent];
997
998 struct PackageInfo
999 *clone_info;
1000
1001 SV
1002 *sv;
1003
1004 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
1005 PackageName,XS_VERSION,reference);
1006 sv=perl_get_sv(message,(TRUE | 0x02));
1007 if (sv == (SV *) NULL)
1008 {
1009 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1010 message);
1011 return(package_info);
1012 }
1013 if (SvREFCNT(sv) == 0)
1014 (void) SvREFCNT_inc(sv);
1015 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1016 return(clone_info);
1017 clone_info=ClonePackageInfo(package_info,exception);
1018 sv_setiv(sv,PTR2IV(clone_info));
1019 return(clone_info);
1020 }
1021
1022 /*
1023 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1024 % %
1025 % %
1026 % %
1027 % S e t A t t r i b u t e %
1028 % %
1029 % %
1030 % %
1031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1032 %
1033 % SetAttribute() sets the attribute to the value in sval. This can change
1034 % either or both of image or info.
1035 %
1036 % The format of the SetAttribute routine is:
1037 %
1038 % SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1039 % SV *sval,ExceptionInfo *exception)
1040 %
1041 % A description of each parameter follows:
1042 %
1043 % o list: a list of strings.
1044 %
1045 % o string: a character string.
1046 %
1047 */
1048
SiPrefixToDoubleInterval(const char * string,const double interval)1049 static double SiPrefixToDoubleInterval(const char *string,const double interval)
1050 {
1051 char
1052 *q;
1053
1054 double
1055 value;
1056
1057 value=InterpretSiPrefixValue(string,&q);
1058 if (*q == '%')
1059 value*=interval/100.0;
1060 return(value);
1061 }
1062
StringToDouble(const char * string,char ** sentinal)1063 static inline double StringToDouble(const char *string,char **sentinal)
1064 {
1065 return(InterpretLocaleValue(string,sentinal));
1066 }
1067
StringToDoubleInterval(const char * string,const double interval)1068 static double StringToDoubleInterval(const char *string,const double interval)
1069 {
1070 char
1071 *q;
1072
1073 double
1074 value;
1075
1076 value=InterpretLocaleValue(string,&q);
1077 if (*q == '%')
1078 value*=interval/100.0;
1079 return(value);
1080 }
1081
StringToLong(const char * value)1082 static inline ssize_t StringToLong(const char *value)
1083 {
1084 return(strtol(value,(char **) NULL,10));
1085 }
1086
SetAttribute(pTHX_ struct PackageInfo * info,Image * image,const char * attribute,SV * sval,ExceptionInfo * exception)1087 static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1088 const char *attribute,SV *sval,ExceptionInfo *exception)
1089 {
1090 GeometryInfo
1091 geometry_info;
1092
1093 long
1094 x,
1095 y;
1096
1097 PixelInfo
1098 pixel;
1099
1100 MagickStatusType
1101 flags;
1102
1103 PixelInfo
1104 *color,
1105 target_color;
1106
1107 ssize_t
1108 sp;
1109
1110 switch (*attribute)
1111 {
1112 case 'A':
1113 case 'a':
1114 {
1115 if (LocaleCompare(attribute,"adjoin") == 0)
1116 {
1117 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1118 SvPV(sval,na)) : SvIV(sval);
1119 if (sp < 0)
1120 {
1121 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1122 SvPV(sval,na));
1123 break;
1124 }
1125 if (info)
1126 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1127 break;
1128 }
1129 if (LocaleCompare(attribute,"alpha") == 0)
1130 {
1131 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1132 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1133 if (sp < 0)
1134 {
1135 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1136 SvPV(sval,na));
1137 break;
1138 }
1139 for ( ; image; image=image->next)
1140 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1141 exception);
1142 break;
1143 }
1144 if (LocaleCompare(attribute,"antialias") == 0)
1145 {
1146 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1147 SvPV(sval,na)) : SvIV(sval);
1148 if (sp < 0)
1149 {
1150 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1151 SvPV(sval,na));
1152 break;
1153 }
1154 if (info)
1155 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1156 break;
1157 }
1158 if (LocaleCompare(attribute,"area-limit") == 0)
1159 {
1160 MagickSizeType
1161 limit;
1162
1163 limit=MagickResourceInfinity;
1164 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1165 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1166 100.0);
1167 (void) SetMagickResourceLimit(AreaResource,limit);
1168 break;
1169 }
1170 if (LocaleCompare(attribute,"attenuate") == 0)
1171 {
1172 if (info)
1173 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1174 break;
1175 }
1176 if (LocaleCompare(attribute,"authenticate") == 0)
1177 {
1178 if (info)
1179 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1180 break;
1181 }
1182 if (info)
1183 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1184 for ( ; image; image=image->next)
1185 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1186 break;
1187 }
1188 case 'B':
1189 case 'b':
1190 {
1191 if (LocaleCompare(attribute,"background") == 0)
1192 {
1193 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1194 exception);
1195 if (info)
1196 info->image_info->background_color=target_color;
1197 for ( ; image; image=image->next)
1198 image->background_color=target_color;
1199 break;
1200 }
1201 if (LocaleCompare(attribute,"blue-primary") == 0)
1202 {
1203 for ( ; image; image=image->next)
1204 {
1205 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1206 image->chromaticity.blue_primary.x=geometry_info.rho;
1207 image->chromaticity.blue_primary.y=geometry_info.sigma;
1208 if ((flags & SigmaValue) == 0)
1209 image->chromaticity.blue_primary.y=
1210 image->chromaticity.blue_primary.x;
1211 }
1212 break;
1213 }
1214 if (LocaleCompare(attribute,"bordercolor") == 0)
1215 {
1216 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1217 exception);
1218 if (info)
1219 info->image_info->border_color=target_color;
1220 for ( ; image; image=image->next)
1221 image->border_color=target_color;
1222 break;
1223 }
1224 if (info)
1225 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1226 for ( ; image; image=image->next)
1227 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1228 break;
1229 }
1230 case 'C':
1231 case 'c':
1232 {
1233 if (LocaleCompare(attribute,"cache-threshold") == 0)
1234 {
1235 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1236 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1237 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1238 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1239 break;
1240 }
1241 if (LocaleCompare(attribute,"clip-mask") == 0)
1242 {
1243 Image
1244 *clip_mask;
1245
1246 clip_mask=(Image *) NULL;
1247 if (SvPOK(sval))
1248 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1249 for ( ; image; image=image->next)
1250 SetImageMask(image,ReadPixelMask,clip_mask,exception);
1251 break;
1252 }
1253 if (LocaleNCompare(attribute,"colormap",8) == 0)
1254 {
1255 for ( ; image; image=image->next)
1256 {
1257 int
1258 items;
1259
1260 long
1261 i;
1262
1263 if (image->storage_class == DirectClass)
1264 continue;
1265 i=0;
1266 items=sscanf(attribute,"%*[^[][%ld",&i);
1267 (void) items;
1268 if (i > (ssize_t) image->colors)
1269 i%=image->colors;
1270 if ((strchr(SvPV(sval,na),',') == 0) ||
1271 (strchr(SvPV(sval,na),')') != 0))
1272 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1273 image->colormap+i,exception);
1274 else
1275 {
1276 color=image->colormap+i;
1277 pixel.red=color->red;
1278 pixel.green=color->green;
1279 pixel.blue=color->blue;
1280 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1281 pixel.red=geometry_info.rho;
1282 pixel.green=geometry_info.sigma;
1283 pixel.blue=geometry_info.xi;
1284 color->red=ClampToQuantum(pixel.red);
1285 color->green=ClampToQuantum(pixel.green);
1286 color->blue=ClampToQuantum(pixel.blue);
1287 }
1288 }
1289 break;
1290 }
1291 if (LocaleCompare(attribute,"colorspace") == 0)
1292 {
1293 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1294 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1295 if (sp < 0)
1296 {
1297 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1298 SvPV(sval,na));
1299 break;
1300 }
1301 for ( ; image; image=image->next)
1302 (void) TransformImageColorspace(image,(ColorspaceType) sp,
1303 exception);
1304 break;
1305 }
1306 if (LocaleCompare(attribute,"comment") == 0)
1307 {
1308 for ( ; image; image=image->next)
1309 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1310 info ? info->image_info : (ImageInfo *) NULL,image,
1311 SvPV(sval,na),exception),exception);
1312 break;
1313 }
1314 if (LocaleCompare(attribute,"compression") == 0)
1315 {
1316 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1317 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1318 if (sp < 0)
1319 {
1320 ThrowPerlException(exception,OptionError,
1321 "UnrecognizedImageCompression",SvPV(sval,na));
1322 break;
1323 }
1324 if (info)
1325 info->image_info->compression=(CompressionType) sp;
1326 for ( ; image; image=image->next)
1327 image->compression=(CompressionType) sp;
1328 break;
1329 }
1330 if (info)
1331 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1332 for ( ; image; image=image->next)
1333 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1334 break;
1335 }
1336 case 'D':
1337 case 'd':
1338 {
1339 if (LocaleCompare(attribute,"debug") == 0)
1340 {
1341 SetLogEventMask(SvPV(sval,na));
1342 break;
1343 }
1344 if (LocaleCompare(attribute,"delay") == 0)
1345 {
1346 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1347 for ( ; image; image=image->next)
1348 {
1349 image->delay=(size_t) floor(geometry_info.rho+0.5);
1350 if ((flags & SigmaValue) != 0)
1351 image->ticks_per_second=(ssize_t)
1352 floor(geometry_info.sigma+0.5);
1353 }
1354 break;
1355 }
1356 if (LocaleCompare(attribute,"disk-limit") == 0)
1357 {
1358 MagickSizeType
1359 limit;
1360
1361 limit=MagickResourceInfinity;
1362 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1363 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1364 100.0);
1365 (void) SetMagickResourceLimit(DiskResource,limit);
1366 break;
1367 }
1368 if (LocaleCompare(attribute,"density") == 0)
1369 {
1370 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1371 {
1372 ThrowPerlException(exception,OptionError,"MissingGeometry",
1373 SvPV(sval,na));
1374 break;
1375 }
1376 if (info)
1377 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1378 for ( ; image; image=image->next)
1379 {
1380 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1381 image->resolution.x=geometry_info.rho;
1382 image->resolution.y=geometry_info.sigma;
1383 if ((flags & SigmaValue) == 0)
1384 image->resolution.y=image->resolution.x;
1385 }
1386 break;
1387 }
1388 if (LocaleCompare(attribute,"depth") == 0)
1389 {
1390 if (info)
1391 info->image_info->depth=SvIV(sval);
1392 for ( ; image; image=image->next)
1393 (void) SetImageDepth(image,SvIV(sval),exception);
1394 break;
1395 }
1396 if (LocaleCompare(attribute,"dispose") == 0)
1397 {
1398 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1399 SvPV(sval,na)) : SvIV(sval);
1400 if (sp < 0)
1401 {
1402 ThrowPerlException(exception,OptionError,
1403 "UnrecognizedDisposeMethod",SvPV(sval,na));
1404 break;
1405 }
1406 for ( ; image; image=image->next)
1407 image->dispose=(DisposeType) sp;
1408 break;
1409 }
1410 if (LocaleCompare(attribute,"dither") == 0)
1411 {
1412 if (info)
1413 {
1414 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1415 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1416 if (sp < 0)
1417 {
1418 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1419 SvPV(sval,na));
1420 break;
1421 }
1422 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1423 }
1424 break;
1425 }
1426 if (LocaleCompare(attribute,"display") == 0)
1427 {
1428 display:
1429 if (info)
1430 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1431 break;
1432 }
1433 if (info)
1434 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1435 for ( ; image; image=image->next)
1436 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1437 break;
1438 }
1439 case 'E':
1440 case 'e':
1441 {
1442 if (LocaleCompare(attribute,"endian") == 0)
1443 {
1444 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1445 SvPV(sval,na)) : SvIV(sval);
1446 if (sp < 0)
1447 {
1448 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1449 SvPV(sval,na));
1450 break;
1451 }
1452 if (info)
1453 info->image_info->endian=(EndianType) sp;
1454 for ( ; image; image=image->next)
1455 image->endian=(EndianType) sp;
1456 break;
1457 }
1458 if (LocaleCompare(attribute,"extract") == 0)
1459 {
1460 /*
1461 Set image extract geometry.
1462 */
1463 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1464 break;
1465 }
1466 if (info)
1467 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1468 for ( ; image; image=image->next)
1469 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1470 break;
1471 }
1472 case 'F':
1473 case 'f':
1474 {
1475 if (LocaleCompare(attribute,"filename") == 0)
1476 {
1477 if (info)
1478 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
1479 MagickPathExtent);
1480 for ( ; image; image=image->next)
1481 (void) CopyMagickString(image->filename,SvPV(sval,na),
1482 MagickPathExtent);
1483 break;
1484 }
1485 if (LocaleCompare(attribute,"file") == 0)
1486 {
1487 FILE
1488 *file;
1489
1490 PerlIO
1491 *io_info;
1492
1493 if (info == (struct PackageInfo *) NULL)
1494 break;
1495 io_info=IoIFP(sv_2io(sval));
1496 if (io_info == (PerlIO *) NULL)
1497 {
1498 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1499 PackageName);
1500 break;
1501 }
1502 file=PerlIO_findFILE(io_info);
1503 if (file == (FILE *) NULL)
1504 {
1505 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1506 PackageName);
1507 break;
1508 }
1509 SetImageInfoFile(info->image_info,file);
1510 break;
1511 }
1512 if (LocaleCompare(attribute,"fill") == 0)
1513 {
1514 if (info)
1515 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1516 break;
1517 }
1518 if (LocaleCompare(attribute,"font") == 0)
1519 {
1520 if (info)
1521 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1522 break;
1523 }
1524 if (LocaleCompare(attribute,"foreground") == 0)
1525 break;
1526 if (LocaleCompare(attribute,"fuzz") == 0)
1527 {
1528 if (info)
1529 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1530 QuantumRange+1.0);
1531 for ( ; image; image=image->next)
1532 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1533 QuantumRange+1.0);
1534 break;
1535 }
1536 if (info)
1537 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1538 for ( ; image; image=image->next)
1539 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1540 break;
1541 }
1542 case 'G':
1543 case 'g':
1544 {
1545 if (LocaleCompare(attribute,"gamma") == 0)
1546 {
1547 for ( ; image; image=image->next)
1548 image->gamma=SvNV(sval);
1549 break;
1550 }
1551 if (LocaleCompare(attribute,"gravity") == 0)
1552 {
1553 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1554 SvPV(sval,na)) : SvIV(sval);
1555 if (sp < 0)
1556 {
1557 ThrowPerlException(exception,OptionError,
1558 "UnrecognizedGravityType",SvPV(sval,na));
1559 break;
1560 }
1561 if (info)
1562 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1563 for ( ; image; image=image->next)
1564 image->gravity=(GravityType) sp;
1565 break;
1566 }
1567 if (LocaleCompare(attribute,"green-primary") == 0)
1568 {
1569 for ( ; image; image=image->next)
1570 {
1571 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1572 image->chromaticity.green_primary.x=geometry_info.rho;
1573 image->chromaticity.green_primary.y=geometry_info.sigma;
1574 if ((flags & SigmaValue) == 0)
1575 image->chromaticity.green_primary.y=
1576 image->chromaticity.green_primary.x;
1577 }
1578 break;
1579 }
1580 if (info)
1581 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1582 for ( ; image; image=image->next)
1583 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1584 break;
1585 }
1586 case 'I':
1587 case 'i':
1588 {
1589 if (LocaleNCompare(attribute,"index",5) == 0)
1590 {
1591 int
1592 items;
1593
1594 long
1595 index;
1596
1597 register Quantum
1598 *q;
1599
1600 CacheView
1601 *image_view;
1602
1603 for ( ; image; image=image->next)
1604 {
1605 if (image->storage_class != PseudoClass)
1606 continue;
1607 x=0;
1608 y=0;
1609 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1610 (void) items;
1611 image_view=AcquireAuthenticCacheView(image,exception);
1612 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1613 if (q != (Quantum *) NULL)
1614 {
1615 items=sscanf(SvPV(sval,na),"%ld",&index);
1616 if ((index >= 0) && (index < (ssize_t) image->colors))
1617 SetPixelIndex(image,index,q);
1618 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1619 }
1620 image_view=DestroyCacheView(image_view);
1621 }
1622 break;
1623 }
1624 if (LocaleCompare(attribute,"iterations") == 0)
1625 {
1626 iterations:
1627 for ( ; image; image=image->next)
1628 image->iterations=SvIV(sval);
1629 break;
1630 }
1631 if (LocaleCompare(attribute,"interlace") == 0)
1632 {
1633 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1634 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1635 if (sp < 0)
1636 {
1637 ThrowPerlException(exception,OptionError,
1638 "UnrecognizedInterlaceType",SvPV(sval,na));
1639 break;
1640 }
1641 if (info)
1642 info->image_info->interlace=(InterlaceType) sp;
1643 for ( ; image; image=image->next)
1644 image->interlace=(InterlaceType) sp;
1645 break;
1646 }
1647 if (info)
1648 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1649 for ( ; image; image=image->next)
1650 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1651 break;
1652 }
1653 case 'L':
1654 case 'l':
1655 {
1656 if (LocaleCompare(attribute,"label") == 0)
1657 {
1658 for ( ; image; image=image->next)
1659 (void) SetImageProperty(image,"label",InterpretImageProperties(
1660 info ? info->image_info : (ImageInfo *) NULL,image,
1661 SvPV(sval,na),exception),exception);
1662 break;
1663 }
1664 if (LocaleCompare(attribute,"loop") == 0)
1665 goto iterations;
1666 if (info)
1667 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1668 for ( ; image; image=image->next)
1669 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1670 break;
1671 }
1672 case 'M':
1673 case 'm':
1674 {
1675 if (LocaleCompare(attribute,"magick") == 0)
1676 {
1677 if (info)
1678 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
1679 "%s:",SvPV(sval,na));
1680 for ( ; image; image=image->next)
1681 (void) CopyMagickString(image->magick,SvPV(sval,na),MagickPathExtent);
1682 break;
1683 }
1684 if (LocaleCompare(attribute,"map-limit") == 0)
1685 {
1686 MagickSizeType
1687 limit;
1688
1689 limit=MagickResourceInfinity;
1690 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1691 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1692 100.0);
1693 (void) SetMagickResourceLimit(MapResource,limit);
1694 break;
1695 }
1696 if (LocaleCompare(attribute,"mask") == 0)
1697 {
1698 Image
1699 *mask;
1700
1701 mask=(Image *) NULL;
1702 if (SvPOK(sval))
1703 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1704 for ( ; image; image=image->next)
1705 SetImageMask(image,ReadPixelMask,mask,exception);
1706 break;
1707 }
1708 if (LocaleCompare(attribute,"mattecolor") == 0)
1709 {
1710 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1711 exception);
1712 if (info)
1713 info->image_info->alpha_color=target_color;
1714 for ( ; image; image=image->next)
1715 image->alpha_color=target_color;
1716 break;
1717 }
1718 if (LocaleCompare(attribute,"matte") == 0)
1719 {
1720 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1721 SvPV(sval,na)) : SvIV(sval);
1722 if (sp < 0)
1723 {
1724 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1725 SvPV(sval,na));
1726 break;
1727 }
1728 for ( ; image; image=image->next)
1729 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1730 break;
1731 }
1732 if (LocaleCompare(attribute,"memory-limit") == 0)
1733 {
1734 MagickSizeType
1735 limit;
1736
1737 limit=MagickResourceInfinity;
1738 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1739 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1740 100.0);
1741 (void) SetMagickResourceLimit(MemoryResource,limit);
1742 break;
1743 }
1744 if (LocaleCompare(attribute,"monochrome") == 0)
1745 {
1746 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1747 SvPV(sval,na)) : SvIV(sval);
1748 if (sp < 0)
1749 {
1750 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1751 SvPV(sval,na));
1752 break;
1753 }
1754 if (info)
1755 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1756 for ( ; image; image=image->next)
1757 (void) SetImageType(image,BilevelType,exception);
1758 break;
1759 }
1760 if (info)
1761 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1762 for ( ; image; image=image->next)
1763 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1764 break;
1765 }
1766 case 'O':
1767 case 'o':
1768 {
1769 if (LocaleCompare(attribute,"option") == 0)
1770 {
1771 if (info)
1772 DefineImageOption(info->image_info,SvPV(sval,na));
1773 break;
1774 }
1775 if (LocaleCompare(attribute,"orientation") == 0)
1776 {
1777 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1778 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1779 if (sp < 0)
1780 {
1781 ThrowPerlException(exception,OptionError,
1782 "UnrecognizedOrientationType",SvPV(sval,na));
1783 break;
1784 }
1785 if (info)
1786 info->image_info->orientation=(OrientationType) sp;
1787 for ( ; image; image=image->next)
1788 image->orientation=(OrientationType) sp;
1789 break;
1790 }
1791 if (info)
1792 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1793 for ( ; image; image=image->next)
1794 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1795 break;
1796 }
1797 case 'P':
1798 case 'p':
1799 {
1800 if (LocaleCompare(attribute,"page") == 0)
1801 {
1802 char
1803 *geometry;
1804
1805 geometry=GetPageGeometry(SvPV(sval,na));
1806 if (info)
1807 (void) CloneString(&info->image_info->page,geometry);
1808 for ( ; image; image=image->next)
1809 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1810 geometry=(char *) RelinquishMagickMemory(geometry);
1811 break;
1812 }
1813 if (LocaleNCompare(attribute,"pixel",5) == 0)
1814 {
1815 int
1816 items;
1817
1818 PixelInfo
1819 pixel;
1820
1821 register Quantum
1822 *q;
1823
1824 CacheView
1825 *image_view;
1826
1827 for ( ; image; image=image->next)
1828 {
1829 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1830 break;
1831 x=0;
1832 y=0;
1833 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1834 (void) items;
1835 image_view=AcquireVirtualCacheView(image,exception);
1836 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1837 if (q != (Quantum *) NULL)
1838 {
1839 if ((strchr(SvPV(sval,na),',') == 0) ||
1840 (strchr(SvPV(sval,na),')') != 0))
1841 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1842 &pixel,exception);
1843 else
1844 {
1845 GetPixelInfo(image,&pixel);
1846 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1847 pixel.red=geometry_info.rho;
1848 if ((flags & SigmaValue) != 0)
1849 pixel.green=geometry_info.sigma;
1850 if ((flags & XiValue) != 0)
1851 pixel.blue=geometry_info.xi;
1852 if ((flags & PsiValue) != 0)
1853 pixel.alpha=geometry_info.psi;
1854 if ((flags & ChiValue) != 0)
1855 pixel.black=geometry_info.chi;
1856 }
1857 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1858 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1859 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1860 if (image->colorspace == CMYKColorspace)
1861 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1862 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1863 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1864 }
1865 image_view=DestroyCacheView(image_view);
1866 }
1867 break;
1868 }
1869 if (LocaleCompare(attribute,"pointsize") == 0)
1870 {
1871 if (info)
1872 {
1873 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1874 info->image_info->pointsize=geometry_info.rho;
1875 }
1876 break;
1877 }
1878 if (info)
1879 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1880 for ( ; image; image=image->next)
1881 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1882 break;
1883 }
1884 case 'Q':
1885 case 'q':
1886 {
1887 if (LocaleCompare(attribute,"quality") == 0)
1888 {
1889 if (info)
1890 info->image_info->quality=SvIV(sval);
1891 for ( ; image; image=image->next)
1892 image->quality=SvIV(sval);
1893 break;
1894 }
1895 if (info)
1896 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1897 for ( ; image; image=image->next)
1898 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1899 break;
1900 }
1901 case 'R':
1902 case 'r':
1903 {
1904 if (LocaleCompare(attribute,"read-mask") == 0)
1905 {
1906 Image
1907 *mask;
1908
1909 mask=(Image *) NULL;
1910 if (SvPOK(sval))
1911 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1912 for ( ; image; image=image->next)
1913 SetImageMask(image,ReadPixelMask,mask,exception);
1914 break;
1915 }
1916 if (LocaleCompare(attribute,"red-primary") == 0)
1917 {
1918 for ( ; image; image=image->next)
1919 {
1920 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1921 image->chromaticity.red_primary.x=geometry_info.rho;
1922 image->chromaticity.red_primary.y=geometry_info.sigma;
1923 if ((flags & SigmaValue) == 0)
1924 image->chromaticity.red_primary.y=
1925 image->chromaticity.red_primary.x;
1926 }
1927 break;
1928 }
1929 if (LocaleCompare(attribute,"render") == 0)
1930 {
1931 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1932 SvPV(sval,na)) : SvIV(sval);
1933 if (sp < 0)
1934 {
1935 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1936 SvPV(sval,na));
1937 break;
1938 }
1939 for ( ; image; image=image->next)
1940 image->rendering_intent=(RenderingIntent) sp;
1941 break;
1942 }
1943 if (LocaleCompare(attribute,"repage") == 0)
1944 {
1945 RectangleInfo
1946 geometry;
1947
1948 for ( ; image; image=image->next)
1949 {
1950 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1951 if ((flags & WidthValue) != 0)
1952 {
1953 if ((flags & HeightValue) == 0)
1954 geometry.height=geometry.width;
1955 image->page.width=geometry.width;
1956 image->page.height=geometry.height;
1957 }
1958 if ((flags & AspectValue) != 0)
1959 {
1960 if ((flags & XValue) != 0)
1961 image->page.x+=geometry.x;
1962 if ((flags & YValue) != 0)
1963 image->page.y+=geometry.y;
1964 }
1965 else
1966 {
1967 if ((flags & XValue) != 0)
1968 {
1969 image->page.x=geometry.x;
1970 if (((flags & WidthValue) != 0) && (geometry.x > 0))
1971 image->page.width=image->columns+geometry.x;
1972 }
1973 if ((flags & YValue) != 0)
1974 {
1975 image->page.y=geometry.y;
1976 if (((flags & HeightValue) != 0) && (geometry.y > 0))
1977 image->page.height=image->rows+geometry.y;
1978 }
1979 }
1980 }
1981 break;
1982 }
1983 if (info)
1984 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1985 for ( ; image; image=image->next)
1986 SetImageProperty(image,attribute,SvPV(sval,na),exception);
1987 break;
1988 }
1989 case 'S':
1990 case 's':
1991 {
1992 if (LocaleCompare(attribute,"sampling-factor") == 0)
1993 {
1994 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1995 {
1996 ThrowPerlException(exception,OptionError,"MissingGeometry",
1997 SvPV(sval,na));
1998 break;
1999 }
2000 if (info)
2001 (void) CloneString(&info->image_info->sampling_factor,
2002 SvPV(sval,na));
2003 break;
2004 }
2005 if (LocaleCompare(attribute,"scene") == 0)
2006 {
2007 for ( ; image; image=image->next)
2008 image->scene=SvIV(sval);
2009 break;
2010 }
2011 if (LocaleCompare(attribute,"server") == 0)
2012 goto display;
2013 if (LocaleCompare(attribute,"size") == 0)
2014 {
2015 if (info)
2016 {
2017 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2018 {
2019 ThrowPerlException(exception,OptionError,"MissingGeometry",
2020 SvPV(sval,na));
2021 break;
2022 }
2023 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2024 }
2025 break;
2026 }
2027 if (LocaleCompare(attribute,"stroke") == 0)
2028 {
2029 if (info)
2030 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2031 break;
2032 }
2033 if (info)
2034 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2035 for ( ; image; image=image->next)
2036 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2037 break;
2038 }
2039 case 'T':
2040 case 't':
2041 {
2042 if (LocaleCompare(attribute,"texture") == 0)
2043 {
2044 if (info)
2045 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2046 break;
2047 }
2048 if (LocaleCompare(attribute,"thread-limit") == 0)
2049 {
2050 MagickSizeType
2051 limit;
2052
2053 limit=MagickResourceInfinity;
2054 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2055 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2056 100.0);
2057 (void) SetMagickResourceLimit(ThreadResource,limit);
2058 break;
2059 }
2060 if (LocaleCompare(attribute,"tile-offset") == 0)
2061 {
2062 char
2063 *geometry;
2064
2065 geometry=GetPageGeometry(SvPV(sval,na));
2066 if (info)
2067 (void) CloneString(&info->image_info->page,geometry);
2068 for ( ; image; image=image->next)
2069 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2070 exception);
2071 geometry=(char *) RelinquishMagickMemory(geometry);
2072 break;
2073 }
2074 if (LocaleCompare(attribute,"time-limit") == 0)
2075 {
2076 MagickSizeType
2077 limit;
2078
2079 limit=MagickResourceInfinity;
2080 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2081 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2082 100.0);
2083 (void) SetMagickResourceLimit(TimeResource,limit);
2084 break;
2085 }
2086 if (LocaleCompare(attribute,"transparent-color") == 0)
2087 {
2088 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2089 exception);
2090 if (info)
2091 info->image_info->transparent_color=target_color;
2092 for ( ; image; image=image->next)
2093 image->transparent_color=target_color;
2094 break;
2095 }
2096 if (LocaleCompare(attribute,"type") == 0)
2097 {
2098 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2099 SvPV(sval,na)) : SvIV(sval);
2100 if (sp < 0)
2101 {
2102 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2103 SvPV(sval,na));
2104 break;
2105 }
2106 if (info)
2107 info->image_info->type=(ImageType) sp;
2108 for ( ; image; image=image->next)
2109 SetImageType(image,(ImageType) sp,exception);
2110 break;
2111 }
2112 if (info)
2113 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2114 for ( ; image; image=image->next)
2115 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2116 break;
2117 }
2118 case 'U':
2119 case 'u':
2120 {
2121 if (LocaleCompare(attribute,"units") == 0)
2122 {
2123 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2124 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2125 if (sp < 0)
2126 {
2127 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2128 SvPV(sval,na));
2129 break;
2130 }
2131 if (info)
2132 info->image_info->units=(ResolutionType) sp;
2133 for ( ; image; image=image->next)
2134 {
2135 ResolutionType
2136 units;
2137
2138 units=(ResolutionType) sp;
2139 if (image->units != units)
2140 switch (image->units)
2141 {
2142 case UndefinedResolution:
2143 case PixelsPerInchResolution:
2144 {
2145 if (units == PixelsPerCentimeterResolution)
2146 {
2147 image->resolution.x*=2.54;
2148 image->resolution.y*=2.54;
2149 }
2150 break;
2151 }
2152 case PixelsPerCentimeterResolution:
2153 {
2154 if (units == PixelsPerInchResolution)
2155 {
2156 image->resolution.x/=2.54;
2157 image->resolution.y/=2.54;
2158 }
2159 break;
2160 }
2161 }
2162 image->units=units;
2163 }
2164 break;
2165 }
2166 if (info)
2167 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2168 for ( ; image; image=image->next)
2169 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2170 break;
2171 }
2172 case 'V':
2173 case 'v':
2174 {
2175 if (LocaleCompare(attribute,"verbose") == 0)
2176 {
2177 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2178 SvPV(sval,na)) : SvIV(sval);
2179 if (sp < 0)
2180 {
2181 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2182 SvPV(sval,na));
2183 break;
2184 }
2185 if (info)
2186 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2187 break;
2188 }
2189 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2190 {
2191 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2192 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2193 if (sp < 0)
2194 {
2195 ThrowPerlException(exception,OptionError,
2196 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2197 break;
2198 }
2199 for ( ; image; image=image->next)
2200 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2201 break;
2202 }
2203 if (info)
2204 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2205 for ( ; image; image=image->next)
2206 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2207 break;
2208 }
2209 case 'W':
2210 case 'w':
2211 {
2212 if (LocaleCompare(attribute,"white-point") == 0)
2213 {
2214 for ( ; image; image=image->next)
2215 {
2216 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2217 image->chromaticity.white_point.x=geometry_info.rho;
2218 image->chromaticity.white_point.y=geometry_info.sigma;
2219 if ((flags & SigmaValue) == 0)
2220 image->chromaticity.white_point.y=
2221 image->chromaticity.white_point.x;
2222 }
2223 break;
2224 }
2225 if (LocaleCompare(attribute,"write-mask") == 0)
2226 {
2227 Image
2228 *mask;
2229
2230 mask=(Image *) NULL;
2231 if (SvPOK(sval))
2232 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2233 for ( ; image; image=image->next)
2234 SetImageMask(image,WritePixelMask,mask,exception);
2235 break;
2236 }
2237 if (info)
2238 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2239 for ( ; image; image=image->next)
2240 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2241 break;
2242 }
2243 default:
2244 {
2245 if (info)
2246 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2247 for ( ; image; image=image->next)
2248 SetImageProperty(image,attribute,SvPV(sval,na),exception);
2249 break;
2250 }
2251 }
2252 }
2253
2254 /*
2255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2256 % %
2257 % %
2258 % %
2259 % S e t u p L i s t %
2260 % %
2261 % %
2262 % %
2263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2264 %
2265 % Method SetupList returns the list of all the images linked by their
2266 % image->next and image->previous link lists for use with ImageMagick. If
2267 % info is non-NULL, an info structure is returned in *info. If
2268 % reference_vector is non-NULL,an array of SV* are returned in
2269 % *reference_vector. Reference_vector is used when the images are going to be
2270 % replaced with new Image*'s.
2271 %
2272 % The format of the SetupList routine is:
2273 %
2274 % Image *SetupList(SV *reference,struct PackageInfo **info,
2275 % SV ***reference_vector,ExceptionInfo *exception)
2276 %
2277 % A description of each parameter follows:
2278 %
2279 % o list: a list of strings.
2280 %
2281 % o string: a character string.
2282 %
2283 % o exception: Return any errors or warnings in this structure.
2284 %
2285 */
SetupList(pTHX_ SV * reference,struct PackageInfo ** info,SV *** reference_vector,ExceptionInfo * exception)2286 static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2287 SV ***reference_vector,ExceptionInfo *exception)
2288 {
2289 Image
2290 *image;
2291
2292 ssize_t
2293 current,
2294 last;
2295
2296 if (reference_vector)
2297 *reference_vector=NULL;
2298 if (info)
2299 *info=NULL;
2300 current=0;
2301 last=0;
2302 image=GetList(aTHX_ reference,reference_vector,¤t,&last,exception);
2303 if (info && (SvTYPE(reference) == SVt_PVAV))
2304 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2305 exception);
2306 return(image);
2307 }
2308
2309 /*
2310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2311 % %
2312 % %
2313 % %
2314 % s t r E Q c a s e %
2315 % %
2316 % %
2317 % %
2318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2319 %
2320 % strEQcase() compares two strings and returns 0 if they are the
2321 % same or if the second string runs out first. The comparison is case
2322 % insensitive.
2323 %
2324 % The format of the strEQcase routine is:
2325 %
2326 % ssize_t strEQcase(const char *p,const char *q)
2327 %
2328 % A description of each parameter follows:
2329 %
2330 % o p: a character string.
2331 %
2332 % o q: a character string.
2333 %
2334 %
2335 */
strEQcase(const char * p,const char * q)2336 static ssize_t strEQcase(const char *p,const char *q)
2337 {
2338 char
2339 c;
2340
2341 register ssize_t
2342 i;
2343
2344 for (i=0 ; (c=(*q)) != 0; i++)
2345 {
2346 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2347 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2348 return(0);
2349 p++;
2350 q++;
2351 }
2352 return(((*q == 0) && (*p == 0)) ? i : 0);
2353 }
2354
2355 /*
2356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2357 % %
2358 % %
2359 % %
2360 % I m a g e : : M a g i c k %
2361 % %
2362 % %
2363 % %
2364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2365 %
2366 %
2367 */
2368 MODULE = Image::Magick PACKAGE = Image::Magick
2369
2370 PROTOTYPES: ENABLE
2371
2372 BOOT:
2373 MagickCoreGenesis("PerlMagick",MagickFalse);
2374 SetWarningHandler(NULL);
2375 SetErrorHandler(NULL);
2376 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2377 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2378
2379 void
UNLOAD()2380 UNLOAD()
2381 PPCODE:
2382 {
2383 if (magick_registry != (SplayTreeInfo *) NULL)
2384 magick_registry=DestroySplayTree(magick_registry);
2385 MagickCoreTerminus();
2386 }
2387
2388 double
constant(name,argument)2389 constant(name,argument)
2390 char *name
2391 ssize_t argument
2392
2393 #
2394 ###############################################################################
2395 # #
2396 # #
2397 # #
2398 # A n i m a t e #
2399 # #
2400 # #
2401 # #
2402 ###############################################################################
2403 #
2404 #
2405 void
2406 Animate(ref,...)
2407 Image::Magick ref=NO_INIT
2408 ALIAS:
2409 AnimateImage = 1
2410 animate = 2
2411 animateimage = 3
2412 PPCODE:
2413 {
2414 ExceptionInfo
2415 *exception;
2416
2417 Image
2418 *image;
2419
2420 register ssize_t
2421 i;
2422
2423 struct PackageInfo
2424 *info,
2425 *package_info;
2426
2427 SV
2428 *perl_exception,
2429 *reference;
2430
2431 PERL_UNUSED_VAR(ref);
2432 PERL_UNUSED_VAR(ix);
2433 exception=AcquireExceptionInfo();
2434 perl_exception=newSVpv("",0);
2435 package_info=(struct PackageInfo *) NULL;
2436 if (sv_isobject(ST(0)) == 0)
2437 {
2438 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2439 PackageName);
2440 goto PerlException;
2441 }
2442 reference=SvRV(ST(0));
2443 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2444 if (image == (Image *) NULL)
2445 {
2446 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2447 PackageName);
2448 goto PerlException;
2449 }
2450 package_info=ClonePackageInfo(info,exception);
2451 if (items == 2)
2452 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2453 else
2454 if (items > 2)
2455 for (i=2; i < items; i+=2)
2456 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2457 exception);
2458 (void) AnimateImages(package_info->image_info,image,exception);
2459 (void) CatchImageException(image);
2460
2461 PerlException:
2462 if (package_info != (struct PackageInfo *) NULL)
2463 DestroyPackageInfo(package_info);
2464 InheritPerlException(exception,perl_exception);
2465 exception=DestroyExceptionInfo(exception);
2466 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2467 SvPOK_on(perl_exception);
2468 ST(0)=sv_2mortal(perl_exception);
2469 XSRETURN(1);
2470 }
2471
2472 #
2473 ###############################################################################
2474 # #
2475 # #
2476 # #
2477 # A p p e n d #
2478 # #
2479 # #
2480 # #
2481 ###############################################################################
2482 #
2483 #
2484 void
Append(ref,...)2485 Append(ref,...)
2486 Image::Magick ref=NO_INIT
2487 ALIAS:
2488 AppendImage = 1
2489 append = 2
2490 appendimage = 3
2491 PPCODE:
2492 {
2493 AV
2494 *av;
2495
2496 char
2497 *attribute;
2498
2499 ExceptionInfo
2500 *exception;
2501
2502 HV
2503 *hv;
2504
2505 Image
2506 *image;
2507
2508 register ssize_t
2509 i;
2510
2511 ssize_t
2512 stack;
2513
2514 struct PackageInfo
2515 *info;
2516
2517 SV
2518 *av_reference,
2519 *perl_exception,
2520 *reference,
2521 *rv,
2522 *sv;
2523
2524 PERL_UNUSED_VAR(ref);
2525 PERL_UNUSED_VAR(ix);
2526 exception=AcquireExceptionInfo();
2527 perl_exception=newSVpv("",0);
2528 sv=NULL;
2529 attribute=NULL;
2530 av=NULL;
2531 if (sv_isobject(ST(0)) == 0)
2532 {
2533 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2534 PackageName);
2535 goto PerlException;
2536 }
2537 reference=SvRV(ST(0));
2538 hv=SvSTASH(reference);
2539 av=newAV();
2540 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2541 SvREFCNT_dec(av);
2542 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2543 if (image == (Image *) NULL)
2544 {
2545 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2546 PackageName);
2547 goto PerlException;
2548 }
2549 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2550 /*
2551 Get options.
2552 */
2553 stack=MagickTrue;
2554 for (i=2; i < items; i+=2)
2555 {
2556 attribute=(char *) SvPV(ST(i-1),na);
2557 switch (*attribute)
2558 {
2559 case 'S':
2560 case 's':
2561 {
2562 if (LocaleCompare(attribute,"stack") == 0)
2563 {
2564 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2565 SvPV(ST(i),na));
2566 if (stack < 0)
2567 {
2568 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2569 SvPV(ST(i),na));
2570 return;
2571 }
2572 break;
2573 }
2574 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2575 attribute);
2576 break;
2577 }
2578 default:
2579 {
2580 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2581 attribute);
2582 break;
2583 }
2584 }
2585 }
2586 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2587 if (image == (Image *) NULL)
2588 goto PerlException;
2589 for ( ; image; image=image->next)
2590 {
2591 AddImageToRegistry(sv,image);
2592 rv=newRV(sv);
2593 av_push(av,sv_bless(rv,hv));
2594 SvREFCNT_dec(sv);
2595 }
2596 exception=DestroyExceptionInfo(exception);
2597 ST(0)=av_reference;
2598 SvREFCNT_dec(perl_exception);
2599 XSRETURN(1);
2600
2601 PerlException:
2602 InheritPerlException(exception,perl_exception);
2603 exception=DestroyExceptionInfo(exception);
2604 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2605 SvPOK_on(perl_exception);
2606 ST(0)=sv_2mortal(perl_exception);
2607 XSRETURN(1);
2608 }
2609
2610 #
2611 ###############################################################################
2612 # #
2613 # #
2614 # #
2615 # A v e r a g e #
2616 # #
2617 # #
2618 # #
2619 ###############################################################################
2620 #
2621 #
2622 void
Average(ref)2623 Average(ref)
2624 Image::Magick ref=NO_INIT
2625 ALIAS:
2626 AverageImage = 1
2627 average = 2
2628 averageimage = 3
2629 PPCODE:
2630 {
2631 AV
2632 *av;
2633
2634 char
2635 *p;
2636
2637 ExceptionInfo
2638 *exception;
2639
2640 HV
2641 *hv;
2642
2643 Image
2644 *image;
2645
2646 struct PackageInfo
2647 *info;
2648
2649 SV
2650 *perl_exception,
2651 *reference,
2652 *rv,
2653 *sv;
2654
2655 PERL_UNUSED_VAR(ref);
2656 PERL_UNUSED_VAR(ix);
2657 exception=AcquireExceptionInfo();
2658 perl_exception=newSVpv("",0);
2659 sv=NULL;
2660 if (sv_isobject(ST(0)) == 0)
2661 {
2662 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2663 PackageName);
2664 goto PerlException;
2665 }
2666 reference=SvRV(ST(0));
2667 hv=SvSTASH(reference);
2668 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2669 if (image == (Image *) NULL)
2670 {
2671 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2672 PackageName);
2673 goto PerlException;
2674 }
2675 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2676 if (image == (Image *) NULL)
2677 goto PerlException;
2678 /*
2679 Create blessed Perl array for the returned image.
2680 */
2681 av=newAV();
2682 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2683 SvREFCNT_dec(av);
2684 AddImageToRegistry(sv,image);
2685 rv=newRV(sv);
2686 av_push(av,sv_bless(rv,hv));
2687 SvREFCNT_dec(sv);
2688 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2689 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2690 "average-%.*s",(int) (MagickPathExtent-9),
2691 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2692 (void) CopyMagickString(image->filename,info->image_info->filename,
2693 MagickPathExtent);
2694 SetImageInfo(info->image_info,0,exception);
2695 exception=DestroyExceptionInfo(exception);
2696 SvREFCNT_dec(perl_exception);
2697 XSRETURN(1);
2698
2699 PerlException:
2700 InheritPerlException(exception,perl_exception);
2701 exception=DestroyExceptionInfo(exception);
2702 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2703 SvPOK_on(perl_exception);
2704 ST(0)=sv_2mortal(perl_exception);
2705 XSRETURN(1);
2706 }
2707
2708 #
2709 ###############################################################################
2710 # #
2711 # #
2712 # #
2713 # B l o b T o I m a g e #
2714 # #
2715 # #
2716 # #
2717 ###############################################################################
2718 #
2719 #
2720 void
BlobToImage(ref,...)2721 BlobToImage(ref,...)
2722 Image::Magick ref=NO_INIT
2723 ALIAS:
2724 BlobToImage = 1
2725 blobtoimage = 2
2726 blobto = 3
2727 PPCODE:
2728 {
2729 AV
2730 *av;
2731
2732 char
2733 **keep,
2734 **list;
2735
2736 ExceptionInfo
2737 *exception;
2738
2739 HV
2740 *hv;
2741
2742 Image
2743 *image;
2744
2745 register char
2746 **p;
2747
2748 register ssize_t
2749 i;
2750
2751 ssize_t
2752 ac,
2753 n,
2754 number_images;
2755
2756 STRLEN
2757 *length;
2758
2759 struct PackageInfo
2760 *info;
2761
2762 SV
2763 *perl_exception,
2764 *reference,
2765 *rv,
2766 *sv;
2767
2768 PERL_UNUSED_VAR(ref);
2769 PERL_UNUSED_VAR(ix);
2770 exception=AcquireExceptionInfo();
2771 perl_exception=newSVpv("",0);
2772 sv=NULL;
2773 number_images=0;
2774 ac=(items < 2) ? 1 : items-1;
2775 length=(STRLEN *) NULL;
2776 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2777 if (list == (char **) NULL)
2778 {
2779 ThrowPerlException(exception,ResourceLimitError,
2780 "MemoryAllocationFailed",PackageName);
2781 goto PerlException;
2782 }
2783 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2784 if (length == (STRLEN *) NULL)
2785 {
2786 ThrowPerlException(exception,ResourceLimitError,
2787 "MemoryAllocationFailed",PackageName);
2788 goto PerlException;
2789 }
2790 if (sv_isobject(ST(0)) == 0)
2791 {
2792 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2793 PackageName);
2794 goto PerlException;
2795 }
2796 reference=SvRV(ST(0));
2797 hv=SvSTASH(reference);
2798 if (SvTYPE(reference) != SVt_PVAV)
2799 {
2800 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2801 PackageName);
2802 goto PerlException;
2803 }
2804 av=(AV *) reference;
2805 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2806 exception);
2807 n=1;
2808 if (items <= 1)
2809 {
2810 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2811 goto PerlException;
2812 }
2813 for (n=0, i=0; i < ac; i++)
2814 {
2815 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2816 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2817 {
2818 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2819 continue;
2820 }
2821 n++;
2822 }
2823 list[n]=(char *) NULL;
2824 keep=list;
2825 for (i=number_images=0; i < n; i++)
2826 {
2827 image=BlobToImage(info->image_info,list[i],length[i],exception);
2828 if (image == (Image *) NULL)
2829 break;
2830 for ( ; image; image=image->next)
2831 {
2832 AddImageToRegistry(sv,image);
2833 rv=newRV(sv);
2834 av_push(av,sv_bless(rv,hv));
2835 SvREFCNT_dec(sv);
2836 number_images++;
2837 }
2838 }
2839 /*
2840 Free resources.
2841 */
2842 for (i=0; i < n; i++)
2843 if (list[i] != (char *) NULL)
2844 for (p=keep; list[i] != *p++; )
2845 if (*p == (char *) NULL)
2846 {
2847 list[i]=(char *) RelinquishMagickMemory(list[i]);
2848 break;
2849 }
2850
2851 PerlException:
2852 if (list)
2853 list=(char **) RelinquishMagickMemory(list);
2854 if (length)
2855 length=(STRLEN *) RelinquishMagickMemory(length);
2856 InheritPerlException(exception,perl_exception);
2857 exception=DestroyExceptionInfo(exception);
2858 sv_setiv(perl_exception,(IV) number_images);
2859 SvPOK_on(perl_exception);
2860 ST(0)=sv_2mortal(perl_exception);
2861 XSRETURN(1);
2862 }
2863
2864 #
2865 ###############################################################################
2866 # #
2867 # #
2868 # #
2869 # C h a n n e l F x #
2870 # #
2871 # #
2872 # #
2873 ###############################################################################
2874 #
2875 #
2876 void
ChannelFx(ref,...)2877 ChannelFx(ref,...)
2878 Image::Magick ref=NO_INIT
2879 ALIAS:
2880 ChannelFxImage = 1
2881 channelfx = 2
2882 channelfximage = 3
2883 PPCODE:
2884 {
2885 AV
2886 *av;
2887
2888 char
2889 *attribute,
2890 expression[MagickPathExtent];
2891
2892 ChannelType
2893 channel,
2894 channel_mask;
2895
2896 ExceptionInfo
2897 *exception;
2898
2899 HV
2900 *hv;
2901
2902 Image
2903 *image;
2904
2905 register ssize_t
2906 i;
2907
2908 struct PackageInfo
2909 *info;
2910
2911 SV
2912 *av_reference,
2913 *perl_exception,
2914 *reference,
2915 *rv,
2916 *sv;
2917
2918 PERL_UNUSED_VAR(ref);
2919 PERL_UNUSED_VAR(ix);
2920 exception=AcquireExceptionInfo();
2921 perl_exception=newSVpv("",0);
2922 sv=NULL;
2923 attribute=NULL;
2924 av=NULL;
2925 if (sv_isobject(ST(0)) == 0)
2926 {
2927 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2928 PackageName);
2929 goto PerlException;
2930 }
2931 reference=SvRV(ST(0));
2932 hv=SvSTASH(reference);
2933 av=newAV();
2934 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2935 SvREFCNT_dec(av);
2936 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2937 if (image == (Image *) NULL)
2938 {
2939 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2940 PackageName);
2941 goto PerlException;
2942 }
2943 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2944 /*
2945 Get options.
2946 */
2947 channel=DefaultChannels;
2948 (void) CopyMagickString(expression,"u",MagickPathExtent);
2949 if (items == 2)
2950 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
2951 else
2952 for (i=2; i < items; i+=2)
2953 {
2954 attribute=(char *) SvPV(ST(i-1),na);
2955 switch (*attribute)
2956 {
2957 case 'C':
2958 case 'c':
2959 {
2960 if (LocaleCompare(attribute,"channel") == 0)
2961 {
2962 ssize_t
2963 option;
2964
2965 option=ParseChannelOption(SvPV(ST(i),na));
2966 if (option < 0)
2967 {
2968 ThrowPerlException(exception,OptionError,
2969 "UnrecognizedType",SvPV(ST(i),na));
2970 return;
2971 }
2972 channel=(ChannelType) option;
2973 break;
2974 }
2975 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2976 attribute);
2977 break;
2978 }
2979 case 'E':
2980 case 'e':
2981 {
2982 if (LocaleCompare(attribute,"expression") == 0)
2983 {
2984 (void) CopyMagickString(expression,SvPV(ST(i),na),
2985 MagickPathExtent);
2986 break;
2987 }
2988 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2989 attribute);
2990 break;
2991 }
2992 default:
2993 {
2994 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2995 attribute);
2996 break;
2997 }
2998 }
2999 }
3000 channel_mask=SetImageChannelMask(image,channel);
3001 image=ChannelFxImage(image,expression,exception);
3002 if (image != (Image *) NULL)
3003 (void) SetImageChannelMask(image,channel_mask);
3004 if (image == (Image *) NULL)
3005 goto PerlException;
3006 for ( ; image; image=image->next)
3007 {
3008 AddImageToRegistry(sv,image);
3009 rv=newRV(sv);
3010 av_push(av,sv_bless(rv,hv));
3011 SvREFCNT_dec(sv);
3012 }
3013 exception=DestroyExceptionInfo(exception);
3014 ST(0)=av_reference;
3015 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3016 XSRETURN(1);
3017
3018 PerlException:
3019 InheritPerlException(exception,perl_exception);
3020 exception=DestroyExceptionInfo(exception);
3021 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3022 SvPOK_on(perl_exception);
3023 ST(0)=sv_2mortal(perl_exception);
3024 XSRETURN(1);
3025 }
3026
3027 #
3028 ###############################################################################
3029 # #
3030 # #
3031 # #
3032 # C l o n e #
3033 # #
3034 # #
3035 # #
3036 ###############################################################################
3037 #
3038 #
3039 void
Clone(ref)3040 Clone(ref)
3041 Image::Magick ref=NO_INIT
3042 ALIAS:
3043 CopyImage = 1
3044 copy = 2
3045 copyimage = 3
3046 CloneImage = 4
3047 clone = 5
3048 cloneimage = 6
3049 Clone = 7
3050 PPCODE:
3051 {
3052 AV
3053 *av;
3054
3055 ExceptionInfo
3056 *exception;
3057
3058 HV
3059 *hv;
3060
3061 Image
3062 *clone,
3063 *image;
3064
3065 struct PackageInfo
3066 *info;
3067
3068 SV
3069 *perl_exception,
3070 *reference,
3071 *rv,
3072 *sv;
3073
3074 PERL_UNUSED_VAR(ref);
3075 PERL_UNUSED_VAR(ix);
3076 exception=AcquireExceptionInfo();
3077 perl_exception=newSVpv("",0);
3078 sv=NULL;
3079 if (sv_isobject(ST(0)) == 0)
3080 {
3081 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3082 PackageName);
3083 goto PerlException;
3084 }
3085 reference=SvRV(ST(0));
3086 hv=SvSTASH(reference);
3087 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3088 if (image == (Image *) NULL)
3089 {
3090 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3091 PackageName);
3092 goto PerlException;
3093 }
3094 /*
3095 Create blessed Perl array for the returned image.
3096 */
3097 av=newAV();
3098 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3099 SvREFCNT_dec(av);
3100 for ( ; image; image=image->next)
3101 {
3102 clone=CloneImage(image,0,0,MagickTrue,exception);
3103 if (clone == (Image *) NULL)
3104 break;
3105 AddImageToRegistry(sv,clone);
3106 rv=newRV(sv);
3107 av_push(av,sv_bless(rv,hv));
3108 SvREFCNT_dec(sv);
3109 }
3110 exception=DestroyExceptionInfo(exception);
3111 SvREFCNT_dec(perl_exception);
3112 XSRETURN(1);
3113
3114 PerlException:
3115 InheritPerlException(exception,perl_exception);
3116 exception=DestroyExceptionInfo(exception);
3117 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3118 SvPOK_on(perl_exception);
3119 ST(0)=sv_2mortal(perl_exception);
3120 XSRETURN(1);
3121 }
3122
3123 #
3124 ###############################################################################
3125 # #
3126 # #
3127 # #
3128 # C L O N E #
3129 # #
3130 # #
3131 # #
3132 ###############################################################################
3133 #
3134 #
3135 void
CLONE(ref,...)3136 CLONE(ref,...)
3137 SV *ref;
3138 CODE:
3139 {
3140 PERL_UNUSED_VAR(ref);
3141 if (magick_registry != (SplayTreeInfo *) NULL)
3142 {
3143 register Image
3144 *p;
3145
3146 ResetSplayTreeIterator(magick_registry);
3147 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3148 while (p != (Image *) NULL)
3149 {
3150 ReferenceImage(p);
3151 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3152 }
3153 }
3154 }
3155
3156 #
3157 ###############################################################################
3158 # #
3159 # #
3160 # #
3161 # C o a l e s c e #
3162 # #
3163 # #
3164 # #
3165 ###############################################################################
3166 #
3167 #
3168 void
Coalesce(ref)3169 Coalesce(ref)
3170 Image::Magick ref=NO_INIT
3171 ALIAS:
3172 CoalesceImage = 1
3173 coalesce = 2
3174 coalesceimage = 3
3175 PPCODE:
3176 {
3177 AV
3178 *av;
3179
3180 ExceptionInfo
3181 *exception;
3182
3183 HV
3184 *hv;
3185
3186 Image
3187 *image;
3188
3189 struct PackageInfo
3190 *info;
3191
3192 SV
3193 *av_reference,
3194 *perl_exception,
3195 *reference,
3196 *rv,
3197 *sv;
3198
3199 PERL_UNUSED_VAR(ref);
3200 PERL_UNUSED_VAR(ix);
3201 exception=AcquireExceptionInfo();
3202 perl_exception=newSVpv("",0);
3203 sv=NULL;
3204 if (sv_isobject(ST(0)) == 0)
3205 {
3206 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3207 PackageName);
3208 goto PerlException;
3209 }
3210 reference=SvRV(ST(0));
3211 hv=SvSTASH(reference);
3212 av=newAV();
3213 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3214 SvREFCNT_dec(av);
3215 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3216 if (image == (Image *) NULL)
3217 {
3218 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3219 PackageName);
3220 goto PerlException;
3221 }
3222 image=CoalesceImages(image,exception);
3223 if (image == (Image *) NULL)
3224 goto PerlException;
3225 for ( ; image; image=image->next)
3226 {
3227 AddImageToRegistry(sv,image);
3228 rv=newRV(sv);
3229 av_push(av,sv_bless(rv,hv));
3230 SvREFCNT_dec(sv);
3231 }
3232 exception=DestroyExceptionInfo(exception);
3233 ST(0)=av_reference;
3234 SvREFCNT_dec(perl_exception);
3235 XSRETURN(1);
3236
3237 PerlException:
3238 InheritPerlException(exception,perl_exception);
3239 exception=DestroyExceptionInfo(exception);
3240 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3241 SvPOK_on(perl_exception);
3242 ST(0)=sv_2mortal(perl_exception);
3243 XSRETURN(1);
3244 }
3245
3246 #
3247 ###############################################################################
3248 # #
3249 # #
3250 # #
3251 # C o m p a r e #
3252 # #
3253 # #
3254 # #
3255 ###############################################################################
3256 #
3257 #
3258 void
Compare(ref,...)3259 Compare(ref,...)
3260 Image::Magick ref=NO_INIT
3261 ALIAS:
3262 CompareImages = 1
3263 compare = 2
3264 compareimage = 3
3265 PPCODE:
3266 {
3267 AV
3268 *av;
3269
3270 char
3271 *attribute;
3272
3273 double
3274 distortion;
3275
3276 ExceptionInfo
3277 *exception;
3278
3279 HV
3280 *hv;
3281
3282 Image
3283 *difference_image,
3284 *image,
3285 *reconstruct_image;
3286
3287 MetricType
3288 metric;
3289
3290 register ssize_t
3291 i;
3292
3293 ssize_t
3294 option;
3295
3296 struct PackageInfo
3297 *info;
3298
3299 SV
3300 *av_reference,
3301 *perl_exception,
3302 *reference,
3303 *rv,
3304 *sv;
3305
3306 PERL_UNUSED_VAR(ref);
3307 PERL_UNUSED_VAR(ix);
3308 exception=AcquireExceptionInfo();
3309 perl_exception=newSVpv("",0);
3310 sv=NULL;
3311 av=NULL;
3312 attribute=NULL;
3313 if (sv_isobject(ST(0)) == 0)
3314 {
3315 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3316 PackageName);
3317 goto PerlException;
3318 }
3319 reference=SvRV(ST(0));
3320 hv=SvSTASH(reference);
3321 av=newAV();
3322 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3323 SvREFCNT_dec(av);
3324 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3325 if (image == (Image *) NULL)
3326 {
3327 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3328 PackageName);
3329 goto PerlException;
3330 }
3331 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3332 /*
3333 Get attribute.
3334 */
3335 reconstruct_image=image;
3336 metric=RootMeanSquaredErrorMetric;
3337 for (i=2; i < items; i+=2)
3338 {
3339 attribute=(char *) SvPV(ST(i-1),na);
3340 switch (*attribute)
3341 {
3342 case 'C':
3343 case 'c':
3344 {
3345 if (LocaleCompare(attribute,"channel") == 0)
3346 {
3347 ssize_t
3348 option;
3349
3350 option=ParseChannelOption(SvPV(ST(i),na));
3351 if (option < 0)
3352 {
3353 ThrowPerlException(exception,OptionError,
3354 "UnrecognizedType",SvPV(ST(i),na));
3355 return;
3356 }
3357 (void) SetPixelChannelMask(image,(ChannelType) option);
3358 break;
3359 }
3360 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3361 attribute);
3362 break;
3363 }
3364 case 'F':
3365 case 'f':
3366 {
3367 if (LocaleCompare(attribute,"fuzz") == 0)
3368 {
3369 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3370 break;
3371 }
3372 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3373 attribute);
3374 break;
3375 }
3376 case 'I':
3377 case 'i':
3378 {
3379 if (LocaleCompare(attribute,"image") == 0)
3380 {
3381 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3382 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3383 break;
3384 }
3385 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3386 attribute);
3387 break;
3388 }
3389 case 'M':
3390 case 'm':
3391 {
3392 if (LocaleCompare(attribute,"metric") == 0)
3393 {
3394 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3395 SvPV(ST(i),na));
3396 if (option < 0)
3397 {
3398 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3399 SvPV(ST(i),na));
3400 break;
3401 }
3402 metric=(MetricType) option;
3403 break;
3404 }
3405 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3406 attribute);
3407 break;
3408 }
3409 default:
3410 {
3411 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3412 attribute);
3413 break;
3414 }
3415 }
3416 }
3417 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3418 exception);
3419 if (difference_image != (Image *) NULL)
3420 {
3421 difference_image->error.mean_error_per_pixel=distortion;
3422 AddImageToRegistry(sv,difference_image);
3423 rv=newRV(sv);
3424 av_push(av,sv_bless(rv,hv));
3425 SvREFCNT_dec(sv);
3426 }
3427 exception=DestroyExceptionInfo(exception);
3428 ST(0)=av_reference;
3429 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3430 XSRETURN(1);
3431
3432 PerlException:
3433 InheritPerlException(exception,perl_exception);
3434 exception=DestroyExceptionInfo(exception);
3435 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3436 SvPOK_on(perl_exception);
3437 ST(0)=sv_2mortal(perl_exception);
3438 XSRETURN(1);
3439 }
3440
3441 #
3442 ###############################################################################
3443 # #
3444 # #
3445 # #
3446 # C o m p l e x I m a g e s #
3447 # #
3448 # #
3449 # #
3450 ###############################################################################
3451 #
3452 #
3453 void
ComplexImages(ref)3454 ComplexImages(ref)
3455 Image::Magick ref=NO_INIT
3456 ALIAS:
3457 ComplexImages = 1
3458 compleximages = 2
3459 PPCODE:
3460 {
3461 AV
3462 *av;
3463
3464 char
3465 *attribute,
3466 *p;
3467
3468 ComplexOperator
3469 op;
3470
3471 ExceptionInfo
3472 *exception;
3473
3474 HV
3475 *hv;
3476
3477 Image
3478 *image;
3479
3480 register ssize_t
3481 i;
3482
3483 struct PackageInfo
3484 *info;
3485
3486 SV
3487 *perl_exception,
3488 *reference,
3489 *rv,
3490 *sv;
3491
3492 PERL_UNUSED_VAR(ref);
3493 PERL_UNUSED_VAR(ix);
3494 exception=AcquireExceptionInfo();
3495 perl_exception=newSVpv("",0);
3496 sv=NULL;
3497 if (sv_isobject(ST(0)) == 0)
3498 {
3499 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3500 PackageName);
3501 goto PerlException;
3502 }
3503 reference=SvRV(ST(0));
3504 hv=SvSTASH(reference);
3505 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3506 if (image == (Image *) NULL)
3507 {
3508 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3509 PackageName);
3510 goto PerlException;
3511 }
3512 op=UndefinedComplexOperator;
3513 if (items == 2)
3514 {
3515 ssize_t
3516 in;
3517
3518 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3519 SvPV(ST(1),na));
3520 if (in < 0)
3521 {
3522 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3523 SvPV(ST(1),na));
3524 return;
3525 }
3526 op=(ComplexOperator) in;
3527 }
3528 else
3529 for (i=2; i < items; i+=2)
3530 {
3531 attribute=(char *) SvPV(ST(i-1),na);
3532 switch (*attribute)
3533 {
3534 case 'O':
3535 case 'o':
3536 {
3537 if (LocaleCompare(attribute,"operator") == 0)
3538 {
3539 ssize_t
3540 in;
3541
3542 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3543 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3544 if (in < 0)
3545 {
3546 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3547 SvPV(ST(i),na));
3548 return;
3549 }
3550 op=(ComplexOperator) in;
3551 break;
3552 }
3553 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3554 attribute);
3555 break;
3556 }
3557 default:
3558 {
3559 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3560 attribute);
3561 break;
3562 }
3563 }
3564 }
3565 image=ComplexImages(image,op,exception);
3566 if (image == (Image *) NULL)
3567 goto PerlException;
3568 /*
3569 Create blessed Perl array for the returned image.
3570 */
3571 av=newAV();
3572 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3573 SvREFCNT_dec(av);
3574 AddImageToRegistry(sv,image);
3575 rv=newRV(sv);
3576 av_push(av,sv_bless(rv,hv));
3577 SvREFCNT_dec(sv);
3578 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3579 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3580 "complex-%.*s",(int) (MagickPathExtent-9),
3581 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3582 (void) CopyMagickString(image->filename,info->image_info->filename,
3583 MagickPathExtent);
3584 SetImageInfo(info->image_info,0,exception);
3585 exception=DestroyExceptionInfo(exception);
3586 SvREFCNT_dec(perl_exception);
3587 XSRETURN(1);
3588
3589 PerlException:
3590 InheritPerlException(exception,perl_exception);
3591 exception=DestroyExceptionInfo(exception);
3592 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3593 SvPOK_on(perl_exception);
3594 ST(0)=sv_2mortal(perl_exception);
3595 XSRETURN(1);
3596 }
3597
3598 #
3599 ###############################################################################
3600 # #
3601 # #
3602 # #
3603 # C o m p a r e L a y e r s #
3604 # #
3605 # #
3606 # #
3607 ###############################################################################
3608 #
3609 #
3610 void
CompareLayers(ref)3611 CompareLayers(ref)
3612 Image::Magick ref=NO_INIT
3613 ALIAS:
3614 CompareImagesLayers = 1
3615 comparelayers = 2
3616 compareimagelayers = 3
3617 PPCODE:
3618 {
3619 AV
3620 *av;
3621
3622 char
3623 *attribute;
3624
3625 ExceptionInfo
3626 *exception;
3627
3628 HV
3629 *hv;
3630
3631 Image
3632 *image;
3633
3634 LayerMethod
3635 method;
3636
3637 register ssize_t
3638 i;
3639
3640 ssize_t
3641 option;
3642
3643 struct PackageInfo
3644 *info;
3645
3646 SV
3647 *av_reference,
3648 *perl_exception,
3649 *reference,
3650 *rv,
3651 *sv;
3652
3653 PERL_UNUSED_VAR(ref);
3654 PERL_UNUSED_VAR(ix);
3655 exception=AcquireExceptionInfo();
3656 perl_exception=newSVpv("",0);
3657 sv=NULL;
3658 if (sv_isobject(ST(0)) == 0)
3659 {
3660 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3661 PackageName);
3662 goto PerlException;
3663 }
3664 reference=SvRV(ST(0));
3665 hv=SvSTASH(reference);
3666 av=newAV();
3667 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3668 SvREFCNT_dec(av);
3669 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3670 if (image == (Image *) NULL)
3671 {
3672 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3673 PackageName);
3674 goto PerlException;
3675 }
3676 method=CompareAnyLayer;
3677 for (i=2; i < items; i+=2)
3678 {
3679 attribute=(char *) SvPV(ST(i-1),na);
3680 switch (*attribute)
3681 {
3682 case 'M':
3683 case 'm':
3684 {
3685 if (LocaleCompare(attribute,"method") == 0)
3686 {
3687 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3688 SvPV(ST(i),na));
3689 if (option < 0)
3690 {
3691 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3692 SvPV(ST(i),na));
3693 break;
3694 }
3695 method=(LayerMethod) option;
3696 break;
3697 }
3698 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3699 attribute);
3700 break;
3701 }
3702 default:
3703 {
3704 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3705 attribute);
3706 break;
3707 }
3708 }
3709 }
3710 image=CompareImagesLayers(image,method,exception);
3711 if (image == (Image *) NULL)
3712 goto PerlException;
3713 for ( ; image; image=image->next)
3714 {
3715 AddImageToRegistry(sv,image);
3716 rv=newRV(sv);
3717 av_push(av,sv_bless(rv,hv));
3718 SvREFCNT_dec(sv);
3719 }
3720 exception=DestroyExceptionInfo(exception);
3721 ST(0)=av_reference;
3722 SvREFCNT_dec(perl_exception);
3723 XSRETURN(1);
3724
3725 PerlException:
3726 InheritPerlException(exception,perl_exception);
3727 exception=DestroyExceptionInfo(exception);
3728 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3729 SvPOK_on(perl_exception);
3730 ST(0)=sv_2mortal(perl_exception);
3731 XSRETURN(1);
3732 }
3733
3734 #
3735 ###############################################################################
3736 # #
3737 # #
3738 # #
3739 # D e s t r o y #
3740 # #
3741 # #
3742 # #
3743 ###############################################################################
3744 #
3745 #
3746 void
DESTROY(ref)3747 DESTROY(ref)
3748 Image::Magick ref=NO_INIT
3749 PPCODE:
3750 {
3751 SV
3752 *reference;
3753
3754 PERL_UNUSED_VAR(ref);
3755 if (sv_isobject(ST(0)) == 0)
3756 croak("ReferenceIsNotMyType");
3757 reference=SvRV(ST(0));
3758 switch (SvTYPE(reference))
3759 {
3760 case SVt_PVAV:
3761 {
3762 char
3763 message[MagickPathExtent];
3764
3765 const SV
3766 *key;
3767
3768 HV
3769 *hv;
3770
3771 GV
3772 **gvp;
3773
3774 struct PackageInfo
3775 *info;
3776
3777 SV
3778 *sv;
3779
3780 /*
3781 Array (AV *) reference
3782 */
3783 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
3784 XS_VERSION,reference);
3785 hv=gv_stashpv(PackageName, FALSE);
3786 if (!hv)
3787 break;
3788 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3789 if (!gvp)
3790 break;
3791 sv=GvSV(*gvp);
3792 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3793 {
3794 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3795 DestroyPackageInfo(info);
3796 }
3797 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3798 (void) key;
3799 break;
3800 }
3801 case SVt_PVMG:
3802 {
3803 Image
3804 *image;
3805
3806 /*
3807 Blessed scalar = (Image *) SvIV(reference)
3808 */
3809 image=INT2PTR(Image *,SvIV(reference));
3810 if (image != (Image *) NULL)
3811 DeleteImageFromRegistry(reference,image);
3812 break;
3813 }
3814 default:
3815 break;
3816 }
3817 }
3818
3819 #
3820 ###############################################################################
3821 # #
3822 # #
3823 # #
3824 # D i s p l a y #
3825 # #
3826 # #
3827 # #
3828 ###############################################################################
3829 #
3830 #
3831 void
Display(ref,...)3832 Display(ref,...)
3833 Image::Magick ref=NO_INIT
3834 ALIAS:
3835 DisplayImage = 1
3836 display = 2
3837 displayimage = 3
3838 PPCODE:
3839 {
3840 ExceptionInfo
3841 *exception;
3842
3843 Image
3844 *image;
3845
3846 register ssize_t
3847 i;
3848
3849 struct PackageInfo
3850 *info,
3851 *package_info;
3852
3853 SV
3854 *perl_exception,
3855 *reference;
3856
3857 PERL_UNUSED_VAR(ref);
3858 PERL_UNUSED_VAR(ix);
3859 exception=AcquireExceptionInfo();
3860 perl_exception=newSVpv("",0);
3861 package_info=(struct PackageInfo *) NULL;
3862 if (sv_isobject(ST(0)) == 0)
3863 {
3864 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3865 PackageName);
3866 goto PerlException;
3867 }
3868 reference=SvRV(ST(0));
3869 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3870 if (image == (Image *) NULL)
3871 {
3872 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3873 PackageName);
3874 goto PerlException;
3875 }
3876 package_info=ClonePackageInfo(info,exception);
3877 if (items == 2)
3878 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3879 else
3880 if (items > 2)
3881 for (i=2; i < items; i+=2)
3882 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3883 exception);
3884 (void) DisplayImages(package_info->image_info,image,exception);
3885 (void) CatchImageException(image);
3886
3887 PerlException:
3888 if (package_info != (struct PackageInfo *) NULL)
3889 DestroyPackageInfo(package_info);
3890 InheritPerlException(exception,perl_exception);
3891 exception=DestroyExceptionInfo(exception);
3892 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3893 SvPOK_on(perl_exception);
3894 ST(0)=sv_2mortal(perl_exception);
3895 XSRETURN(1);
3896 }
3897
3898 #
3899 ###############################################################################
3900 # #
3901 # #
3902 # #
3903 # E v a l u a t e I m a g e s #
3904 # #
3905 # #
3906 # #
3907 ###############################################################################
3908 #
3909 #
3910 void
EvaluateImages(ref)3911 EvaluateImages(ref)
3912 Image::Magick ref=NO_INIT
3913 ALIAS:
3914 EvaluateImages = 1
3915 evaluateimages = 2
3916 PPCODE:
3917 {
3918 AV
3919 *av;
3920
3921 char
3922 *attribute,
3923 *p;
3924
3925 ExceptionInfo
3926 *exception;
3927
3928 HV
3929 *hv;
3930
3931 Image
3932 *image;
3933
3934 MagickEvaluateOperator
3935 op;
3936
3937 register ssize_t
3938 i;
3939
3940 struct PackageInfo
3941 *info;
3942
3943 SV
3944 *perl_exception,
3945 *reference,
3946 *rv,
3947 *sv;
3948
3949 PERL_UNUSED_VAR(ref);
3950 PERL_UNUSED_VAR(ix);
3951 exception=AcquireExceptionInfo();
3952 perl_exception=newSVpv("",0);
3953 sv=NULL;
3954 if (sv_isobject(ST(0)) == 0)
3955 {
3956 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3957 PackageName);
3958 goto PerlException;
3959 }
3960 reference=SvRV(ST(0));
3961 hv=SvSTASH(reference);
3962 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3963 if (image == (Image *) NULL)
3964 {
3965 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3966 PackageName);
3967 goto PerlException;
3968 }
3969 op=MeanEvaluateOperator;
3970 if (items == 2)
3971 {
3972 ssize_t
3973 in;
3974
3975 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3976 SvPV(ST(1),na));
3977 if (in < 0)
3978 {
3979 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3980 SvPV(ST(1),na));
3981 return;
3982 }
3983 op=(MagickEvaluateOperator) in;
3984 }
3985 else
3986 for (i=2; i < items; i+=2)
3987 {
3988 attribute=(char *) SvPV(ST(i-1),na);
3989 switch (*attribute)
3990 {
3991 case 'O':
3992 case 'o':
3993 {
3994 if (LocaleCompare(attribute,"operator") == 0)
3995 {
3996 ssize_t
3997 in;
3998
3999 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4000 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4001 if (in < 0)
4002 {
4003 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4004 SvPV(ST(i),na));
4005 return;
4006 }
4007 op=(MagickEvaluateOperator) in;
4008 break;
4009 }
4010 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4011 attribute);
4012 break;
4013 }
4014 default:
4015 {
4016 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4017 attribute);
4018 break;
4019 }
4020 }
4021 }
4022 image=EvaluateImages(image,op,exception);
4023 if (image == (Image *) NULL)
4024 goto PerlException;
4025 /*
4026 Create blessed Perl array for the returned image.
4027 */
4028 av=newAV();
4029 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4030 SvREFCNT_dec(av);
4031 AddImageToRegistry(sv,image);
4032 rv=newRV(sv);
4033 av_push(av,sv_bless(rv,hv));
4034 SvREFCNT_dec(sv);
4035 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4036 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4037 "evaluate-%.*s",(int) (MagickPathExtent-9),
4038 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4039 (void) CopyMagickString(image->filename,info->image_info->filename,
4040 MagickPathExtent);
4041 SetImageInfo(info->image_info,0,exception);
4042 exception=DestroyExceptionInfo(exception);
4043 SvREFCNT_dec(perl_exception);
4044 XSRETURN(1);
4045
4046 PerlException:
4047 InheritPerlException(exception,perl_exception);
4048 exception=DestroyExceptionInfo(exception);
4049 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4050 SvPOK_on(perl_exception);
4051 ST(0)=sv_2mortal(perl_exception);
4052 XSRETURN(1);
4053 }
4054
4055 #
4056 ###############################################################################
4057 # #
4058 # #
4059 # #
4060 # F e a t u r e s #
4061 # #
4062 # #
4063 # #
4064 ###############################################################################
4065 #
4066 #
4067 void
Features(ref,...)4068 Features(ref,...)
4069 Image::Magick ref=NO_INIT
4070 ALIAS:
4071 FeaturesImage = 1
4072 features = 2
4073 featuresimage = 3
4074 PPCODE:
4075 {
4076 #define ChannelFeatures(channel,direction) \
4077 { \
4078 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4079 channel_features[channel].angular_second_moment[direction]); \
4080 PUSHs(sv_2mortal(newSVpv(message,0))); \
4081 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4082 channel_features[channel].contrast[direction]); \
4083 PUSHs(sv_2mortal(newSVpv(message,0))); \
4084 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4085 channel_features[channel].contrast[direction]); \
4086 PUSHs(sv_2mortal(newSVpv(message,0))); \
4087 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4088 channel_features[channel].variance_sum_of_squares[direction]); \
4089 PUSHs(sv_2mortal(newSVpv(message,0))); \
4090 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4091 channel_features[channel].inverse_difference_moment[direction]); \
4092 PUSHs(sv_2mortal(newSVpv(message,0))); \
4093 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4094 channel_features[channel].sum_average[direction]); \
4095 PUSHs(sv_2mortal(newSVpv(message,0))); \
4096 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4097 channel_features[channel].sum_variance[direction]); \
4098 PUSHs(sv_2mortal(newSVpv(message,0))); \
4099 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4100 channel_features[channel].sum_entropy[direction]); \
4101 PUSHs(sv_2mortal(newSVpv(message,0))); \
4102 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4103 channel_features[channel].entropy[direction]); \
4104 PUSHs(sv_2mortal(newSVpv(message,0))); \
4105 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4106 channel_features[channel].difference_variance[direction]); \
4107 PUSHs(sv_2mortal(newSVpv(message,0))); \
4108 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4109 channel_features[channel].difference_entropy[direction]); \
4110 PUSHs(sv_2mortal(newSVpv(message,0))); \
4111 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4112 channel_features[channel].measure_of_correlation_1[direction]); \
4113 PUSHs(sv_2mortal(newSVpv(message,0))); \
4114 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4115 channel_features[channel].measure_of_correlation_2[direction]); \
4116 PUSHs(sv_2mortal(newSVpv(message,0))); \
4117 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4118 channel_features[channel].maximum_correlation_coefficient[direction]); \
4119 PUSHs(sv_2mortal(newSVpv(message,0))); \
4120 }
4121
4122 AV
4123 *av;
4124
4125 char
4126 *attribute,
4127 message[MagickPathExtent];
4128
4129 ChannelFeatures
4130 *channel_features;
4131
4132 double
4133 distance;
4134
4135 ExceptionInfo
4136 *exception;
4137
4138 Image
4139 *image;
4140
4141 register ssize_t
4142 i;
4143
4144 ssize_t
4145 count;
4146
4147 struct PackageInfo
4148 *info;
4149
4150 SV
4151 *perl_exception,
4152 *reference;
4153
4154 PERL_UNUSED_VAR(ref);
4155 PERL_UNUSED_VAR(ix);
4156 exception=AcquireExceptionInfo();
4157 perl_exception=newSVpv("",0);
4158 av=NULL;
4159 if (sv_isobject(ST(0)) == 0)
4160 {
4161 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4162 PackageName);
4163 goto PerlException;
4164 }
4165 reference=SvRV(ST(0));
4166 av=newAV();
4167 SvREFCNT_dec(av);
4168 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4169 if (image == (Image *) NULL)
4170 {
4171 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4172 PackageName);
4173 goto PerlException;
4174 }
4175 distance=1.0;
4176 for (i=2; i < items; i+=2)
4177 {
4178 attribute=(char *) SvPV(ST(i-1),na);
4179 switch (*attribute)
4180 {
4181 case 'D':
4182 case 'd':
4183 {
4184 if (LocaleCompare(attribute,"distance") == 0)
4185 {
4186 distance=StringToLong((char *) SvPV(ST(1),na));
4187 break;
4188 }
4189 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4190 attribute);
4191 break;
4192 }
4193 default:
4194 {
4195 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4196 attribute);
4197 break;
4198 }
4199 }
4200 }
4201 count=0;
4202 for ( ; image; image=image->next)
4203 {
4204 channel_features=GetImageFeatures(image,distance,exception);
4205 if (channel_features == (ChannelFeatures *) NULL)
4206 continue;
4207 count++;
4208 EXTEND(sp,280*count);
4209 for (i=0; i < 4; i++)
4210 {
4211 ChannelFeatures(RedChannel,i);
4212 ChannelFeatures(GreenChannel,i);
4213 ChannelFeatures(BlueChannel,i);
4214 if (image->colorspace == CMYKColorspace)
4215 ChannelFeatures(BlackChannel,i);
4216 if (image->alpha_trait != UndefinedPixelTrait)
4217 ChannelFeatures(AlphaChannel,i);
4218 }
4219 channel_features=(ChannelFeatures *)
4220 RelinquishMagickMemory(channel_features);
4221 }
4222
4223 PerlException:
4224 InheritPerlException(exception,perl_exception);
4225 exception=DestroyExceptionInfo(exception);
4226 SvREFCNT_dec(perl_exception);
4227 }
4228
4229 #
4230 ###############################################################################
4231 # #
4232 # #
4233 # #
4234 # F l a t t e n #
4235 # #
4236 # #
4237 # #
4238 ###############################################################################
4239 #
4240 #
4241 void
Flatten(ref)4242 Flatten(ref)
4243 Image::Magick ref=NO_INIT
4244 ALIAS:
4245 FlattenImage = 1
4246 flatten = 2
4247 flattenimage = 3
4248 PPCODE:
4249 {
4250 AV
4251 *av;
4252
4253 char
4254 *attribute,
4255 *p;
4256
4257 ExceptionInfo
4258 *exception;
4259
4260 HV
4261 *hv;
4262
4263 Image
4264 *image;
4265
4266 PixelInfo
4267 background_color;
4268
4269 register ssize_t
4270 i;
4271
4272 struct PackageInfo
4273 *info;
4274
4275 SV
4276 *perl_exception,
4277 *reference,
4278 *rv,
4279 *sv;
4280
4281 PERL_UNUSED_VAR(ref);
4282 PERL_UNUSED_VAR(ix);
4283 exception=AcquireExceptionInfo();
4284 perl_exception=newSVpv("",0);
4285 sv=NULL;
4286 if (sv_isobject(ST(0)) == 0)
4287 {
4288 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4289 PackageName);
4290 goto PerlException;
4291 }
4292 reference=SvRV(ST(0));
4293 hv=SvSTASH(reference);
4294 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4295 if (image == (Image *) NULL)
4296 {
4297 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4298 PackageName);
4299 goto PerlException;
4300 }
4301 background_color=image->background_color;
4302 if (items == 2)
4303 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4304 &background_color,exception);
4305 else
4306 for (i=2; i < items; i+=2)
4307 {
4308 attribute=(char *) SvPV(ST(i-1),na);
4309 switch (*attribute)
4310 {
4311 case 'B':
4312 case 'b':
4313 {
4314 if (LocaleCompare(attribute,"background") == 0)
4315 {
4316 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4317 AllCompliance,&background_color,exception);
4318 break;
4319 }
4320 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4321 attribute);
4322 break;
4323 }
4324 default:
4325 {
4326 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4327 attribute);
4328 break;
4329 }
4330 }
4331 }
4332 image->background_color=background_color;
4333 image=MergeImageLayers(image,FlattenLayer,exception);
4334 if (image == (Image *) NULL)
4335 goto PerlException;
4336 /*
4337 Create blessed Perl array for the returned image.
4338 */
4339 av=newAV();
4340 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4341 SvREFCNT_dec(av);
4342 AddImageToRegistry(sv,image);
4343 rv=newRV(sv);
4344 av_push(av,sv_bless(rv,hv));
4345 SvREFCNT_dec(sv);
4346 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4347 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4348 "flatten-%.*s",(int) (MagickPathExtent-9),
4349 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4350 (void) CopyMagickString(image->filename,info->image_info->filename,
4351 MagickPathExtent);
4352 SetImageInfo(info->image_info,0,exception);
4353 exception=DestroyExceptionInfo(exception);
4354 SvREFCNT_dec(perl_exception);
4355 XSRETURN(1);
4356
4357 PerlException:
4358 InheritPerlException(exception,perl_exception);
4359 exception=DestroyExceptionInfo(exception);
4360 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4361 SvPOK_on(perl_exception); /* return messages in string context */
4362 ST(0)=sv_2mortal(perl_exception);
4363 XSRETURN(1);
4364 }
4365
4366 #
4367 ###############################################################################
4368 # #
4369 # #
4370 # #
4371 # F x #
4372 # #
4373 # #
4374 # #
4375 ###############################################################################
4376 #
4377 #
4378 void
Fx(ref,...)4379 Fx(ref,...)
4380 Image::Magick ref=NO_INIT
4381 ALIAS:
4382 FxImage = 1
4383 fx = 2
4384 fximage = 3
4385 PPCODE:
4386 {
4387 AV
4388 *av;
4389
4390 char
4391 *attribute,
4392 expression[MagickPathExtent];
4393
4394 ChannelType
4395 channel,
4396 channel_mask;
4397
4398 ExceptionInfo
4399 *exception;
4400
4401 HV
4402 *hv;
4403
4404 Image
4405 *image;
4406
4407 register ssize_t
4408 i;
4409
4410 struct PackageInfo
4411 *info;
4412
4413 SV
4414 *av_reference,
4415 *perl_exception,
4416 *reference,
4417 *rv,
4418 *sv;
4419
4420 PERL_UNUSED_VAR(ref);
4421 PERL_UNUSED_VAR(ix);
4422 exception=AcquireExceptionInfo();
4423 perl_exception=newSVpv("",0);
4424 sv=NULL;
4425 attribute=NULL;
4426 av=NULL;
4427 if (sv_isobject(ST(0)) == 0)
4428 {
4429 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4430 PackageName);
4431 goto PerlException;
4432 }
4433 reference=SvRV(ST(0));
4434 hv=SvSTASH(reference);
4435 av=newAV();
4436 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4437 SvREFCNT_dec(av);
4438 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4439 if (image == (Image *) NULL)
4440 {
4441 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4442 PackageName);
4443 goto PerlException;
4444 }
4445 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4446 /*
4447 Get options.
4448 */
4449 channel=DefaultChannels;
4450 (void) CopyMagickString(expression,"u",MagickPathExtent);
4451 if (items == 2)
4452 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
4453 else
4454 for (i=2; i < items; i+=2)
4455 {
4456 attribute=(char *) SvPV(ST(i-1),na);
4457 switch (*attribute)
4458 {
4459 case 'C':
4460 case 'c':
4461 {
4462 if (LocaleCompare(attribute,"channel") == 0)
4463 {
4464 ssize_t
4465 option;
4466
4467 option=ParseChannelOption(SvPV(ST(i),na));
4468 if (option < 0)
4469 {
4470 ThrowPerlException(exception,OptionError,
4471 "UnrecognizedType",SvPV(ST(i),na));
4472 return;
4473 }
4474 channel=(ChannelType) option;
4475 break;
4476 }
4477 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4478 attribute);
4479 break;
4480 }
4481 case 'E':
4482 case 'e':
4483 {
4484 if (LocaleCompare(attribute,"expression") == 0)
4485 {
4486 (void) CopyMagickString(expression,SvPV(ST(i),na),
4487 MagickPathExtent);
4488 break;
4489 }
4490 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4491 attribute);
4492 break;
4493 }
4494 default:
4495 {
4496 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4497 attribute);
4498 break;
4499 }
4500 }
4501 }
4502 channel_mask=SetImageChannelMask(image,channel);
4503 image=FxImage(image,expression,exception);
4504 if (image != (Image *) NULL)
4505 (void) SetImageChannelMask(image,channel_mask);
4506 if (image == (Image *) NULL)
4507 goto PerlException;
4508 for ( ; image; image=image->next)
4509 {
4510 AddImageToRegistry(sv,image);
4511 rv=newRV(sv);
4512 av_push(av,sv_bless(rv,hv));
4513 SvREFCNT_dec(sv);
4514 }
4515 exception=DestroyExceptionInfo(exception);
4516 ST(0)=av_reference;
4517 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4518 XSRETURN(1);
4519
4520 PerlException:
4521 InheritPerlException(exception,perl_exception);
4522 exception=DestroyExceptionInfo(exception);
4523 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4524 SvPOK_on(perl_exception);
4525 ST(0)=sv_2mortal(perl_exception);
4526 XSRETURN(1);
4527 }
4528
4529 #
4530 ###############################################################################
4531 # #
4532 # #
4533 # #
4534 # G e t #
4535 # #
4536 # #
4537 # #
4538 ###############################################################################
4539 #
4540 #
4541 void
Get(ref,...)4542 Get(ref,...)
4543 Image::Magick ref=NO_INIT
4544 ALIAS:
4545 GetAttributes = 1
4546 GetAttribute = 2
4547 get = 3
4548 getattributes = 4
4549 getattribute = 5
4550 PPCODE:
4551 {
4552 char
4553 *attribute,
4554 color[MagickPathExtent];
4555
4556 const char
4557 *value;
4558
4559 ExceptionInfo
4560 *exception;
4561
4562 Image
4563 *image;
4564
4565 long
4566 j;
4567
4568 register ssize_t
4569 i;
4570
4571 struct PackageInfo
4572 *info;
4573
4574 SV
4575 *perl_exception,
4576 *reference,
4577 *s;
4578
4579 PERL_UNUSED_VAR(ref);
4580 PERL_UNUSED_VAR(ix);
4581 exception=AcquireExceptionInfo();
4582 perl_exception=newSVpv("",0);
4583 if (sv_isobject(ST(0)) == 0)
4584 {
4585 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4586 PackageName);
4587 XSRETURN_EMPTY;
4588 }
4589 reference=SvRV(ST(0));
4590 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4591 if (image == (Image *) NULL && !info)
4592 XSRETURN_EMPTY;
4593 EXTEND(sp,items);
4594 for (i=1; i < items; i++)
4595 {
4596 attribute=(char *) SvPV(ST(i),na);
4597 s=NULL;
4598 switch (*attribute)
4599 {
4600 case 'A':
4601 case 'a':
4602 {
4603 if (LocaleCompare(attribute,"adjoin") == 0)
4604 {
4605 if (info)
4606 s=newSViv((ssize_t) info->image_info->adjoin);
4607 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4608 continue;
4609 }
4610 if (LocaleCompare(attribute,"antialias") == 0)
4611 {
4612 if (info)
4613 s=newSViv((ssize_t) info->image_info->antialias);
4614 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4615 continue;
4616 }
4617 if (LocaleCompare(attribute,"area") == 0)
4618 {
4619 s=newSViv(GetMagickResource(AreaResource));
4620 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4621 continue;
4622 }
4623 if (LocaleCompare(attribute,"attenuate") == 0)
4624 {
4625 const char
4626 *value;
4627
4628 value=GetImageProperty(image,attribute,exception);
4629 if (value != (const char *) NULL)
4630 s=newSVpv(value,0);
4631 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4632 continue;
4633 }
4634 if (LocaleCompare(attribute,"authenticate") == 0)
4635 {
4636 if (info)
4637 {
4638 const char
4639 *option;
4640
4641 option=GetImageOption(info->image_info,attribute);
4642 if (option != (const char *) NULL)
4643 s=newSVpv(option,0);
4644 }
4645 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4646 continue;
4647 }
4648 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4649 attribute);
4650 break;
4651 }
4652 case 'B':
4653 case 'b':
4654 {
4655 if (LocaleCompare(attribute,"background") == 0)
4656 {
4657 if (image == (Image *) NULL)
4658 break;
4659 (void) FormatLocaleString(color,MagickPathExtent,
4660 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4661 (double) image->background_color.green,
4662 (double) image->background_color.blue,
4663 (double) image->background_color.alpha);
4664 s=newSVpv(color,0);
4665 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4666 continue;
4667 }
4668 if (LocaleCompare(attribute,"base-columns") == 0)
4669 {
4670 if (image != (Image *) NULL)
4671 s=newSViv((ssize_t) image->magick_columns);
4672 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4673 continue;
4674 }
4675 if (LocaleCompare(attribute,"base-filename") == 0)
4676 {
4677 if (image != (Image *) NULL)
4678 s=newSVpv(image->magick_filename,0);
4679 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4680 continue;
4681 }
4682 if (LocaleCompare(attribute,"base-height") == 0)
4683 {
4684 if (image != (Image *) NULL)
4685 s=newSViv((ssize_t) image->magick_rows);
4686 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4687 continue;
4688 }
4689 if (LocaleCompare(attribute,"base-rows") == 0)
4690 {
4691 if (image != (Image *) NULL)
4692 s=newSViv((ssize_t) image->magick_rows);
4693 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4694 continue;
4695 }
4696 if (LocaleCompare(attribute,"base-width") == 0)
4697 {
4698 if (image != (Image *) NULL)
4699 s=newSViv((ssize_t) image->magick_columns);
4700 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4701 continue;
4702 }
4703 if (LocaleCompare(attribute,"blue-primary") == 0)
4704 {
4705 if (image == (Image *) NULL)
4706 break;
4707 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
4708 image->chromaticity.blue_primary.x,
4709 image->chromaticity.blue_primary.y);
4710 s=newSVpv(color,0);
4711 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4712 continue;
4713 }
4714 if (LocaleCompare(attribute,"bordercolor") == 0)
4715 {
4716 if (image == (Image *) NULL)
4717 break;
4718 (void) FormatLocaleString(color,MagickPathExtent,
4719 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4720 (double) image->border_color.green,
4721 (double) image->border_color.blue,
4722 (double) image->border_color.alpha);
4723 s=newSVpv(color,0);
4724 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4725 continue;
4726 }
4727 if (LocaleCompare(attribute,"bounding-box") == 0)
4728 {
4729 char
4730 geometry[MagickPathExtent];
4731
4732 RectangleInfo
4733 page;
4734
4735 if (image == (Image *) NULL)
4736 break;
4737 page=GetImageBoundingBox(image,exception);
4738 (void) FormatLocaleString(geometry,MagickPathExtent,
4739 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4740 page.height,(double) page.x,(double) page.y);
4741 s=newSVpv(geometry,0);
4742 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4743 continue;
4744 }
4745 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4746 attribute);
4747 break;
4748 }
4749 case 'C':
4750 case 'c':
4751 {
4752 if (LocaleCompare(attribute,"class") == 0)
4753 {
4754 if (image == (Image *) NULL)
4755 break;
4756 s=newSViv(image->storage_class);
4757 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4758 image->storage_class));
4759 SvIOK_on(s);
4760 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4761 continue;
4762 }
4763 if (LocaleCompare(attribute,"clip-mask") == 0)
4764 {
4765 if (image != (Image *) NULL)
4766 {
4767 Image
4768 *mask_image;
4769
4770 SV
4771 *sv;
4772
4773 sv=NULL;
4774 if (image->read_mask == MagickFalse)
4775 ClipImage(image,exception);
4776 mask_image=GetImageMask(image,ReadPixelMask,exception);
4777 if (mask_image != (Image *) NULL)
4778 {
4779 AddImageToRegistry(sv,mask_image);
4780 s=sv_bless(newRV(sv),SvSTASH(reference));
4781 }
4782 }
4783 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4784 continue;
4785 }
4786 if (LocaleCompare(attribute,"clip-path") == 0)
4787 {
4788 if (image != (Image *) NULL)
4789 {
4790 Image
4791 *mask_image;
4792
4793 SV
4794 *sv;
4795
4796 sv=NULL;
4797 if (image->read_mask != MagickFalse)
4798 ClipImage(image,exception);
4799 mask_image=GetImageMask(image,ReadPixelMask,exception);
4800 if (mask_image != (Image *) NULL)
4801 {
4802 AddImageToRegistry(sv,mask_image);
4803 s=sv_bless(newRV(sv),SvSTASH(reference));
4804 }
4805 }
4806 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4807 continue;
4808 }
4809 if (LocaleCompare(attribute,"compression") == 0)
4810 {
4811 j=info ? info->image_info->compression : image ?
4812 image->compression : UndefinedCompression;
4813 if (info)
4814 if (info->image_info->compression == UndefinedCompression)
4815 j=image->compression;
4816 s=newSViv(j);
4817 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4818 j));
4819 SvIOK_on(s);
4820 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4821 continue;
4822 }
4823 if (LocaleCompare(attribute,"colorspace") == 0)
4824 {
4825 j=image ? image->colorspace : RGBColorspace;
4826 s=newSViv(j);
4827 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4828 j));
4829 SvIOK_on(s);
4830 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4831 continue;
4832 }
4833 if (LocaleCompare(attribute,"colors") == 0)
4834 {
4835 if (image != (Image *) NULL)
4836 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4837 exception));
4838 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4839 continue;
4840 }
4841 if (LocaleNCompare(attribute,"colormap",8) == 0)
4842 {
4843 int
4844 items;
4845
4846 if (image == (Image *) NULL || !image->colormap)
4847 break;
4848 j=0;
4849 items=sscanf(attribute,"%*[^[][%ld",&j);
4850 (void) items;
4851 if (j > (ssize_t) image->colors)
4852 j%=image->colors;
4853 (void) FormatLocaleString(color,MagickPathExtent,
4854 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4855 (double) image->colormap[j].green,
4856 (double) image->colormap[j].blue,
4857 (double) image->colormap[j].alpha);
4858 s=newSVpv(color,0);
4859 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4860 continue;
4861 }
4862 if (LocaleCompare(attribute,"columns") == 0)
4863 {
4864 if (image != (Image *) NULL)
4865 s=newSViv((ssize_t) image->columns);
4866 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4867 continue;
4868 }
4869 if (LocaleCompare(attribute,"comment") == 0)
4870 {
4871 const char
4872 *value;
4873
4874 value=GetImageProperty(image,attribute,exception);
4875 if (value != (const char *) NULL)
4876 s=newSVpv(value,0);
4877 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4878 continue;
4879 }
4880 if (LocaleCompare(attribute,"copyright") == 0)
4881 {
4882 s=newSVpv(GetMagickCopyright(),0);
4883 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4884 continue;
4885 }
4886 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4887 attribute);
4888 break;
4889 }
4890 case 'D':
4891 case 'd':
4892 {
4893 if (LocaleCompare(attribute,"density") == 0)
4894 {
4895 char
4896 geometry[MagickPathExtent];
4897
4898 if (image == (Image *) NULL)
4899 break;
4900 (void) FormatLocaleString(geometry,MagickPathExtent,"%.15gx%.15g",
4901 image->resolution.x,image->resolution.y);
4902 s=newSVpv(geometry,0);
4903 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4904 continue;
4905 }
4906 if (LocaleCompare(attribute,"delay") == 0)
4907 {
4908 if (image != (Image *) NULL)
4909 s=newSViv((ssize_t) image->delay);
4910 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4911 continue;
4912 }
4913 if (LocaleCompare(attribute,"depth") == 0)
4914 {
4915 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4916 if (image != (Image *) NULL)
4917 s=newSViv((ssize_t) GetImageDepth(image,exception));
4918 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4919 continue;
4920 }
4921 if (LocaleCompare(attribute,"directory") == 0)
4922 {
4923 if (image && image->directory)
4924 s=newSVpv(image->directory,0);
4925 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4926 continue;
4927 }
4928 if (LocaleCompare(attribute,"dispose") == 0)
4929 {
4930 if (image == (Image *) NULL)
4931 break;
4932
4933 s=newSViv(image->dispose);
4934 (void) sv_setpv(s,
4935 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4936 SvIOK_on(s);
4937 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4938 continue;
4939 }
4940 if (LocaleCompare(attribute,"disk") == 0)
4941 {
4942 s=newSViv(GetMagickResource(DiskResource));
4943 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4944 continue;
4945 }
4946 if (LocaleCompare(attribute,"dither") == 0)
4947 {
4948 if (info)
4949 s=newSViv((ssize_t) info->image_info->dither);
4950 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4951 continue;
4952 }
4953 if (LocaleCompare(attribute,"display") == 0) /* same as server */
4954 {
4955 if (info && info->image_info->server_name)
4956 s=newSVpv(info->image_info->server_name,0);
4957 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4958 continue;
4959 }
4960 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4961 attribute);
4962 break;
4963 }
4964 case 'E':
4965 case 'e':
4966 {
4967 if (LocaleCompare(attribute,"elapsed-time") == 0)
4968 {
4969 if (image != (Image *) NULL)
4970 s=newSVnv(GetElapsedTime(&image->timer));
4971 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4972 continue;
4973 }
4974 if (LocaleCompare(attribute,"endian") == 0)
4975 {
4976 j=info ? info->image_info->endian : image ? image->endian :
4977 UndefinedEndian;
4978 s=newSViv(j);
4979 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4980 SvIOK_on(s);
4981 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4982 continue;
4983 }
4984 if (LocaleCompare(attribute,"error") == 0)
4985 {
4986 if (image != (Image *) NULL)
4987 s=newSVnv(image->error.mean_error_per_pixel);
4988 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4989 continue;
4990 }
4991 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4992 attribute);
4993 break;
4994 }
4995 case 'F':
4996 case 'f':
4997 {
4998 if (LocaleCompare(attribute,"filesize") == 0)
4999 {
5000 if (image != (Image *) NULL)
5001 s=newSViv((ssize_t) GetBlobSize(image));
5002 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5003 continue;
5004 }
5005 if (LocaleCompare(attribute,"filename") == 0)
5006 {
5007 if (info && info->image_info->filename &&
5008 *info->image_info->filename)
5009 s=newSVpv(info->image_info->filename,0);
5010 if (image != (Image *) NULL)
5011 s=newSVpv(image->filename,0);
5012 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5013 continue;
5014 }
5015 if (LocaleCompare(attribute,"filter") == 0)
5016 {
5017 s=image ? newSViv(image->filter) : newSViv(0);
5018 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5019 image->filter));
5020 SvIOK_on(s);
5021 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5022 continue;
5023 }
5024 if (LocaleCompare(attribute,"font") == 0)
5025 {
5026 if (info && info->image_info->font)
5027 s=newSVpv(info->image_info->font,0);
5028 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5029 continue;
5030 }
5031 if (LocaleCompare(attribute,"foreground") == 0)
5032 continue;
5033 if (LocaleCompare(attribute,"format") == 0)
5034 {
5035 const MagickInfo
5036 *magick_info;
5037
5038 magick_info=(const MagickInfo *) NULL;
5039 if (info && (*info->image_info->magick != '\0'))
5040 magick_info=GetMagickInfo(info->image_info->magick,exception);
5041 if (image != (Image *) NULL)
5042 magick_info=GetMagickInfo(image->magick,exception);
5043 if ((magick_info != (const MagickInfo *) NULL) &&
5044 (*magick_info->description != '\0'))
5045 s=newSVpv((char *) magick_info->description,0);
5046 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5047 continue;
5048 }
5049 if (LocaleCompare(attribute,"fuzz") == 0)
5050 {
5051 if (info)
5052 s=newSVnv(info->image_info->fuzz);
5053 if (image != (Image *) NULL)
5054 s=newSVnv(image->fuzz);
5055 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5056 continue;
5057 }
5058 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5059 attribute);
5060 break;
5061 }
5062 case 'G':
5063 case 'g':
5064 {
5065 if (LocaleCompare(attribute,"gamma") == 0)
5066 {
5067 if (image != (Image *) NULL)
5068 s=newSVnv(image->gamma);
5069 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5070 continue;
5071 }
5072 if (LocaleCompare(attribute,"geometry") == 0)
5073 {
5074 if (image && image->geometry)
5075 s=newSVpv(image->geometry,0);
5076 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5077 continue;
5078 }
5079 if (LocaleCompare(attribute,"gravity") == 0)
5080 {
5081 s=image ? newSViv(image->gravity) : newSViv(0);
5082 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5083 image->gravity));
5084 SvIOK_on(s);
5085 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5086 continue;
5087 }
5088 if (LocaleCompare(attribute,"green-primary") == 0)
5089 {
5090 if (image == (Image *) NULL)
5091 break;
5092 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
5093 image->chromaticity.green_primary.x,
5094 image->chromaticity.green_primary.y);
5095 s=newSVpv(color,0);
5096 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5097 continue;
5098 }
5099 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5100 attribute);
5101 break;
5102 }
5103 case 'H':
5104 case 'h':
5105 {
5106 if (LocaleCompare(attribute,"height") == 0)
5107 {
5108 if (image != (Image *) NULL)
5109 s=newSViv((ssize_t) image->rows);
5110 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5111 continue;
5112 }
5113 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5114 attribute);
5115 break;
5116 }
5117 case 'I':
5118 case 'i':
5119 {
5120 if (LocaleCompare(attribute,"icc") == 0)
5121 {
5122 if (image != (Image *) NULL)
5123 {
5124 const StringInfo
5125 *profile;
5126
5127 profile=GetImageProfile(image,"icc");
5128 if (profile != (StringInfo *) NULL)
5129 s=newSVpv((const char *) GetStringInfoDatum(profile),
5130 GetStringInfoLength(profile));
5131 }
5132 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5133 continue;
5134 }
5135 if (LocaleCompare(attribute,"icm") == 0)
5136 {
5137 if (image != (Image *) NULL)
5138 {
5139 const StringInfo
5140 *profile;
5141
5142 profile=GetImageProfile(image,"icm");
5143 if (profile != (const StringInfo *) NULL)
5144 s=newSVpv((const char *) GetStringInfoDatum(profile),
5145 GetStringInfoLength(profile));
5146 }
5147 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5148 continue;
5149 }
5150 if (LocaleCompare(attribute,"id") == 0)
5151 {
5152 if (image != (Image *) NULL)
5153 {
5154 char
5155 key[MagickPathExtent];
5156
5157 MagickBooleanType
5158 status;
5159
5160 static ssize_t
5161 id = 0;
5162
5163 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
5164 id);
5165 status=SetImageRegistry(ImageRegistryType,key,image,
5166 exception);
5167 (void) status;
5168 s=newSViv(id++);
5169 }
5170 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5171 continue;
5172 }
5173 if (LocaleNCompare(attribute,"index",5) == 0)
5174 {
5175 char
5176 name[MagickPathExtent];
5177
5178 int
5179 items;
5180
5181 long
5182 x,
5183 y;
5184
5185 register const Quantum
5186 *p;
5187
5188 CacheView
5189 *image_view;
5190
5191 if (image == (Image *) NULL)
5192 break;
5193 if (image->storage_class != PseudoClass)
5194 break;
5195 x=0;
5196 y=0;
5197 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5198 (void) items;
5199 image_view=AcquireVirtualCacheView(image,exception);
5200 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5201 if (p != (const Quantum *) NULL)
5202 {
5203 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
5204 GetPixelIndex(image,p));
5205 s=newSVpv(name,0);
5206 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5207 }
5208 image_view=DestroyCacheView(image_view);
5209 continue;
5210 }
5211 if (LocaleCompare(attribute,"iptc") == 0)
5212 {
5213 if (image != (Image *) NULL)
5214 {
5215 const StringInfo
5216 *profile;
5217
5218 profile=GetImageProfile(image,"iptc");
5219 if (profile != (const StringInfo *) NULL)
5220 s=newSVpv((const char *) GetStringInfoDatum(profile),
5221 GetStringInfoLength(profile));
5222 }
5223 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5224 continue;
5225 }
5226 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5227 {
5228 if (image != (Image *) NULL)
5229 s=newSViv((ssize_t) image->iterations);
5230 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5231 continue;
5232 }
5233 if (LocaleCompare(attribute,"interlace") == 0)
5234 {
5235 j=info ? info->image_info->interlace : image ? image->interlace :
5236 UndefinedInterlace;
5237 s=newSViv(j);
5238 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5239 j));
5240 SvIOK_on(s);
5241 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5242 continue;
5243 }
5244 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5245 attribute);
5246 break;
5247 }
5248 case 'L':
5249 case 'l':
5250 {
5251 if (LocaleCompare(attribute,"label") == 0)
5252 {
5253 const char
5254 *value;
5255
5256 if (image == (Image *) NULL)
5257 break;
5258 value=GetImageProperty(image,"Label",exception);
5259 if (value != (const char *) NULL)
5260 s=newSVpv(value,0);
5261 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5262 continue;
5263 }
5264 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5265 {
5266 if (image != (Image *) NULL)
5267 s=newSViv((ssize_t) image->iterations);
5268 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5269 continue;
5270 }
5271 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5272 attribute);
5273 break;
5274 }
5275 case 'M':
5276 case 'm':
5277 {
5278 if (LocaleCompare(attribute,"magick") == 0)
5279 {
5280 if (info && *info->image_info->magick)
5281 s=newSVpv(info->image_info->magick,0);
5282 if (image != (Image *) NULL)
5283 s=newSVpv(image->magick,0);
5284 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5285 continue;
5286 }
5287 if (LocaleCompare(attribute,"map") == 0)
5288 {
5289 s=newSViv(GetMagickResource(MapResource));
5290 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5291 continue;
5292 }
5293 if (LocaleCompare(attribute,"maximum-error") == 0)
5294 {
5295 if (image != (Image *) NULL)
5296 s=newSVnv(image->error.normalized_maximum_error);
5297 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5298 continue;
5299 }
5300 if (LocaleCompare(attribute,"memory") == 0)
5301 {
5302 s=newSViv(GetMagickResource(MemoryResource));
5303 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5304 continue;
5305 }
5306 if (LocaleCompare(attribute,"mean-error") == 0)
5307 {
5308 if (image != (Image *) NULL)
5309 s=newSVnv(image->error.normalized_mean_error);
5310 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5311 continue;
5312 }
5313 if (LocaleCompare(attribute,"mime") == 0)
5314 {
5315 if (info && *info->image_info->magick)
5316 s=newSVpv(MagickToMime(info->image_info->magick),0);
5317 if (image != (Image *) NULL)
5318 s=newSVpv(MagickToMime(image->magick),0);
5319 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5320 continue;
5321 }
5322 if (LocaleCompare(attribute,"mattecolor") == 0)
5323 {
5324 if (image == (Image *) NULL)
5325 break;
5326 (void) FormatLocaleString(color,MagickPathExtent,
5327 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5328 (double) image->alpha_color.green,
5329 (double) image->alpha_color.blue,
5330 (double) image->alpha_color.alpha);
5331 s=newSVpv(color,0);
5332 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5333 continue;
5334 }
5335 if (LocaleCompare(attribute,"matte") == 0)
5336 {
5337 if (image != (Image *) NULL)
5338 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
5339 1 : 0);
5340 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5341 continue;
5342 }
5343 if (LocaleCompare(attribute,"mime") == 0)
5344 {
5345 const char
5346 *magick;
5347
5348 magick=NULL;
5349 if (info && *info->image_info->magick)
5350 magick=info->image_info->magick;
5351 if (image != (Image *) NULL)
5352 magick=image->magick;
5353 if (magick)
5354 {
5355 char
5356 *mime;
5357
5358 mime=MagickToMime(magick);
5359 s=newSVpv(mime,0);
5360 mime=(char *) RelinquishMagickMemory(mime);
5361 }
5362 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5363 continue;
5364 }
5365 if (LocaleCompare(attribute,"monochrome") == 0)
5366 {
5367 if (image == (Image *) NULL)
5368 continue;
5369 j=info ? info->image_info->monochrome :
5370 SetImageMonochrome(image,exception);
5371 s=newSViv(j);
5372 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5373 continue;
5374 }
5375 if (LocaleCompare(attribute,"montage") == 0)
5376 {
5377 if (image && image->montage)
5378 s=newSVpv(image->montage,0);
5379 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5380 continue;
5381 }
5382 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5383 attribute);
5384 break;
5385 }
5386 case 'O':
5387 case 'o':
5388 {
5389 if (LocaleCompare(attribute,"orientation") == 0)
5390 {
5391 j=info ? info->image_info->orientation : image ?
5392 image->orientation : UndefinedOrientation;
5393 s=newSViv(j);
5394 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5395 j));
5396 SvIOK_on(s);
5397 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5398 continue;
5399 }
5400 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5401 attribute);
5402 break;
5403 }
5404 case 'P':
5405 case 'p':
5406 {
5407 if (LocaleCompare(attribute,"page") == 0)
5408 {
5409 if (info && info->image_info->page)
5410 s=newSVpv(info->image_info->page,0);
5411 if (image != (Image *) NULL)
5412 {
5413 char
5414 geometry[MagickPathExtent];
5415
5416 (void) FormatLocaleString(geometry,MagickPathExtent,
5417 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5418 (double) image->page.height,(double) image->page.x,(double)
5419 image->page.y);
5420 s=newSVpv(geometry,0);
5421 }
5422 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5423 continue;
5424 }
5425 if (LocaleCompare(attribute,"page.x") == 0)
5426 {
5427 if (image != (Image *) NULL)
5428 s=newSViv((ssize_t) image->page.x);
5429 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5430 continue;
5431 }
5432 if (LocaleCompare(attribute,"page.y") == 0)
5433 {
5434 if (image != (Image *) NULL)
5435 s=newSViv((ssize_t) image->page.y);
5436 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5437 continue;
5438 }
5439 if (LocaleNCompare(attribute,"pixel",5) == 0)
5440 {
5441 char
5442 tuple[MagickPathExtent];
5443
5444 int
5445 items;
5446
5447 long
5448 x,
5449 y;
5450
5451 register const Quantum
5452 *p;
5453
5454 if (image == (Image *) NULL)
5455 break;
5456 x=0;
5457 y=0;
5458 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5459 (void) items;
5460 p=GetVirtualPixels(image,x,y,1,1,exception);
5461 if (image->colorspace != CMYKColorspace)
5462 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
5463 QuantumFormat "," QuantumFormat "," QuantumFormat,
5464 GetPixelRed(image,p),GetPixelGreen(image,p),
5465 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5466 else
5467 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
5468 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5469 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5470 GetPixelBlue(image,p),GetPixelBlack(image,p),
5471 GetPixelAlpha(image,p));
5472 s=newSVpv(tuple,0);
5473 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5474 continue;
5475 }
5476 if (LocaleCompare(attribute,"pointsize") == 0)
5477 {
5478 if (info)
5479 s=newSViv((ssize_t) info->image_info->pointsize);
5480 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5481 continue;
5482 }
5483 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5484 attribute);
5485 break;
5486 }
5487 case 'Q':
5488 case 'q':
5489 {
5490 if (LocaleCompare(attribute,"quality") == 0)
5491 {
5492 if (info)
5493 s=newSViv((ssize_t) info->image_info->quality);
5494 if (image != (Image *) NULL)
5495 s=newSViv((ssize_t) image->quality);
5496 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5497 continue;
5498 }
5499 if (LocaleCompare(attribute,"quantum") == 0)
5500 {
5501 if (info)
5502 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5503 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5504 continue;
5505 }
5506 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5507 attribute);
5508 break;
5509 }
5510 case 'R':
5511 case 'r':
5512 {
5513 if (LocaleCompare(attribute,"rendering-intent") == 0)
5514 {
5515 s=newSViv(image->rendering_intent);
5516 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5517 image->rendering_intent));
5518 SvIOK_on(s);
5519 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5520 continue;
5521 }
5522 if (LocaleCompare(attribute,"red-primary") == 0)
5523 {
5524 if (image == (Image *) NULL)
5525 break;
5526 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
5527 image->chromaticity.red_primary.x,
5528 image->chromaticity.red_primary.y);
5529 s=newSVpv(color,0);
5530 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5531 continue;
5532 }
5533 if (LocaleCompare(attribute,"rows") == 0)
5534 {
5535 if (image != (Image *) NULL)
5536 s=newSViv((ssize_t) image->rows);
5537 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5538 continue;
5539 }
5540 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5541 attribute);
5542 break;
5543 }
5544 case 'S':
5545 case 's':
5546 {
5547 if (LocaleCompare(attribute,"sampling-factor") == 0)
5548 {
5549 if (info && info->image_info->sampling_factor)
5550 s=newSVpv(info->image_info->sampling_factor,0);
5551 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5552 continue;
5553 }
5554 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5555 {
5556 if (info && info->image_info->server_name)
5557 s=newSVpv(info->image_info->server_name,0);
5558 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5559 continue;
5560 }
5561 if (LocaleCompare(attribute,"size") == 0)
5562 {
5563 if (info && info->image_info->size)
5564 s=newSVpv(info->image_info->size,0);
5565 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5566 continue;
5567 }
5568 if (LocaleCompare(attribute,"scene") == 0)
5569 {
5570 if (image != (Image *) NULL)
5571 s=newSViv((ssize_t) image->scene);
5572 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5573 continue;
5574 }
5575 if (LocaleCompare(attribute,"scenes") == 0)
5576 {
5577 if (image != (Image *) NULL)
5578 s=newSViv((ssize_t) info->image_info->number_scenes);
5579 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5580 continue;
5581 }
5582 if (LocaleCompare(attribute,"signature") == 0)
5583 {
5584 const char
5585 *value;
5586
5587 if (image == (Image *) NULL)
5588 break;
5589 (void) SignatureImage(image,exception);
5590 value=GetImageProperty(image,"Signature",exception);
5591 if (value != (const char *) NULL)
5592 s=newSVpv(value,0);
5593 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5594 continue;
5595 }
5596 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5597 attribute);
5598 break;
5599 }
5600 case 'T':
5601 case 't':
5602 {
5603 if (LocaleCompare(attribute,"taint") == 0)
5604 {
5605 if (image != (Image *) NULL)
5606 s=newSViv((ssize_t) IsTaintImage(image));
5607 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5608 continue;
5609 }
5610 if (LocaleCompare(attribute,"texture") == 0)
5611 {
5612 if (info && info->image_info->texture)
5613 s=newSVpv(info->image_info->texture,0);
5614 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5615 continue;
5616 }
5617 if (LocaleCompare(attribute,"total-ink-density") == 0)
5618 {
5619 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5620 if (image != (Image *) NULL)
5621 s=newSVnv(GetImageTotalInkDensity(image,exception));
5622 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5623 continue;
5624 }
5625 if (LocaleCompare(attribute,"transparent-color") == 0)
5626 {
5627 if (image == (Image *) NULL)
5628 break;
5629 (void) FormatLocaleString(color,MagickPathExtent,
5630 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5631 (double) image->transparent_color.green,
5632 (double) image->transparent_color.blue,
5633 (double) image->transparent_color.alpha);
5634 s=newSVpv(color,0);
5635 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5636 continue;
5637 }
5638 if (LocaleCompare(attribute,"type") == 0)
5639 {
5640 if (image == (Image *) NULL)
5641 break;
5642 j=(ssize_t) GetImageType(image);
5643 s=newSViv(j);
5644 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5645 SvIOK_on(s);
5646 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5647 continue;
5648 }
5649 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5650 attribute);
5651 break;
5652 }
5653 case 'U':
5654 case 'u':
5655 {
5656 if (LocaleCompare(attribute,"units") == 0)
5657 {
5658 j=info ? info->image_info->units : image ? image->units :
5659 UndefinedResolution;
5660 if (info && (info->image_info->units == UndefinedResolution))
5661 if (image)
5662 j=image->units;
5663 if (j == UndefinedResolution)
5664 s=newSVpv("undefined units",0);
5665 else
5666 if (j == PixelsPerInchResolution)
5667 s=newSVpv("pixels / inch",0);
5668 else
5669 s=newSVpv("pixels / centimeter",0);
5670 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5671 continue;
5672 }
5673 if (LocaleCompare(attribute,"user-time") == 0)
5674 {
5675 if (image != (Image *) NULL)
5676 s=newSVnv(GetUserTime(&image->timer));
5677 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5678 continue;
5679 }
5680 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5681 attribute);
5682 break;
5683 }
5684 case 'V':
5685 case 'v':
5686 {
5687 if (LocaleCompare(attribute,"verbose") == 0)
5688 {
5689 if (info)
5690 s=newSViv((ssize_t) info->image_info->verbose);
5691 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5692 continue;
5693 }
5694 if (LocaleCompare(attribute,"version") == 0)
5695 {
5696 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5697 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5698 continue;
5699 }
5700 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5701 {
5702 if (image == (Image *) NULL)
5703 break;
5704 j=(ssize_t) GetImageVirtualPixelMethod(image);
5705 s=newSViv(j);
5706 (void) sv_setpv(s,CommandOptionToMnemonic(
5707 MagickVirtualPixelOptions,j));
5708 SvIOK_on(s);
5709 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5710 continue;
5711 }
5712 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5713 attribute);
5714 break;
5715 }
5716 case 'W':
5717 case 'w':
5718 {
5719 if (LocaleCompare(attribute,"white-point") == 0)
5720 {
5721 if (image == (Image *) NULL)
5722 break;
5723 (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
5724 image->chromaticity.white_point.x,
5725 image->chromaticity.white_point.y);
5726 s=newSVpv(color,0);
5727 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5728 continue;
5729 }
5730 if (LocaleCompare(attribute,"width") == 0)
5731 {
5732 if (image != (Image *) NULL)
5733 s=newSViv((ssize_t) image->columns);
5734 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5735 continue;
5736 }
5737 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5738 attribute);
5739 break;
5740 }
5741 case 'X':
5742 case 'x':
5743 {
5744 if (LocaleCompare(attribute,"xmp") == 0)
5745 {
5746 if (image != (Image *) NULL)
5747 {
5748 const StringInfo
5749 *profile;
5750
5751 profile=GetImageProfile(image,"xmp");
5752 if (profile != (StringInfo *) NULL)
5753 s=newSVpv((const char *) GetStringInfoDatum(profile),
5754 GetStringInfoLength(profile));
5755 }
5756 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5757 continue;
5758 }
5759 if (LocaleCompare(attribute,"x-resolution") == 0)
5760 {
5761 if (image != (Image *) NULL)
5762 s=newSVnv(image->resolution.x);
5763 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5764 continue;
5765 }
5766 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5767 attribute);
5768 break;
5769 }
5770 case 'Y':
5771 case 'y':
5772 {
5773 if (LocaleCompare(attribute,"y-resolution") == 0)
5774 {
5775 if (image != (Image *) NULL)
5776 s=newSVnv(image->resolution.y);
5777 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5778 continue;
5779 }
5780 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5781 attribute);
5782 break;
5783 }
5784 default:
5785 break;
5786 }
5787 if (image == (Image *) NULL)
5788 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5789 attribute)
5790 else
5791 {
5792 value=GetImageProperty(image,attribute,exception);
5793 if (value != (const char *) NULL)
5794 {
5795 s=newSVpv(value,0);
5796 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5797 }
5798 else
5799 if (*attribute != '%')
5800 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5801 attribute)
5802 else
5803 {
5804 char
5805 *meta;
5806
5807 meta=InterpretImageProperties(info ? info->image_info :
5808 (ImageInfo *) NULL,image,attribute,exception);
5809 s=newSVpv(meta,0);
5810 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5811 meta=(char *) RelinquishMagickMemory(meta);
5812 }
5813 }
5814 }
5815 exception=DestroyExceptionInfo(exception);
5816 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5817 }
5818
5819 #
5820 ###############################################################################
5821 # #
5822 # #
5823 # #
5824 # G e t A u t h e n t i c P i x e l s #
5825 # #
5826 # #
5827 # #
5828 ###############################################################################
5829 #
5830 #
5831 void *
GetAuthenticPixels(ref,...)5832 GetAuthenticPixels(ref,...)
5833 Image::Magick ref = NO_INIT
5834 ALIAS:
5835 getauthenticpixels = 1
5836 GetImagePixels = 2
5837 getimagepixels = 3
5838 CODE:
5839 {
5840 char
5841 *attribute;
5842
5843 ExceptionInfo
5844 *exception;
5845
5846 Image
5847 *image;
5848
5849 RectangleInfo
5850 region;
5851
5852 ssize_t
5853 i;
5854
5855 struct PackageInfo
5856 *info;
5857
5858 SV
5859 *perl_exception,
5860 *reference;
5861
5862 void
5863 *blob = NULL;
5864
5865 PERL_UNUSED_VAR(ref);
5866 PERL_UNUSED_VAR(ix);
5867 exception=AcquireExceptionInfo();
5868 perl_exception=newSVpv("",0);
5869 if (sv_isobject(ST(0)) == 0)
5870 {
5871 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5872 PackageName);
5873 goto PerlException;
5874 }
5875 reference=SvRV(ST(0));
5876
5877 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5878 if (image == (Image *) NULL)
5879 {
5880 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5881 PackageName);
5882 goto PerlException;
5883 }
5884
5885 region.x=0;
5886 region.y=0;
5887 region.width=image->columns;
5888 region.height=1;
5889 if (items == 1)
5890 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion);
5891 for (i=2; i < items; i+=2)
5892 {
5893 attribute=(char *) SvPV(ST(i-1),na);
5894 switch (*attribute)
5895 {
5896 case 'g':
5897 case 'G':
5898 {
5899 if (LocaleCompare(attribute,"geometry") == 0)
5900 {
5901 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion);
5902 break;
5903 }
5904 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5905 attribute);
5906 break;
5907 }
5908 case 'H':
5909 case 'h':
5910 {
5911 if (LocaleCompare(attribute,"height") == 0)
5912 {
5913 region.height=SvIV(ST(i));
5914 continue;
5915 }
5916 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5917 attribute);
5918 break;
5919 }
5920 case 'X':
5921 case 'x':
5922 {
5923 if (LocaleCompare(attribute,"x") == 0)
5924 {
5925 region.x=SvIV(ST(i));
5926 continue;
5927 }
5928 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5929 attribute);
5930 break;
5931 }
5932 case 'Y':
5933 case 'y':
5934 {
5935 if (LocaleCompare(attribute,"y") == 0)
5936 {
5937 region.y=SvIV(ST(i));
5938 continue;
5939 }
5940 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5941 attribute);
5942 break;
5943 }
5944 case 'W':
5945 case 'w':
5946 {
5947 if (LocaleCompare(attribute,"width") == 0)
5948 {
5949 region.width=SvIV(ST(i));
5950 continue;
5951 }
5952 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5953 attribute);
5954 break;
5955 }
5956 }
5957 }
5958 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5959 region.height,exception);
5960 if (blob != (void *) NULL)
5961 goto PerlEnd;
5962
5963 PerlException:
5964 InheritPerlException(exception,perl_exception);
5965 exception=DestroyExceptionInfo(exception);
5966 SvREFCNT_dec(perl_exception); /* throw away all errors */
5967
5968 PerlEnd:
5969 RETVAL = blob;
5970 }
5971 OUTPUT:
5972 RETVAL
5973
5974 #
5975 ###############################################################################
5976 # #
5977 # #
5978 # #
5979 # G e t V i r t u a l P i x e l s #
5980 # #
5981 # #
5982 # #
5983 ###############################################################################
5984 #
5985 #
5986 void *
GetVirtualPixels(ref,...)5987 GetVirtualPixels(ref,...)
5988 Image::Magick ref = NO_INIT
5989 ALIAS:
5990 getvirtualpixels = 1
5991 AcquireImagePixels = 2
5992 acquireimagepixels = 3
5993 CODE:
5994 {
5995 char
5996 *attribute;
5997
5998 const void
5999 *blob = NULL;
6000
6001 ExceptionInfo
6002 *exception;
6003
6004 Image
6005 *image;
6006
6007 RectangleInfo
6008 region;
6009
6010 ssize_t
6011 i;
6012
6013 struct PackageInfo
6014 *info;
6015
6016 SV
6017 *perl_exception,
6018 *reference;
6019
6020 PERL_UNUSED_VAR(ref);
6021 PERL_UNUSED_VAR(ix);
6022 exception=AcquireExceptionInfo();
6023 perl_exception=newSVpv("",0);
6024 if (sv_isobject(ST(0)) == 0)
6025 {
6026 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6027 PackageName);
6028 goto PerlException;
6029 }
6030 reference=SvRV(ST(0));
6031
6032 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6033 if (image == (Image *) NULL)
6034 {
6035 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6036 PackageName);
6037 goto PerlException;
6038 }
6039
6040 region.x=0;
6041 region.y=0;
6042 region.width=image->columns;
6043 region.height=1;
6044 if (items == 1)
6045 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion);
6046 for (i=2; i < items; i+=2)
6047 {
6048 attribute=(char *) SvPV(ST(i-1),na);
6049 switch (*attribute)
6050 {
6051 case 'g':
6052 case 'G':
6053 {
6054 if (LocaleCompare(attribute,"geometry") == 0)
6055 {
6056 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion);
6057 break;
6058 }
6059 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6060 attribute);
6061 break;
6062 }
6063 case 'H':
6064 case 'h':
6065 {
6066 if (LocaleCompare(attribute,"height") == 0)
6067 {
6068 region.height=SvIV(ST(i));
6069 continue;
6070 }
6071 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6072 attribute);
6073 break;
6074 }
6075 case 'X':
6076 case 'x':
6077 {
6078 if (LocaleCompare(attribute,"x") == 0)
6079 {
6080 region.x=SvIV(ST(i));
6081 continue;
6082 }
6083 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6084 attribute);
6085 break;
6086 }
6087 case 'Y':
6088 case 'y':
6089 {
6090 if (LocaleCompare(attribute,"y") == 0)
6091 {
6092 region.y=SvIV(ST(i));
6093 continue;
6094 }
6095 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6096 attribute);
6097 break;
6098 }
6099 case 'W':
6100 case 'w':
6101 {
6102 if (LocaleCompare(attribute,"width") == 0)
6103 {
6104 region.width=SvIV(ST(i));
6105 continue;
6106 }
6107 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6108 attribute);
6109 break;
6110 }
6111 }
6112 }
6113 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6114 region.height,exception);
6115 if (blob != (void *) NULL)
6116 goto PerlEnd;
6117
6118 PerlException:
6119 InheritPerlException(exception,perl_exception);
6120 exception=DestroyExceptionInfo(exception);
6121 SvREFCNT_dec(perl_exception); /* throw away all errors */
6122
6123 PerlEnd:
6124 RETVAL = (void *) blob;
6125 }
6126 OUTPUT:
6127 RETVAL
6128
6129 #
6130 ###############################################################################
6131 # #
6132 # #
6133 # #
6134 # G e t A u t h e n t i c M e t a c o n t e n t #
6135 # #
6136 # #
6137 # #
6138 ###############################################################################
6139 #
6140 #
6141 void *
GetAuthenticMetacontent(ref,...)6142 GetAuthenticMetacontent(ref,...)
6143 Image::Magick ref = NO_INIT
6144 ALIAS:
6145 getauthenticmetacontent = 1
6146 GetMetacontent = 2
6147 getmetacontent = 3
6148 CODE:
6149 {
6150 ExceptionInfo
6151 *exception;
6152
6153 Image
6154 *image;
6155
6156 struct PackageInfo
6157 *info;
6158
6159 SV
6160 *perl_exception,
6161 *reference;
6162
6163 void
6164 *blob = NULL;
6165
6166 PERL_UNUSED_VAR(ref);
6167 PERL_UNUSED_VAR(ix);
6168 exception=AcquireExceptionInfo();
6169 perl_exception=newSVpv("",0);
6170 if (sv_isobject(ST(0)) == 0)
6171 {
6172 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6173 PackageName);
6174 goto PerlException;
6175 }
6176 reference=SvRV(ST(0));
6177
6178 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6179 if (image == (Image *) NULL)
6180 {
6181 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6182 PackageName);
6183 goto PerlException;
6184 }
6185
6186 blob=(void *) GetAuthenticMetacontent(image);
6187 if (blob != (void *) NULL)
6188 goto PerlEnd;
6189
6190 PerlException:
6191 InheritPerlException(exception,perl_exception);
6192 exception=DestroyExceptionInfo(exception);
6193 SvREFCNT_dec(perl_exception); /* throw away all errors */
6194
6195 PerlEnd:
6196 RETVAL = blob;
6197 }
6198 OUTPUT:
6199 RETVAL
6200
6201 #
6202 ###############################################################################
6203 # #
6204 # #
6205 # #
6206 # G e t V i r t u a l M e t a c o n t e n t #
6207 # #
6208 # #
6209 # #
6210 ###############################################################################
6211 #
6212 #
6213 void *
GetVirtualMetacontent(ref,...)6214 GetVirtualMetacontent(ref,...)
6215 Image::Magick ref = NO_INIT
6216 ALIAS:
6217 getvirtualmetacontent = 1
6218 CODE:
6219 {
6220 ExceptionInfo
6221 *exception;
6222
6223 Image
6224 *image;
6225
6226 struct PackageInfo
6227 *info;
6228
6229 SV
6230 *perl_exception,
6231 *reference;
6232
6233 void
6234 *blob = NULL;
6235
6236 PERL_UNUSED_VAR(ref);
6237 PERL_UNUSED_VAR(ix);
6238 exception=AcquireExceptionInfo();
6239 perl_exception=newSVpv("",0);
6240 if (sv_isobject(ST(0)) == 0)
6241 {
6242 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6243 PackageName);
6244 goto PerlException;
6245 }
6246 reference=SvRV(ST(0));
6247
6248 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6249 if (image == (Image *) NULL)
6250 {
6251 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6252 PackageName);
6253 goto PerlException;
6254 }
6255
6256 blob=(void *) GetVirtualMetacontent(image);
6257 if (blob != (void *) NULL)
6258 goto PerlEnd;
6259
6260 PerlException:
6261 InheritPerlException(exception,perl_exception);
6262 exception=DestroyExceptionInfo(exception);
6263 SvREFCNT_dec(perl_exception); /* throw away all errors */
6264
6265 PerlEnd:
6266 RETVAL = blob;
6267 }
6268 OUTPUT:
6269 RETVAL
6270
6271 #
6272 ###############################################################################
6273 # #
6274 # #
6275 # #
6276 # H i s t o g r a m #
6277 # #
6278 # #
6279 # #
6280 ###############################################################################
6281 #
6282 #
6283 void
Histogram(ref,...)6284 Histogram(ref,...)
6285 Image::Magick ref=NO_INIT
6286 ALIAS:
6287 HistogramImage = 1
6288 histogram = 2
6289 histogramimage = 3
6290 PPCODE:
6291 {
6292 AV
6293 *av;
6294
6295 char
6296 message[MagickPathExtent];
6297
6298 PixelInfo
6299 *histogram;
6300
6301 ExceptionInfo
6302 *exception;
6303
6304 Image
6305 *image;
6306
6307 register ssize_t
6308 i;
6309
6310 ssize_t
6311 count;
6312
6313 struct PackageInfo
6314 *info;
6315
6316 SV
6317 *perl_exception,
6318 *reference;
6319
6320 size_t
6321 number_colors;
6322
6323 PERL_UNUSED_VAR(ref);
6324 PERL_UNUSED_VAR(ix);
6325 exception=AcquireExceptionInfo();
6326 perl_exception=newSVpv("",0);
6327 av=NULL;
6328 if (sv_isobject(ST(0)) == 0)
6329 {
6330 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6331 PackageName);
6332 goto PerlException;
6333 }
6334 reference=SvRV(ST(0));
6335 av=newAV();
6336 SvREFCNT_dec(av);
6337 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6338 if (image == (Image *) NULL)
6339 {
6340 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6341 PackageName);
6342 goto PerlException;
6343 }
6344 count=0;
6345 for ( ; image; image=image->next)
6346 {
6347 histogram=GetImageHistogram(image,&number_colors,exception);
6348 if (histogram == (PixelInfo *) NULL)
6349 continue;
6350 count+=(ssize_t) number_colors;
6351 EXTEND(sp,6*count);
6352 for (i=0; i < (ssize_t) number_colors; i++)
6353 {
6354 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6355 histogram[i].red);
6356 PUSHs(sv_2mortal(newSVpv(message,0)));
6357 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6358 histogram[i].green);
6359 PUSHs(sv_2mortal(newSVpv(message,0)));
6360 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6361 histogram[i].blue);
6362 PUSHs(sv_2mortal(newSVpv(message,0)));
6363 if (image->colorspace == CMYKColorspace)
6364 {
6365 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6366 histogram[i].black);
6367 PUSHs(sv_2mortal(newSVpv(message,0)));
6368 }
6369 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6370 histogram[i].alpha);
6371 PUSHs(sv_2mortal(newSVpv(message,0)));
6372 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
6373 histogram[i].count);
6374 PUSHs(sv_2mortal(newSVpv(message,0)));
6375 }
6376 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6377 }
6378
6379 PerlException:
6380 InheritPerlException(exception,perl_exception);
6381 exception=DestroyExceptionInfo(exception);
6382 SvREFCNT_dec(perl_exception);
6383 }
6384
6385 #
6386 ###############################################################################
6387 # #
6388 # #
6389 # #
6390 # G e t P i x e l #
6391 # #
6392 # #
6393 # #
6394 ###############################################################################
6395 #
6396 #
6397 void
GetPixel(ref,...)6398 GetPixel(ref,...)
6399 Image::Magick ref=NO_INIT
6400 ALIAS:
6401 getpixel = 1
6402 getPixel = 2
6403 PPCODE:
6404 {
6405 AV
6406 *av;
6407
6408 char
6409 *attribute;
6410
6411 ExceptionInfo
6412 *exception;
6413
6414 Image
6415 *image;
6416
6417 MagickBooleanType
6418 normalize;
6419
6420 RectangleInfo
6421 region;
6422
6423 register const Quantum
6424 *p;
6425
6426 register ssize_t
6427 i;
6428
6429 ssize_t
6430 option;
6431
6432 struct PackageInfo
6433 *info;
6434
6435 SV
6436 *perl_exception,
6437 *reference; /* reference is the SV* of ref=SvIV(reference) */
6438
6439 PERL_UNUSED_VAR(ref);
6440 PERL_UNUSED_VAR(ix);
6441 exception=AcquireExceptionInfo();
6442 perl_exception=newSVpv("",0);
6443 reference=SvRV(ST(0));
6444 av=(AV *) reference;
6445 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6446 exception);
6447 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6448 if (image == (Image *) NULL)
6449 {
6450 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6451 PackageName);
6452 goto PerlException;
6453 }
6454 normalize=MagickTrue;
6455 region.x=0;
6456 region.y=0;
6457 region.width=image->columns;
6458 region.height=1;
6459 if (items == 1)
6460 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion);
6461 for (i=2; i < items; i+=2)
6462 {
6463 attribute=(char *) SvPV(ST(i-1),na);
6464 switch (*attribute)
6465 {
6466 case 'C':
6467 case 'c':
6468 {
6469 if (LocaleCompare(attribute,"channel") == 0)
6470 {
6471 ssize_t
6472 option;
6473
6474 option=ParseChannelOption(SvPV(ST(i),na));
6475 if (option < 0)
6476 {
6477 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6478 SvPV(ST(i),na));
6479 return;
6480 }
6481 (void) SetPixelChannelMask(image,(ChannelType) option);
6482 break;
6483 }
6484 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6485 attribute);
6486 break;
6487 }
6488 case 'g':
6489 case 'G':
6490 {
6491 if (LocaleCompare(attribute,"geometry") == 0)
6492 {
6493 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion);
6494 break;
6495 }
6496 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6497 attribute);
6498 break;
6499 }
6500 case 'N':
6501 case 'n':
6502 {
6503 if (LocaleCompare(attribute,"normalize") == 0)
6504 {
6505 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6506 SvPV(ST(i),na));
6507 if (option < 0)
6508 {
6509 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6510 SvPV(ST(i),na));
6511 break;
6512 }
6513 normalize=option != 0 ? MagickTrue : MagickFalse;
6514 break;
6515 }
6516 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6517 attribute);
6518 break;
6519 }
6520 case 'x':
6521 case 'X':
6522 {
6523 if (LocaleCompare(attribute,"x") == 0)
6524 {
6525 region.x=SvIV(ST(i));
6526 break;
6527 }
6528 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6529 attribute);
6530 break;
6531 }
6532 case 'y':
6533 case 'Y':
6534 {
6535 if (LocaleCompare(attribute,"y") == 0)
6536 {
6537 region.y=SvIV(ST(i));
6538 break;
6539 }
6540 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6541 attribute);
6542 break;
6543 }
6544 default:
6545 {
6546 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6547 attribute);
6548 break;
6549 }
6550 }
6551 }
6552 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6553 if (p == (const Quantum *) NULL)
6554 PUSHs(&sv_undef);
6555 else
6556 {
6557 double
6558 scale;
6559
6560 scale=1.0;
6561 if (normalize != MagickFalse)
6562 scale=1.0/QuantumRange;
6563 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6564 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6565 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6566 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6567 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6568 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6569 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6570 (image->colorspace == CMYKColorspace))
6571 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6572 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6573 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6574 }
6575
6576 PerlException:
6577 InheritPerlException(exception,perl_exception);
6578 exception=DestroyExceptionInfo(exception);
6579 SvREFCNT_dec(perl_exception);
6580 }
6581
6582 #
6583 ###############################################################################
6584 # #
6585 # #
6586 # #
6587 # G e t P i x e l s #
6588 # #
6589 # #
6590 # #
6591 ###############################################################################
6592 #
6593 #
6594 void
GetPixels(ref,...)6595 GetPixels(ref,...)
6596 Image::Magick ref=NO_INIT
6597 ALIAS:
6598 getpixels = 1
6599 getPixels = 2
6600 PPCODE:
6601 {
6602 AV
6603 *av;
6604
6605 char
6606 *attribute;
6607
6608 const char
6609 *map;
6610
6611 ExceptionInfo
6612 *exception;
6613
6614 Image
6615 *image;
6616
6617 MagickBooleanType
6618 normalize,
6619 status;
6620
6621 RectangleInfo
6622 region;
6623
6624 register ssize_t
6625 i;
6626
6627 ssize_t
6628 option;
6629
6630 struct PackageInfo
6631 *info;
6632
6633 SV
6634 *perl_exception,
6635 *reference; /* reference is the SV* of ref=SvIV(reference) */
6636
6637 PERL_UNUSED_VAR(ref);
6638 PERL_UNUSED_VAR(ix);
6639 exception=AcquireExceptionInfo();
6640 perl_exception=newSVpv("",0);
6641 reference=SvRV(ST(0));
6642 av=(AV *) reference;
6643 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6644 exception);
6645 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6646 if (image == (Image *) NULL)
6647 {
6648 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6649 PackageName);
6650 goto PerlException;
6651 }
6652 map="RGB";
6653 if (image->alpha_trait != UndefinedPixelTrait)
6654 map="RGBA";
6655 if (image->colorspace == CMYKColorspace)
6656 {
6657 map="CMYK";
6658 if (image->alpha_trait != UndefinedPixelTrait)
6659 map="CMYKA";
6660 }
6661 normalize=MagickFalse;
6662 region.x=0;
6663 region.y=0;
6664 region.width=image->columns;
6665 region.height=1;
6666 if (items == 1)
6667 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion);
6668 for (i=2; i < items; i+=2)
6669 {
6670 attribute=(char *) SvPV(ST(i-1),na);
6671 switch (*attribute)
6672 {
6673 case 'g':
6674 case 'G':
6675 {
6676 if (LocaleCompare(attribute,"geometry") == 0)
6677 {
6678 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion);
6679 break;
6680 }
6681 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6682 attribute);
6683 break;
6684 }
6685 case 'H':
6686 case 'h':
6687 {
6688 if (LocaleCompare(attribute,"height") == 0)
6689 {
6690 region.height=SvIV(ST(i));
6691 break;
6692 }
6693 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6694 attribute);
6695 break;
6696 }
6697 case 'M':
6698 case 'm':
6699 {
6700 if (LocaleCompare(attribute,"map") == 0)
6701 {
6702 map=SvPV(ST(i),na);
6703 break;
6704 }
6705 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6706 attribute);
6707 break;
6708 }
6709 case 'N':
6710 case 'n':
6711 {
6712 if (LocaleCompare(attribute,"normalize") == 0)
6713 {
6714 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6715 SvPV(ST(i),na));
6716 if (option < 0)
6717 {
6718 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6719 SvPV(ST(i),na));
6720 break;
6721 }
6722 normalize=option != 0 ? MagickTrue : MagickFalse;
6723 break;
6724 }
6725 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6726 attribute);
6727 break;
6728 }
6729 case 'W':
6730 case 'w':
6731 {
6732 if (LocaleCompare(attribute,"width") == 0)
6733 {
6734 region.width=SvIV(ST(i));
6735 break;
6736 }
6737 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6738 attribute);
6739 break;
6740 }
6741 case 'x':
6742 case 'X':
6743 {
6744 if (LocaleCompare(attribute,"x") == 0)
6745 {
6746 region.x=SvIV(ST(i));
6747 break;
6748 }
6749 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6750 attribute);
6751 break;
6752 }
6753 case 'y':
6754 case 'Y':
6755 {
6756 if (LocaleCompare(attribute,"y") == 0)
6757 {
6758 region.y=SvIV(ST(i));
6759 break;
6760 }
6761 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6762 attribute);
6763 break;
6764 }
6765 default:
6766 {
6767 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6768 attribute);
6769 break;
6770 }
6771 }
6772 }
6773 if (normalize != MagickFalse)
6774 {
6775 float
6776 *pixels;
6777
6778 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6779 region.height*sizeof(*pixels));
6780 if (pixels == (float *) NULL)
6781 {
6782 ThrowPerlException(exception,ResourceLimitError,
6783 "MemoryAllocationFailed",PackageName);
6784 goto PerlException;
6785 }
6786 status=ExportImagePixels(image,region.x,region.y,region.width,
6787 region.height,map,FloatPixel,pixels,exception);
6788 if (status == MagickFalse)
6789 PUSHs(&sv_undef);
6790 else
6791 {
6792 EXTEND(sp,strlen(map)*region.width*region.height);
6793 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6794 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6795 }
6796 pixels=(float *) RelinquishMagickMemory(pixels);
6797 }
6798 else
6799 {
6800 Quantum
6801 *pixels;
6802
6803 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6804 region.height*sizeof(*pixels));
6805 if (pixels == (Quantum *) NULL)
6806 {
6807 ThrowPerlException(exception,ResourceLimitError,
6808 "MemoryAllocationFailed",PackageName);
6809 goto PerlException;
6810 }
6811 status=ExportImagePixels(image,region.x,region.y,region.width,
6812 region.height,map,QuantumPixel,pixels,exception);
6813 if (status == MagickFalse)
6814 PUSHs(&sv_undef);
6815 else
6816 {
6817 EXTEND(sp,strlen(map)*region.width*region.height);
6818 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6819 PUSHs(sv_2mortal(newSViv(pixels[i])));
6820 }
6821 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6822 }
6823
6824 PerlException:
6825 InheritPerlException(exception,perl_exception);
6826 exception=DestroyExceptionInfo(exception);
6827 SvREFCNT_dec(perl_exception);
6828 }
6829
6830 #
6831 ###############################################################################
6832 # #
6833 # #
6834 # #
6835 # I m a g e T o B l o b #
6836 # #
6837 # #
6838 # #
6839 ###############################################################################
6840 #
6841 #
6842 void
ImageToBlob(ref,...)6843 ImageToBlob(ref,...)
6844 Image::Magick ref=NO_INIT
6845 ALIAS:
6846 ImageToBlob = 1
6847 imagetoblob = 2
6848 toblob = 3
6849 blob = 4
6850 PPCODE:
6851 {
6852 char
6853 filename[MagickPathExtent];
6854
6855 ExceptionInfo
6856 *exception;
6857
6858 Image
6859 *image,
6860 *next;
6861
6862 register ssize_t
6863 i;
6864
6865 struct PackageInfo
6866 *info,
6867 *package_info;
6868
6869 size_t
6870 length;
6871
6872 ssize_t
6873 scene;
6874
6875 SV
6876 *perl_exception,
6877 *reference;
6878
6879 void
6880 *blob;
6881
6882 PERL_UNUSED_VAR(ref);
6883 PERL_UNUSED_VAR(ix);
6884 exception=AcquireExceptionInfo();
6885 perl_exception=newSVpv("",0);
6886 package_info=(struct PackageInfo *) NULL;
6887 if (sv_isobject(ST(0)) == 0)
6888 {
6889 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6890 PackageName);
6891 goto PerlException;
6892 }
6893 reference=SvRV(ST(0));
6894 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6895 if (image == (Image *) NULL)
6896 {
6897 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6898 PackageName);
6899 goto PerlException;
6900 }
6901 package_info=ClonePackageInfo(info,exception);
6902 for (i=2; i < items; i+=2)
6903 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6904 (void) CopyMagickString(filename,package_info->image_info->filename,
6905 MagickPathExtent);
6906 scene=0;
6907 for (next=image; next; next=next->next)
6908 {
6909 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
6910 next->scene=scene++;
6911 }
6912 SetImageInfo(package_info->image_info,(unsigned int)
6913 GetImageListLength(image),exception);
6914 EXTEND(sp,(ssize_t) GetImageListLength(image));
6915 for ( ; image; image=image->next)
6916 {
6917 length=0;
6918 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6919 if (blob != (char *) NULL)
6920 {
6921 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6922 blob=(unsigned char *) RelinquishMagickMemory(blob);
6923 }
6924 if (package_info->image_info->adjoin)
6925 break;
6926 }
6927
6928 PerlException:
6929 if (package_info != (struct PackageInfo *) NULL)
6930 DestroyPackageInfo(package_info);
6931 InheritPerlException(exception,perl_exception);
6932 exception=DestroyExceptionInfo(exception);
6933 SvREFCNT_dec(perl_exception); /* throw away all errors */
6934 }
6935
6936 #
6937 ###############################################################################
6938 # #
6939 # #
6940 # #
6941 # L a y e r s #
6942 # #
6943 # #
6944 # #
6945 ###############################################################################
6946 #
6947 #
6948 void
Layers(ref,...)6949 Layers(ref,...)
6950 Image::Magick ref=NO_INIT
6951 ALIAS:
6952 Layers = 1
6953 layers = 2
6954 OptimizeImageLayers = 3
6955 optimizelayers = 4
6956 optimizeimagelayers = 5
6957 PPCODE:
6958 {
6959 AV
6960 *av;
6961
6962 char
6963 *attribute;
6964
6965 CompositeOperator
6966 compose;
6967
6968 ExceptionInfo
6969 *exception;
6970
6971 HV
6972 *hv;
6973
6974 Image
6975 *image,
6976 *layers;
6977
6978 LayerMethod
6979 method;
6980
6981 register ssize_t
6982 i;
6983
6984 ssize_t
6985 option,
6986 sp;
6987
6988 struct PackageInfo
6989 *info;
6990
6991 SV
6992 *av_reference,
6993 *perl_exception,
6994 *reference,
6995 *rv,
6996 *sv;
6997
6998 PERL_UNUSED_VAR(ref);
6999 PERL_UNUSED_VAR(ix);
7000 exception=AcquireExceptionInfo();
7001 perl_exception=newSVpv("",0);
7002 sv=NULL;
7003 if (sv_isobject(ST(0)) == 0)
7004 {
7005 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7006 PackageName);
7007 goto PerlException;
7008 }
7009 reference=SvRV(ST(0));
7010 hv=SvSTASH(reference);
7011 av=newAV();
7012 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7013 SvREFCNT_dec(av);
7014 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7015 if (image == (Image *) NULL)
7016 {
7017 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7018 PackageName);
7019 goto PerlException;
7020 }
7021 compose=image->compose;
7022 method=OptimizeLayer;
7023 for (i=2; i < items; i+=2)
7024 {
7025 attribute=(char *) SvPV(ST(i-1),na);
7026 switch (*attribute)
7027 {
7028 case 'C':
7029 case 'c':
7030 {
7031 if (LocaleCompare(attribute,"compose") == 0)
7032 {
7033 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7034 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7035 if (sp < 0)
7036 {
7037 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7038 SvPV(ST(i),na));
7039 break;
7040 }
7041 compose=(CompositeOperator) sp;
7042 break;
7043 }
7044 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7045 attribute);
7046 break;
7047 }
7048 case 'M':
7049 case 'm':
7050 {
7051 if (LocaleCompare(attribute,"method") == 0)
7052 {
7053 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7054 SvPV(ST(i),na));
7055 if (option < 0)
7056 {
7057 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7058 SvPV(ST(i),na));
7059 break;
7060 }
7061 method=(LayerMethod) option;
7062 break;
7063 }
7064 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7065 attribute);
7066 break;
7067 }
7068 default:
7069 {
7070 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7071 attribute);
7072 break;
7073 }
7074 }
7075 }
7076 layers=(Image *) NULL;
7077 switch (method)
7078 {
7079 case CompareAnyLayer:
7080 case CompareClearLayer:
7081 case CompareOverlayLayer:
7082 default:
7083 {
7084 layers=CompareImagesLayers(image,method,exception);
7085 break;
7086 }
7087 case MergeLayer:
7088 case FlattenLayer:
7089 case MosaicLayer:
7090 {
7091 layers=MergeImageLayers(image,method,exception);
7092 break;
7093 }
7094 case DisposeLayer:
7095 {
7096 layers=DisposeImages(image,exception);
7097 break;
7098 }
7099 case OptimizeImageLayer:
7100 {
7101 layers=OptimizeImageLayers(image,exception);
7102 break;
7103 }
7104 case OptimizePlusLayer:
7105 {
7106 layers=OptimizePlusImageLayers(image,exception);
7107 break;
7108 }
7109 case OptimizeTransLayer:
7110 {
7111 OptimizeImageTransparency(image,exception);
7112 break;
7113 }
7114 case RemoveDupsLayer:
7115 {
7116 RemoveDuplicateLayers(&image,exception);
7117 break;
7118 }
7119 case RemoveZeroLayer:
7120 {
7121 RemoveZeroDelayLayers(&image,exception);
7122 break;
7123 }
7124 case OptimizeLayer:
7125 {
7126 QuantizeInfo
7127 *quantize_info;
7128
7129 /*
7130 General Purpose, GIF Animation Optimizer.
7131 */
7132 layers=CoalesceImages(image,exception);
7133 if (layers == (Image *) NULL)
7134 break;
7135 image=layers;
7136 layers=OptimizeImageLayers(image,exception);
7137 if (layers == (Image *) NULL)
7138 break;
7139 image=DestroyImageList(image);
7140 image=layers;
7141 layers=(Image *) NULL;
7142 OptimizeImageTransparency(image,exception);
7143 quantize_info=AcquireQuantizeInfo(info->image_info);
7144 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7145 quantize_info=DestroyQuantizeInfo(quantize_info);
7146 break;
7147 }
7148 case CompositeLayer:
7149 {
7150 Image
7151 *source;
7152
7153 RectangleInfo
7154 geometry;
7155
7156 /*
7157 Split image sequence at the first 'NULL:' image.
7158 */
7159 source=image;
7160 while (source != (Image *) NULL)
7161 {
7162 source=GetNextImageInList(source);
7163 if ((source != (Image *) NULL) &&
7164 (LocaleCompare(source->magick,"NULL") == 0))
7165 break;
7166 }
7167 if (source != (Image *) NULL)
7168 {
7169 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7170 (GetNextImageInList(source) == (Image *) NULL))
7171 source=(Image *) NULL;
7172 else
7173 {
7174 /*
7175 Separate the two lists, junk the null: image.
7176 */
7177 source=SplitImageList(source->previous);
7178 DeleteImageFromList(&source);
7179 }
7180 }
7181 if (source == (Image *) NULL)
7182 {
7183 (void) ThrowMagickException(exception,GetMagickModule(),
7184 OptionError,"MissingNullSeparator","layers Composite");
7185 break;
7186 }
7187 /*
7188 Adjust offset with gravity and virtual canvas.
7189 */
7190 SetGeometry(image,&geometry);
7191 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7192 geometry.width=source->page.width != 0 ? source->page.width :
7193 source->columns;
7194 geometry.height=source->page.height != 0 ? source->page.height :
7195 source->rows;
7196 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7197 image->columns,image->page.height != 0 ? image->page.height :
7198 image->rows,image->gravity,&geometry);
7199 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7200 source=DestroyImageList(source);
7201 break;
7202 }
7203 }
7204 if (layers != (Image *) NULL)
7205 image=layers;
7206 else
7207 image=CloneImage(image,0,0,MagickTrue,exception);
7208 if (image == (Image *) NULL)
7209 goto PerlException;
7210 for ( ; image; image=image->next)
7211 {
7212 AddImageToRegistry(sv,image);
7213 rv=newRV(sv);
7214 av_push(av,sv_bless(rv,hv));
7215 SvREFCNT_dec(sv);
7216 }
7217 exception=DestroyExceptionInfo(exception);
7218 ST(0)=av_reference;
7219 SvREFCNT_dec(perl_exception);
7220 XSRETURN(1);
7221
7222 PerlException:
7223 InheritPerlException(exception,perl_exception);
7224 exception=DestroyExceptionInfo(exception);
7225 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7226 SvPOK_on(perl_exception);
7227 ST(0)=sv_2mortal(perl_exception);
7228 XSRETURN(1);
7229 }
7230
7231 #
7232 ###############################################################################
7233 # #
7234 # #
7235 # #
7236 # M a g i c k T o M i m e #
7237 # #
7238 # #
7239 # #
7240 ###############################################################################
7241 #
7242 #
7243 SV *
MagickToMime(ref,name)7244 MagickToMime(ref,name)
7245 Image::Magick ref=NO_INIT
7246 char *name
7247 ALIAS:
7248 magicktomime = 1
7249 CODE:
7250 {
7251 char
7252 *mime;
7253
7254 PERL_UNUSED_VAR(ref);
7255 PERL_UNUSED_VAR(ix);
7256 mime=MagickToMime(name);
7257 RETVAL=newSVpv(mime,0);
7258 mime=(char *) RelinquishMagickMemory(mime);
7259 }
7260 OUTPUT:
7261 RETVAL
7262
7263 #
7264 ###############################################################################
7265 # #
7266 # #
7267 # #
7268 # M o g r i f y #
7269 # #
7270 # #
7271 # #
7272 ###############################################################################
7273 #
7274 #
7275 void
Mogrify(ref,...)7276 Mogrify(ref,...)
7277 Image::Magick ref=NO_INIT
7278 ALIAS:
7279 Comment = 1
7280 CommentImage = 2
7281 Label = 3
7282 LabelImage = 4
7283 AddNoise = 5
7284 AddNoiseImage = 6
7285 Colorize = 7
7286 ColorizeImage = 8
7287 Border = 9
7288 BorderImage = 10
7289 Blur = 11
7290 BlurImage = 12
7291 Chop = 13
7292 ChopImage = 14
7293 Crop = 15
7294 CropImage = 16
7295 Despeckle = 17
7296 DespeckleImage = 18
7297 Edge = 19
7298 EdgeImage = 20
7299 Emboss = 21
7300 EmbossImage = 22
7301 Enhance = 23
7302 EnhanceImage = 24
7303 Flip = 25
7304 FlipImage = 26
7305 Flop = 27
7306 FlopImage = 28
7307 Frame = 29
7308 FrameImage = 30
7309 Implode = 31
7310 ImplodeImage = 32
7311 Magnify = 33
7312 MagnifyImage = 34
7313 MedianFilter = 35
7314 MedianConvolveImage = 36
7315 Minify = 37
7316 MinifyImage = 38
7317 OilPaint = 39
7318 OilPaintImage = 40
7319 ReduceNoise = 41
7320 ReduceNoiseImage = 42
7321 Roll = 43
7322 RollImage = 44
7323 Rotate = 45
7324 RotateImage = 46
7325 Sample = 47
7326 SampleImage = 48
7327 Scale = 49
7328 ScaleImage = 50
7329 Shade = 51
7330 ShadeImage = 52
7331 Sharpen = 53
7332 SharpenImage = 54
7333 Shear = 55
7334 ShearImage = 56
7335 Spread = 57
7336 SpreadImage = 58
7337 Swirl = 59
7338 SwirlImage = 60
7339 Resize = 61
7340 ResizeImage = 62
7341 Zoom = 63
7342 ZoomImage = 64
7343 Annotate = 65
7344 AnnotateImage = 66
7345 ColorFloodfill = 67
7346 ColorFloodfillImage= 68
7347 Composite = 69
7348 CompositeImage = 70
7349 Contrast = 71
7350 ContrastImage = 72
7351 CycleColormap = 73
7352 CycleColormapImage = 74
7353 Draw = 75
7354 DrawImage = 76
7355 Equalize = 77
7356 EqualizeImage = 78
7357 Gamma = 79
7358 GammaImage = 80
7359 Map = 81
7360 MapImage = 82
7361 MatteFloodfill = 83
7362 MatteFloodfillImage= 84
7363 Modulate = 85
7364 ModulateImage = 86
7365 Negate = 87
7366 NegateImage = 88
7367 Normalize = 89
7368 NormalizeImage = 90
7369 NumberColors = 91
7370 NumberColorsImage = 92
7371 Opaque = 93
7372 OpaqueImage = 94
7373 Quantize = 95
7374 QuantizeImage = 96
7375 Raise = 97
7376 RaiseImage = 98
7377 Segment = 99
7378 SegmentImage = 100
7379 Signature = 101
7380 SignatureImage = 102
7381 Solarize = 103
7382 SolarizeImage = 104
7383 Sync = 105
7384 SyncImage = 106
7385 Texture = 107
7386 TextureImage = 108
7387 Evaluate = 109
7388 EvaluateImage = 110
7389 Transparent = 111
7390 TransparentImage = 112
7391 Threshold = 113
7392 ThresholdImage = 114
7393 Charcoal = 115
7394 CharcoalImage = 116
7395 Trim = 117
7396 TrimImage = 118
7397 Wave = 119
7398 WaveImage = 120
7399 Separate = 121
7400 SeparateImage = 122
7401 Stereo = 125
7402 StereoImage = 126
7403 Stegano = 127
7404 SteganoImage = 128
7405 Deconstruct = 129
7406 DeconstructImage = 130
7407 GaussianBlur = 131
7408 GaussianBlurImage = 132
7409 Convolve = 133
7410 ConvolveImage = 134
7411 Profile = 135
7412 ProfileImage = 136
7413 UnsharpMask = 137
7414 UnsharpMaskImage = 138
7415 MotionBlur = 139
7416 MotionBlurImage = 140
7417 OrderedDither = 141
7418 OrderedDitherImage = 142
7419 Shave = 143
7420 ShaveImage = 144
7421 Level = 145
7422 LevelImage = 146
7423 Clip = 147
7424 ClipImage = 148
7425 AffineTransform = 149
7426 AffineTransformImage = 150
7427 Difference = 151
7428 DifferenceImage = 152
7429 AdaptiveThreshold = 153
7430 AdaptiveThresholdImage = 154
7431 Resample = 155
7432 ResampleImage = 156
7433 Describe = 157
7434 DescribeImage = 158
7435 BlackThreshold = 159
7436 BlackThresholdImage= 160
7437 WhiteThreshold = 161
7438 WhiteThresholdImage= 162
7439 RotationalBlur = 163
7440 RotationalBlurImage= 164
7441 Thumbnail = 165
7442 ThumbnailImage = 166
7443 Strip = 167
7444 StripImage = 168
7445 Tint = 169
7446 TintImage = 170
7447 Channel = 171
7448 ChannelImage = 172
7449 Splice = 173
7450 SpliceImage = 174
7451 Posterize = 175
7452 PosterizeImage = 176
7453 Shadow = 177
7454 ShadowImage = 178
7455 Identify = 179
7456 IdentifyImage = 180
7457 SepiaTone = 181
7458 SepiaToneImage = 182
7459 SigmoidalContrast = 183
7460 SigmoidalContrastImage = 184
7461 Extent = 185
7462 ExtentImage = 186
7463 Vignette = 187
7464 VignetteImage = 188
7465 ContrastStretch = 189
7466 ContrastStretchImage = 190
7467 Sans0 = 191
7468 Sans0Image = 192
7469 Sans1 = 193
7470 Sans1Image = 194
7471 AdaptiveSharpen = 195
7472 AdaptiveSharpenImage = 196
7473 Transpose = 197
7474 TransposeImage = 198
7475 Transverse = 199
7476 TransverseImage = 200
7477 AutoOrient = 201
7478 AutoOrientImage = 202
7479 AdaptiveBlur = 203
7480 AdaptiveBlurImage = 204
7481 Sketch = 205
7482 SketchImage = 206
7483 UniqueColors = 207
7484 UniqueColorsImage = 208
7485 AdaptiveResize = 209
7486 AdaptiveResizeImage= 210
7487 ClipMask = 211
7488 ClipMaskImage = 212
7489 LinearStretch = 213
7490 LinearStretchImage = 214
7491 ColorMatrix = 215
7492 ColorMatrixImage = 216
7493 Mask = 217
7494 MaskImage = 218
7495 Polaroid = 219
7496 PolaroidImage = 220
7497 FloodfillPaint = 221
7498 FloodfillPaintImage= 222
7499 Distort = 223
7500 DistortImage = 224
7501 Clut = 225
7502 ClutImage = 226
7503 LiquidRescale = 227
7504 LiquidRescaleImage = 228
7505 Encipher = 229
7506 EncipherImage = 230
7507 Decipher = 231
7508 DecipherImage = 232
7509 Deskew = 233
7510 DeskewImage = 234
7511 Remap = 235
7512 RemapImage = 236
7513 SparseColor = 237
7514 SparseColorImage = 238
7515 Function = 239
7516 FunctionImage = 240
7517 SelectiveBlur = 241
7518 SelectiveBlurImage = 242
7519 HaldClut = 243
7520 HaldClutImage = 244
7521 BlueShift = 245
7522 BlueShiftImage = 246
7523 ForwardFourierTransform = 247
7524 ForwardFourierTransformImage = 248
7525 InverseFourierTransform = 249
7526 InverseFourierTransformImage = 250
7527 ColorDecisionList = 251
7528 ColorDecisionListImage = 252
7529 AutoGamma = 253
7530 AutoGammaImage = 254
7531 AutoLevel = 255
7532 AutoLevelImage = 256
7533 LevelColors = 257
7534 LevelImageColors = 258
7535 Clamp = 259
7536 ClampImage = 260
7537 BrightnessContrast = 261
7538 BrightnessContrastImage = 262
7539 Morphology = 263
7540 MorphologyImage = 264
7541 Mode = 265
7542 ModeImage = 266
7543 Statistic = 267
7544 StatisticImage = 268
7545 Perceptible = 269
7546 PerceptibleImage = 270
7547 Poly = 271
7548 PolyImage = 272
7549 Grayscale = 273
7550 GrayscaleImage = 274
7551 CannyEdge = 275
7552 CannyEdgeImage = 276
7553 HoughLine = 277
7554 HoughLineImage = 278
7555 MeanShift = 279
7556 MeanShiftImage = 280
7557 Kuwahara = 281
7558 KuwaharaImage = 282
7559 ConnectedComponent = 283
7560 ConnectedComponentImage = 284
7561 CopyPixels = 285
7562 CopyImagePixels = 286
7563 Color = 287
7564 ColorImage = 288
7565 WaveletDenoise = 289
7566 WaveletDenoiseImage= 290
7567 MogrifyRegion = 666
7568 PPCODE:
7569 {
7570 AffineMatrix
7571 affine,
7572 current;
7573
7574 char
7575 attribute_flag[MaxArguments],
7576 message[MagickPathExtent];
7577
7578 ChannelType
7579 channel,
7580 channel_mask;
7581
7582 CompositeOperator
7583 compose;
7584
7585 const char
7586 *attribute,
7587 *value;
7588
7589 double
7590 angle;
7591
7592 ExceptionInfo
7593 *exception;
7594
7595 GeometryInfo
7596 geometry_info;
7597
7598 Image
7599 *image,
7600 *next,
7601 *region_image;
7602
7603 MagickBooleanType
7604 status;
7605
7606 MagickStatusType
7607 flags;
7608
7609 PixelInfo
7610 fill_color;
7611
7612 RectangleInfo
7613 geometry,
7614 region_info;
7615
7616 register ssize_t
7617 i;
7618
7619 ssize_t
7620 base,
7621 j,
7622 number_images;
7623
7624 struct Methods
7625 *rp;
7626
7627 struct PackageInfo
7628 *info;
7629
7630 SV
7631 *perl_exception,
7632 **pv,
7633 *reference,
7634 **reference_vector;
7635
7636 struct ArgumentList
7637 argument_list[MaxArguments];
7638
7639 PERL_UNUSED_VAR(ref);
7640 PERL_UNUSED_VAR(ix);
7641 exception=AcquireExceptionInfo();
7642 perl_exception=newSVpv("",0);
7643 reference_vector=NULL;
7644 region_image=NULL;
7645 number_images=0;
7646 base=2;
7647 if (sv_isobject(ST(0)) == 0)
7648 {
7649 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7650 PackageName);
7651 goto PerlException;
7652 }
7653 reference=SvRV(ST(0));
7654 region_info.width=0;
7655 region_info.height=0;
7656 region_info.x=0;
7657 region_info.y=0;
7658 region_image=(Image *) NULL;
7659 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7660 if (ix && (ix != 666))
7661 {
7662 /*
7663 Called as Method(...)
7664 */
7665 ix=(ix+1)/2;
7666 rp=(&Methods[ix-1]);
7667 attribute=rp->name;
7668 }
7669 else
7670 {
7671 /*
7672 Called as Mogrify("Method",...)
7673 */
7674 attribute=(char *) SvPV(ST(1),na);
7675 if (ix)
7676 {
7677 flags=ParseGravityGeometry(image,attribute,®ion_info,exception);
7678 attribute=(char *) SvPV(ST(2),na);
7679 base++;
7680 }
7681 for (rp=Methods; ; rp++)
7682 {
7683 if (rp >= EndOf(Methods))
7684 {
7685 ThrowPerlException(exception,OptionError,
7686 "UnrecognizedPerlMagickMethod",attribute);
7687 goto PerlException;
7688 }
7689 if (strEQcase(attribute,rp->name))
7690 break;
7691 }
7692 ix=rp-Methods+1;
7693 base++;
7694 }
7695 if (image == (Image *) NULL)
7696 {
7697 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7698 goto PerlException;
7699 }
7700 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7701 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7702 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7703 {
7704 Arguments
7705 *pp,
7706 *qq;
7707
7708 ssize_t
7709 ssize_test;
7710
7711 struct ArgumentList
7712 *al;
7713
7714 SV
7715 *sv;
7716
7717 sv=NULL;
7718 ssize_test=0;
7719 pp=(Arguments *) NULL;
7720 qq=rp->arguments;
7721 if (i == items)
7722 {
7723 pp=rp->arguments,
7724 sv=ST(i-1);
7725 }
7726 else
7727 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7728 {
7729 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7730 break;
7731 if (strEQcase(attribute,qq->method) > ssize_test)
7732 {
7733 pp=qq;
7734 ssize_test=strEQcase(attribute,qq->method);
7735 }
7736 }
7737 if (pp == (Arguments *) NULL)
7738 {
7739 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7740 attribute);
7741 goto continue_outer_loop;
7742 }
7743 al=(&argument_list[pp-rp->arguments]);
7744 switch (pp->type)
7745 {
7746 case ArrayReference:
7747 {
7748 if (SvTYPE(sv) != SVt_RV)
7749 {
7750 (void) FormatLocaleString(message,MagickPathExtent,
7751 "invalid %.60s value",pp->method);
7752 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7753 goto continue_outer_loop;
7754 }
7755 al->array_reference=SvRV(sv);
7756 break;
7757 }
7758 case RealReference:
7759 {
7760 al->real_reference=SvNV(sv);
7761 break;
7762 }
7763 case FileReference:
7764 {
7765 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7766 break;
7767 }
7768 case ImageReference:
7769 {
7770 if (!sv_isobject(sv) ||
7771 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7772 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7773 {
7774 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7775 PackageName);
7776 goto PerlException;
7777 }
7778 break;
7779 }
7780 case IntegerReference:
7781 {
7782 al->integer_reference=SvIV(sv);
7783 break;
7784 }
7785 case StringReference:
7786 {
7787 al->string_reference=(char *) SvPV(sv,al->length);
7788 if (sv_isobject(sv))
7789 al->image_reference=SetupList(aTHX_ SvRV(sv),
7790 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7791 break;
7792 }
7793 default:
7794 {
7795 /*
7796 Is a string; look up name.
7797 */
7798 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7799 {
7800 al->string_reference=(char *) SvPV(sv,al->length);
7801 al->integer_reference=(-1);
7802 break;
7803 }
7804 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7805 MagickFalse,SvPV(sv,na));
7806 if (pp->type == MagickChannelOptions)
7807 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7808 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7809 {
7810 (void) FormatLocaleString(message,MagickPathExtent,
7811 "invalid %.60s value",pp->method);
7812 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7813 goto continue_outer_loop;
7814 }
7815 break;
7816 }
7817 }
7818 attribute_flag[pp-rp->arguments]++;
7819 continue_outer_loop: ;
7820 }
7821 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7822 pv=reference_vector;
7823 SetGeometryInfo(&geometry_info);
7824 channel=DefaultChannels;
7825 for (next=image; next; next=next->next)
7826 {
7827 image=next;
7828 SetGeometry(image,&geometry);
7829 if ((region_info.width*region_info.height) != 0)
7830 {
7831 region_image=image;
7832 image=CropImage(image,®ion_info,exception);
7833 }
7834 switch (ix)
7835 {
7836 default:
7837 {
7838 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
7839 ThrowPerlException(exception,OptionError,
7840 "UnrecognizedPerlMagickMethod",message);
7841 goto PerlException;
7842 }
7843 case 1: /* Comment */
7844 {
7845 if (attribute_flag[0] == 0)
7846 argument_list[0].string_reference=(char *) NULL;
7847 (void) SetImageProperty(image,"comment",InterpretImageProperties(
7848 info ? info->image_info : (ImageInfo *) NULL,image,
7849 argument_list[0].string_reference,exception),exception);
7850 break;
7851 }
7852 case 2: /* Label */
7853 {
7854 if (attribute_flag[0] == 0)
7855 argument_list[0].string_reference=(char *) NULL;
7856 (void) SetImageProperty(image,"label",InterpretImageProperties(
7857 info ? info->image_info : (ImageInfo *) NULL,image,
7858 argument_list[0].string_reference,exception),exception);
7859 break;
7860 }
7861 case 3: /* AddNoise */
7862 {
7863 double
7864 attenuate;
7865
7866 if (attribute_flag[0] == 0)
7867 argument_list[0].integer_reference=UniformNoise;
7868 attenuate=1.0;
7869 if (attribute_flag[1] != 0)
7870 attenuate=argument_list[1].real_reference;
7871 if (attribute_flag[2] != 0)
7872 channel=(ChannelType) argument_list[2].integer_reference;
7873 channel_mask=SetImageChannelMask(image,channel);
7874 image=AddNoiseImage(image,(NoiseType)
7875 argument_list[0].integer_reference,attenuate,exception);
7876 if (image != (Image *) NULL)
7877 (void) SetImageChannelMask(image,channel_mask);
7878 break;
7879 }
7880 case 4: /* Colorize */
7881 {
7882 PixelInfo
7883 target;
7884
7885 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7886 0,0,&target,exception);
7887 if (attribute_flag[0] != 0)
7888 (void) QueryColorCompliance(argument_list[0].string_reference,
7889 AllCompliance,&target,exception);
7890 if (attribute_flag[1] == 0)
7891 argument_list[1].string_reference="100%";
7892 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7893 exception);
7894 break;
7895 }
7896 case 5: /* Border */
7897 {
7898 CompositeOperator
7899 compose;
7900
7901 geometry.width=0;
7902 geometry.height=0;
7903 if (attribute_flag[0] != 0)
7904 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7905 &geometry,exception);
7906 if (attribute_flag[1] != 0)
7907 geometry.width=argument_list[1].integer_reference;
7908 if (attribute_flag[2] != 0)
7909 geometry.height=argument_list[2].integer_reference;
7910 if (attribute_flag[3] != 0)
7911 QueryColorCompliance(argument_list[3].string_reference,
7912 AllCompliance,&image->border_color,exception);
7913 if (attribute_flag[4] != 0)
7914 QueryColorCompliance(argument_list[4].string_reference,
7915 AllCompliance,&image->border_color,exception);
7916 if (attribute_flag[5] != 0)
7917 QueryColorCompliance(argument_list[5].string_reference,
7918 AllCompliance,&image->border_color,exception);
7919 compose=image->compose;
7920 if (attribute_flag[6] != 0)
7921 compose=(CompositeOperator) argument_list[6].integer_reference;
7922 image=BorderImage(image,&geometry,compose,exception);
7923 break;
7924 }
7925 case 6: /* Blur */
7926 {
7927 if (attribute_flag[0] != 0)
7928 {
7929 flags=ParseGeometry(argument_list[0].string_reference,
7930 &geometry_info);
7931 if ((flags & SigmaValue) == 0)
7932 geometry_info.sigma=1.0;
7933 }
7934 if (attribute_flag[1] != 0)
7935 geometry_info.rho=argument_list[1].real_reference;
7936 if (attribute_flag[2] != 0)
7937 geometry_info.sigma=argument_list[2].real_reference;
7938 if (attribute_flag[3] != 0)
7939 channel=(ChannelType) argument_list[3].integer_reference;
7940 channel_mask=SetImageChannelMask(image,channel);
7941 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7942 exception);
7943 if (image != (Image *) NULL)
7944 (void) SetImageChannelMask(image,channel_mask);
7945 break;
7946 }
7947 case 7: /* Chop */
7948 {
7949 if (attribute_flag[5] != 0)
7950 image->gravity=(GravityType) argument_list[5].integer_reference;
7951 if (attribute_flag[0] != 0)
7952 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7953 &geometry,exception);
7954 if (attribute_flag[1] != 0)
7955 geometry.width=argument_list[1].integer_reference;
7956 if (attribute_flag[2] != 0)
7957 geometry.height=argument_list[2].integer_reference;
7958 if (attribute_flag[3] != 0)
7959 geometry.x=argument_list[3].integer_reference;
7960 if (attribute_flag[4] != 0)
7961 geometry.y=argument_list[4].integer_reference;
7962 image=ChopImage(image,&geometry,exception);
7963 break;
7964 }
7965 case 8: /* Crop */
7966 {
7967 if (attribute_flag[6] != 0)
7968 image->gravity=(GravityType) argument_list[6].integer_reference;
7969 if (attribute_flag[0] != 0)
7970 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7971 &geometry,exception);
7972 if (attribute_flag[1] != 0)
7973 geometry.width=argument_list[1].integer_reference;
7974 if (attribute_flag[2] != 0)
7975 geometry.height=argument_list[2].integer_reference;
7976 if (attribute_flag[3] != 0)
7977 geometry.x=argument_list[3].integer_reference;
7978 if (attribute_flag[4] != 0)
7979 geometry.y=argument_list[4].integer_reference;
7980 if (attribute_flag[5] != 0)
7981 image->fuzz=StringToDoubleInterval(
7982 argument_list[5].string_reference,(double) QuantumRange+1.0);
7983 image=CropImage(image,&geometry,exception);
7984 break;
7985 }
7986 case 9: /* Despeckle */
7987 {
7988 image=DespeckleImage(image,exception);
7989 break;
7990 }
7991 case 10: /* Edge */
7992 {
7993 if (attribute_flag[0] != 0)
7994 geometry_info.rho=argument_list[0].real_reference;
7995 image=EdgeImage(image,geometry_info.rho,exception);
7996 break;
7997 }
7998 case 11: /* Emboss */
7999 {
8000 if (attribute_flag[0] != 0)
8001 {
8002 flags=ParseGeometry(argument_list[0].string_reference,
8003 &geometry_info);
8004 if ((flags & SigmaValue) == 0)
8005 geometry_info.sigma=1.0;
8006 }
8007 if (attribute_flag[1] != 0)
8008 geometry_info.rho=argument_list[1].real_reference;
8009 if (attribute_flag[2] != 0)
8010 geometry_info.sigma=argument_list[2].real_reference;
8011 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8012 exception);
8013 break;
8014 }
8015 case 12: /* Enhance */
8016 {
8017 image=EnhanceImage(image,exception);
8018 break;
8019 }
8020 case 13: /* Flip */
8021 {
8022 image=FlipImage(image,exception);
8023 break;
8024 }
8025 case 14: /* Flop */
8026 {
8027 image=FlopImage(image,exception);
8028 break;
8029 }
8030 case 15: /* Frame */
8031 {
8032 CompositeOperator
8033 compose;
8034
8035 FrameInfo
8036 frame_info;
8037
8038 if (attribute_flag[0] != 0)
8039 {
8040 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8041 &geometry,exception);
8042 frame_info.width=geometry.width;
8043 frame_info.height=geometry.height;
8044 frame_info.outer_bevel=geometry.x;
8045 frame_info.inner_bevel=geometry.y;
8046 }
8047 if (attribute_flag[1] != 0)
8048 frame_info.width=argument_list[1].integer_reference;
8049 if (attribute_flag[2] != 0)
8050 frame_info.height=argument_list[2].integer_reference;
8051 if (attribute_flag[3] != 0)
8052 frame_info.inner_bevel=argument_list[3].integer_reference;
8053 if (attribute_flag[4] != 0)
8054 frame_info.outer_bevel=argument_list[4].integer_reference;
8055 if (attribute_flag[5] != 0)
8056 QueryColorCompliance(argument_list[5].string_reference,
8057 AllCompliance,&fill_color,exception);
8058 if (attribute_flag[6] != 0)
8059 QueryColorCompliance(argument_list[6].string_reference,
8060 AllCompliance,&fill_color,exception);
8061 frame_info.x=(ssize_t) frame_info.width;
8062 frame_info.y=(ssize_t) frame_info.height;
8063 frame_info.width=image->columns+2*frame_info.x;
8064 frame_info.height=image->rows+2*frame_info.y;
8065 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
8066 image->alpha_color=fill_color;
8067 compose=image->compose;
8068 if (attribute_flag[7] != 0)
8069 compose=(CompositeOperator) argument_list[7].integer_reference;
8070 image=FrameImage(image,&frame_info,compose,exception);
8071 break;
8072 }
8073 case 16: /* Implode */
8074 {
8075 PixelInterpolateMethod
8076 method;
8077
8078 if (attribute_flag[0] == 0)
8079 argument_list[0].real_reference=0.5;
8080 method=UndefinedInterpolatePixel;
8081 if (attribute_flag[1] != 0)
8082 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8083 image=ImplodeImage(image,argument_list[0].real_reference,
8084 method,exception);
8085 break;
8086 }
8087 case 17: /* Magnify */
8088 {
8089 image=MagnifyImage(image,exception);
8090 break;
8091 }
8092 case 18: /* MedianFilter */
8093 {
8094 if (attribute_flag[0] != 0)
8095 {
8096 flags=ParseGeometry(argument_list[0].string_reference,
8097 &geometry_info);
8098 if ((flags & SigmaValue) == 0)
8099 geometry_info.sigma=geometry_info.rho;
8100 }
8101 if (attribute_flag[1] != 0)
8102 geometry_info.rho=argument_list[1].real_reference;
8103 if (attribute_flag[2] != 0)
8104 geometry_info.sigma=argument_list[2].real_reference;
8105 if (attribute_flag[3] != 0)
8106 channel=(ChannelType) argument_list[3].integer_reference;
8107 channel_mask=SetImageChannelMask(image,channel);
8108 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8109 (size_t) geometry_info.sigma,exception);
8110 if (image != (Image *) NULL)
8111 (void) SetImageChannelMask(image,channel_mask);
8112 break;
8113 }
8114 case 19: /* Minify */
8115 {
8116 image=MinifyImage(image,exception);
8117 break;
8118 }
8119 case 20: /* OilPaint */
8120 {
8121 if (attribute_flag[0] == 0)
8122 argument_list[0].real_reference=0.0;
8123 if (attribute_flag[1] == 0)
8124 argument_list[1].real_reference=1.0;
8125 image=OilPaintImage(image,argument_list[0].real_reference,
8126 argument_list[1].real_reference,exception);
8127 break;
8128 }
8129 case 21: /* ReduceNoise */
8130 {
8131 if (attribute_flag[0] != 0)
8132 {
8133 flags=ParseGeometry(argument_list[0].string_reference,
8134 &geometry_info);
8135 if ((flags & SigmaValue) == 0)
8136 geometry_info.sigma=1.0;
8137 }
8138 if (attribute_flag[1] != 0)
8139 geometry_info.rho=argument_list[1].real_reference;
8140 if (attribute_flag[2] != 0)
8141 geometry_info.sigma=argument_list[2].real_reference;
8142 if (attribute_flag[3] != 0)
8143 channel=(ChannelType) argument_list[3].integer_reference;
8144 channel_mask=SetImageChannelMask(image,channel);
8145 image=StatisticImage(image,NonpeakStatistic,(size_t)
8146 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8147 if (image != (Image *) NULL)
8148 (void) SetImageChannelMask(image,channel_mask);
8149 break;
8150 }
8151 case 22: /* Roll */
8152 {
8153 if (attribute_flag[0] != 0)
8154 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8155 &geometry,exception);
8156 if (attribute_flag[1] != 0)
8157 geometry.x=argument_list[1].integer_reference;
8158 if (attribute_flag[2] != 0)
8159 geometry.y=argument_list[2].integer_reference;
8160 image=RollImage(image,geometry.x,geometry.y,exception);
8161 break;
8162 }
8163 case 23: /* Rotate */
8164 {
8165 if (attribute_flag[0] == 0)
8166 argument_list[0].real_reference=90.0;
8167 if (attribute_flag[1] != 0)
8168 {
8169 QueryColorCompliance(argument_list[1].string_reference,
8170 AllCompliance,&image->background_color,exception);
8171 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8172 (image->alpha_trait == UndefinedPixelTrait))
8173 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8174 }
8175 image=RotateImage(image,argument_list[0].real_reference,exception);
8176 break;
8177 }
8178 case 24: /* Sample */
8179 {
8180 if (attribute_flag[0] != 0)
8181 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8182 &geometry,exception);
8183 if (attribute_flag[1] != 0)
8184 geometry.width=argument_list[1].integer_reference;
8185 if (attribute_flag[2] != 0)
8186 geometry.height=argument_list[2].integer_reference;
8187 image=SampleImage(image,geometry.width,geometry.height,exception);
8188 break;
8189 }
8190 case 25: /* Scale */
8191 {
8192 if (attribute_flag[0] != 0)
8193 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8194 &geometry,exception);
8195 if (attribute_flag[1] != 0)
8196 geometry.width=argument_list[1].integer_reference;
8197 if (attribute_flag[2] != 0)
8198 geometry.height=argument_list[2].integer_reference;
8199 image=ScaleImage(image,geometry.width,geometry.height,exception);
8200 break;
8201 }
8202 case 26: /* Shade */
8203 {
8204 if (attribute_flag[0] != 0)
8205 {
8206 flags=ParseGeometry(argument_list[0].string_reference,
8207 &geometry_info);
8208 if ((flags & SigmaValue) == 0)
8209 geometry_info.sigma=0.0;
8210 }
8211 if (attribute_flag[1] != 0)
8212 geometry_info.rho=argument_list[1].real_reference;
8213 if (attribute_flag[2] != 0)
8214 geometry_info.sigma=argument_list[2].real_reference;
8215 image=ShadeImage(image,
8216 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8217 geometry_info.rho,geometry_info.sigma,exception);
8218 break;
8219 }
8220 case 27: /* Sharpen */
8221 {
8222 if (attribute_flag[0] != 0)
8223 {
8224 flags=ParseGeometry(argument_list[0].string_reference,
8225 &geometry_info);
8226 if ((flags & SigmaValue) == 0)
8227 geometry_info.sigma=1.0;
8228 }
8229 if (attribute_flag[1] != 0)
8230 geometry_info.rho=argument_list[1].real_reference;
8231 if (attribute_flag[2] != 0)
8232 geometry_info.sigma=argument_list[2].real_reference;
8233 if (attribute_flag[3] != 0)
8234 channel=(ChannelType) argument_list[3].integer_reference;
8235 channel_mask=SetImageChannelMask(image,channel);
8236 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8237 exception);
8238 if (image != (Image *) NULL)
8239 (void) SetImageChannelMask(image,channel_mask);
8240 break;
8241 }
8242 case 28: /* Shear */
8243 {
8244 if (attribute_flag[0] != 0)
8245 {
8246 flags=ParseGeometry(argument_list[0].string_reference,
8247 &geometry_info);
8248 if ((flags & SigmaValue) == 0)
8249 geometry_info.sigma=geometry_info.rho;
8250 }
8251 if (attribute_flag[1] != 0)
8252 geometry_info.rho=argument_list[1].real_reference;
8253 if (attribute_flag[2] != 0)
8254 geometry_info.sigma=argument_list[2].real_reference;
8255 if (attribute_flag[3] != 0)
8256 QueryColorCompliance(argument_list[3].string_reference,
8257 AllCompliance,&image->background_color,exception);
8258 if (attribute_flag[4] != 0)
8259 QueryColorCompliance(argument_list[4].string_reference,
8260 AllCompliance,&image->background_color,exception);
8261 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8262 exception);
8263 break;
8264 }
8265 case 29: /* Spread */
8266 {
8267 PixelInterpolateMethod
8268 method;
8269
8270 if (attribute_flag[0] == 0)
8271 argument_list[0].real_reference=1.0;
8272 method=UndefinedInterpolatePixel;
8273 if (attribute_flag[1] != 0)
8274 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8275 image=SpreadImage(image,method,argument_list[0].real_reference,
8276 exception);
8277 break;
8278 }
8279 case 30: /* Swirl */
8280 {
8281 PixelInterpolateMethod
8282 method;
8283
8284 if (attribute_flag[0] == 0)
8285 argument_list[0].real_reference=50.0;
8286 method=UndefinedInterpolatePixel;
8287 if (attribute_flag[1] != 0)
8288 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8289 image=SwirlImage(image,argument_list[0].real_reference,
8290 method,exception);
8291 break;
8292 }
8293 case 31: /* Resize */
8294 case 32: /* Zoom */
8295 {
8296 if (attribute_flag[0] != 0)
8297 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8298 &geometry,exception);
8299 if (attribute_flag[1] != 0)
8300 geometry.width=argument_list[1].integer_reference;
8301 if (attribute_flag[2] != 0)
8302 geometry.height=argument_list[2].integer_reference;
8303 if (attribute_flag[3] == 0)
8304 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8305 if (attribute_flag[4] != 0)
8306 SetImageArtifact(image,"filter:support",
8307 argument_list[4].string_reference);
8308 image=ResizeImage(image,geometry.width,geometry.height,
8309 (FilterType) argument_list[3].integer_reference,
8310 exception);
8311 break;
8312 }
8313 case 33: /* Annotate */
8314 {
8315 DrawInfo
8316 *draw_info;
8317
8318 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8319 (DrawInfo *) NULL);
8320 if (attribute_flag[0] != 0)
8321 {
8322 char
8323 *text;
8324
8325 text=InterpretImageProperties(info ? info->image_info :
8326 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8327 exception);
8328 (void) CloneString(&draw_info->text,text);
8329 text=DestroyString(text);
8330 }
8331 if (attribute_flag[1] != 0)
8332 (void) CloneString(&draw_info->font,
8333 argument_list[1].string_reference);
8334 if (attribute_flag[2] != 0)
8335 draw_info->pointsize=argument_list[2].real_reference;
8336 if (attribute_flag[3] != 0)
8337 (void) CloneString(&draw_info->density,
8338 argument_list[3].string_reference);
8339 if (attribute_flag[4] != 0)
8340 (void) QueryColorCompliance(argument_list[4].string_reference,
8341 AllCompliance,&draw_info->undercolor,exception);
8342 if (attribute_flag[5] != 0)
8343 {
8344 (void) QueryColorCompliance(argument_list[5].string_reference,
8345 AllCompliance,&draw_info->stroke,exception);
8346 if (argument_list[5].image_reference != (Image *) NULL)
8347 draw_info->stroke_pattern=CloneImage(
8348 argument_list[5].image_reference,0,0,MagickTrue,exception);
8349 }
8350 if (attribute_flag[6] != 0)
8351 {
8352 (void) QueryColorCompliance(argument_list[6].string_reference,
8353 AllCompliance,&draw_info->fill,exception);
8354 if (argument_list[6].image_reference != (Image *) NULL)
8355 draw_info->fill_pattern=CloneImage(
8356 argument_list[6].image_reference,0,0,MagickTrue,exception);
8357 }
8358 if (attribute_flag[7] != 0)
8359 {
8360 (void) CloneString(&draw_info->geometry,
8361 argument_list[7].string_reference);
8362 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8363 &geometry,exception);
8364 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8365 geometry_info.sigma=geometry_info.xi;
8366 }
8367 if (attribute_flag[8] != 0)
8368 (void) QueryColorCompliance(argument_list[8].string_reference,
8369 AllCompliance,&draw_info->fill,exception);
8370 if (attribute_flag[11] != 0)
8371 draw_info->gravity=(GravityType)
8372 argument_list[11].integer_reference;
8373 if (attribute_flag[25] != 0)
8374 {
8375 AV
8376 *av;
8377
8378 av=(AV *) argument_list[25].array_reference;
8379 if ((av_len(av) != 3) && (av_len(av) != 5))
8380 {
8381 ThrowPerlException(exception,OptionError,
8382 "affine matrix must have 4 or 6 elements",PackageName);
8383 goto PerlException;
8384 }
8385 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8386 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8387 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8388 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8389 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8390 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8391 {
8392 ThrowPerlException(exception,OptionError,
8393 "affine matrix is singular",PackageName);
8394 goto PerlException;
8395 }
8396 if (av_len(av) == 5)
8397 {
8398 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8399 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8400 }
8401 }
8402 for (j=12; j < 17; j++)
8403 {
8404 if (attribute_flag[j] == 0)
8405 continue;
8406 value=argument_list[j].string_reference;
8407 angle=argument_list[j].real_reference;
8408 current=draw_info->affine;
8409 GetAffineMatrix(&affine);
8410 switch (j)
8411 {
8412 case 12:
8413 {
8414 /*
8415 Translate.
8416 */
8417 flags=ParseGeometry(value,&geometry_info);
8418 affine.tx=geometry_info.xi;
8419 affine.ty=geometry_info.psi;
8420 if ((flags & PsiValue) == 0)
8421 affine.ty=affine.tx;
8422 break;
8423 }
8424 case 13:
8425 {
8426 /*
8427 Scale.
8428 */
8429 flags=ParseGeometry(value,&geometry_info);
8430 affine.sx=geometry_info.rho;
8431 affine.sy=geometry_info.sigma;
8432 if ((flags & SigmaValue) == 0)
8433 affine.sy=affine.sx;
8434 break;
8435 }
8436 case 14:
8437 {
8438 /*
8439 Rotate.
8440 */
8441 if (angle == 0.0)
8442 break;
8443 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8444 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8445 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8446 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8447 break;
8448 }
8449 case 15:
8450 {
8451 /*
8452 SkewX.
8453 */
8454 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8455 break;
8456 }
8457 case 16:
8458 {
8459 /*
8460 SkewY.
8461 */
8462 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8463 break;
8464 }
8465 }
8466 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8467 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8468 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8469 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8470 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8471 current.tx;
8472 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8473 current.ty;
8474 }
8475 if (attribute_flag[9] == 0)
8476 argument_list[9].real_reference=0.0;
8477 if (attribute_flag[10] == 0)
8478 argument_list[10].real_reference=0.0;
8479 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8480 {
8481 char
8482 geometry[MagickPathExtent];
8483
8484 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
8485 (double) argument_list[9].real_reference+draw_info->affine.tx,
8486 (double) argument_list[10].real_reference+draw_info->affine.ty);
8487 (void) CloneString(&draw_info->geometry,geometry);
8488 }
8489 if (attribute_flag[17] != 0)
8490 draw_info->stroke_width=argument_list[17].real_reference;
8491 if (attribute_flag[18] != 0)
8492 {
8493 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8494 MagickTrue : MagickFalse;
8495 draw_info->stroke_antialias=draw_info->text_antialias;
8496 }
8497 if (attribute_flag[19] != 0)
8498 (void) CloneString(&draw_info->family,
8499 argument_list[19].string_reference);
8500 if (attribute_flag[20] != 0)
8501 draw_info->style=(StyleType) argument_list[20].integer_reference;
8502 if (attribute_flag[21] != 0)
8503 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8504 if (attribute_flag[22] != 0)
8505 draw_info->weight=argument_list[22].integer_reference;
8506 if (attribute_flag[23] != 0)
8507 draw_info->align=(AlignType) argument_list[23].integer_reference;
8508 if (attribute_flag[24] != 0)
8509 (void) CloneString(&draw_info->encoding,
8510 argument_list[24].string_reference);
8511 if (attribute_flag[25] != 0)
8512 draw_info->fill_pattern=CloneImage(
8513 argument_list[25].image_reference,0,0,MagickTrue,exception);
8514 if (attribute_flag[26] != 0)
8515 draw_info->fill_pattern=CloneImage(
8516 argument_list[26].image_reference,0,0,MagickTrue,exception);
8517 if (attribute_flag[27] != 0)
8518 draw_info->stroke_pattern=CloneImage(
8519 argument_list[27].image_reference,0,0,MagickTrue,exception);
8520 if (attribute_flag[29] != 0)
8521 draw_info->kerning=argument_list[29].real_reference;
8522 if (attribute_flag[30] != 0)
8523 draw_info->interline_spacing=argument_list[30].real_reference;
8524 if (attribute_flag[31] != 0)
8525 draw_info->interword_spacing=argument_list[31].real_reference;
8526 if (attribute_flag[32] != 0)
8527 draw_info->direction=(DirectionType)
8528 argument_list[32].integer_reference;
8529 (void) AnnotateImage(image,draw_info,exception);
8530 draw_info=DestroyDrawInfo(draw_info);
8531 break;
8532 }
8533 case 34: /* ColorFloodfill */
8534 {
8535 DrawInfo
8536 *draw_info;
8537
8538 MagickBooleanType
8539 invert;
8540
8541 PixelInfo
8542 target;
8543
8544 draw_info=CloneDrawInfo(info ? info->image_info :
8545 (ImageInfo *) NULL,(DrawInfo *) NULL);
8546 if (attribute_flag[0] != 0)
8547 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8548 &geometry,exception);
8549 if (attribute_flag[1] != 0)
8550 geometry.x=argument_list[1].integer_reference;
8551 if (attribute_flag[2] != 0)
8552 geometry.y=argument_list[2].integer_reference;
8553 if (attribute_flag[3] != 0)
8554 (void) QueryColorCompliance(argument_list[3].string_reference,
8555 AllCompliance,&draw_info->fill,exception);
8556 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8557 geometry.x,geometry.y,&target,exception);
8558 invert=MagickFalse;
8559 if (attribute_flag[4] != 0)
8560 {
8561 QueryColorCompliance(argument_list[4].string_reference,
8562 AllCompliance,&target,exception);
8563 invert=MagickTrue;
8564 }
8565 if (attribute_flag[5] != 0)
8566 image->fuzz=StringToDoubleInterval(
8567 argument_list[5].string_reference,(double) QuantumRange+1.0);
8568 if (attribute_flag[6] != 0)
8569 invert=(MagickBooleanType) argument_list[6].integer_reference;
8570 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8571 geometry.y,invert,exception);
8572 draw_info=DestroyDrawInfo(draw_info);
8573 break;
8574 }
8575 case 35: /* Composite */
8576 {
8577 char
8578 composite_geometry[MagickPathExtent];
8579
8580 Image
8581 *composite_image,
8582 *rotate_image;
8583
8584 MagickBooleanType
8585 clip_to_self;
8586
8587 compose=OverCompositeOp;
8588 if (attribute_flag[0] != 0)
8589 composite_image=argument_list[0].image_reference;
8590 else
8591 {
8592 ThrowPerlException(exception,OptionError,
8593 "CompositeImageRequired",PackageName);
8594 goto PerlException;
8595 }
8596 /*
8597 Parameter Handling used for BOTH normal and tiled composition.
8598 */
8599 if (attribute_flag[1] != 0) /* compose */
8600 compose=(CompositeOperator) argument_list[1].integer_reference;
8601 if (attribute_flag[6] != 0) /* opacity */
8602 {
8603 if (compose != DissolveCompositeOp)
8604 (void) SetImageAlpha(composite_image,(Quantum)
8605 StringToDoubleInterval(argument_list[6].string_reference,
8606 (double) QuantumRange+1.0),exception);
8607 else
8608 {
8609 CacheView
8610 *composite_view;
8611
8612 double
8613 opacity;
8614
8615 MagickBooleanType
8616 sync;
8617
8618 register ssize_t
8619 x;
8620
8621 register Quantum
8622 *q;
8623
8624 ssize_t
8625 y;
8626
8627 /*
8628 Handle dissolve composite operator (patch by
8629 Kevin A. McGrail).
8630 */
8631 (void) CloneString(&image->geometry,
8632 argument_list[6].string_reference);
8633 opacity=(Quantum) StringToDoubleInterval(
8634 argument_list[6].string_reference,(double) QuantumRange+
8635 1.0);
8636 if (composite_image->alpha_trait != UndefinedPixelTrait)
8637 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8638 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8639 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8640 {
8641 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8642 composite_image->columns,1,exception);
8643 for (x=0; x < (ssize_t) composite_image->columns; x++)
8644 {
8645 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8646 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8647 q);
8648 q+=GetPixelChannels(composite_image);
8649 }
8650 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8651 if (sync == MagickFalse)
8652 break;
8653 }
8654 composite_view=DestroyCacheView(composite_view);
8655 }
8656 }
8657 if (attribute_flag[9] != 0) /* "color=>" */
8658 QueryColorCompliance(argument_list[9].string_reference,
8659 AllCompliance,&composite_image->background_color,exception);
8660 if (attribute_flag[12] != 0) /* "interpolate=>" */
8661 image->interpolate=(PixelInterpolateMethod)
8662 argument_list[12].integer_reference;
8663 if (attribute_flag[13] != 0) /* "args=>" */
8664 (void) SetImageArtifact(composite_image,"compose:args",
8665 argument_list[13].string_reference);
8666 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8667 (void) SetImageArtifact(composite_image,"compose:args",
8668 argument_list[14].string_reference);
8669 clip_to_self=MagickTrue;
8670 if (attribute_flag[15] != 0)
8671 clip_to_self=(MagickBooleanType)
8672 argument_list[15].integer_reference;
8673 /*
8674 Tiling Composition (with orthogonal rotate).
8675 */
8676 rotate_image=(Image *) NULL;
8677 if (attribute_flag[8] != 0) /* "rotate=>" */
8678 {
8679 /*
8680 Rotate image.
8681 */
8682 rotate_image=RotateImage(composite_image,
8683 argument_list[8].real_reference,exception);
8684 if (rotate_image == (Image *) NULL)
8685 break;
8686 }
8687 if ((attribute_flag[7] != 0) &&
8688 (argument_list[7].integer_reference != 0)) /* tile */
8689 {
8690 ssize_t
8691 x,
8692 y;
8693
8694 /*
8695 Tile the composite image.
8696 */
8697 if (attribute_flag[8] != 0) /* "tile=>" */
8698 (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8699 "false");
8700 else
8701 (void) SetImageArtifact(composite_image,
8702 "compose:outside-overlay","false");
8703 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8704 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8705 {
8706 if (attribute_flag[8] != 0) /* rotate */
8707 (void) CompositeImage(image,rotate_image,compose,
8708 MagickTrue,x,y,exception);
8709 else
8710 (void) CompositeImage(image,composite_image,compose,
8711 MagickTrue,x,y,exception);
8712 }
8713 if (attribute_flag[8] != 0) /* rotate */
8714 rotate_image=DestroyImage(rotate_image);
8715 break;
8716 }
8717 /*
8718 Parameter Handling used used ONLY for normal composition.
8719 */
8720 if (attribute_flag[5] != 0) /* gravity */
8721 image->gravity=(GravityType) argument_list[5].integer_reference;
8722 if (attribute_flag[2] != 0) /* geometry offset */
8723 {
8724 SetGeometry(image,&geometry);
8725 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8726 &geometry);
8727 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8728 &geometry);
8729 }
8730 if (attribute_flag[3] != 0) /* x offset */
8731 geometry.x=argument_list[3].integer_reference;
8732 if (attribute_flag[4] != 0) /* y offset */
8733 geometry.y=argument_list[4].integer_reference;
8734 if (attribute_flag[10] != 0) /* mask */
8735 {
8736 if ((image->compose == DisplaceCompositeOp) ||
8737 (image->compose == DistortCompositeOp))
8738 {
8739 /*
8740 Merge Y displacement into X displacement image.
8741 */
8742 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8743 exception);
8744 (void) CompositeImage(composite_image,
8745 argument_list[10].image_reference,CopyGreenCompositeOp,
8746 MagickTrue,0,0,exception);
8747 }
8748 else
8749 {
8750 Image
8751 *mask_image;
8752
8753 /*
8754 Set a blending mask for the composition.
8755 */
8756 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8757 MagickTrue,exception);
8758 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
8759 exception);
8760 mask_image=DestroyImage(mask_image);
8761 }
8762 }
8763 if (attribute_flag[11] != 0) /* channel */
8764 channel=(ChannelType) argument_list[11].integer_reference;
8765 /*
8766 Composite two images (normal composition).
8767 */
8768 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
8769 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8770 (double) composite_image->rows,(double) geometry.x,(double)
8771 geometry.y);
8772 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8773 exception);
8774 channel_mask=SetImageChannelMask(image,channel);
8775 if (attribute_flag[8] == 0) /* no rotate */
8776 CompositeImage(image,composite_image,compose,clip_to_self,
8777 geometry.x,geometry.y,exception);
8778 else
8779 {
8780 /*
8781 Position adjust rotated image then composite.
8782 */
8783 geometry.x-=(ssize_t) (rotate_image->columns-
8784 composite_image->columns)/2;
8785 geometry.y-=(ssize_t) (rotate_image->rows-
8786 composite_image->rows)/2;
8787 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8788 geometry.y,exception);
8789 rotate_image=DestroyImage(rotate_image);
8790 }
8791 if (attribute_flag[10] != 0) /* mask */
8792 {
8793 if ((image->compose == DisplaceCompositeOp) ||
8794 (image->compose == DistortCompositeOp))
8795 composite_image=DestroyImage(composite_image);
8796 else
8797 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
8798 exception);
8799 }
8800 (void) SetImageChannelMask(image,channel_mask);
8801 break;
8802 }
8803 case 36: /* Contrast */
8804 {
8805 if (attribute_flag[0] == 0)
8806 argument_list[0].integer_reference=0;
8807 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8808 MagickTrue : MagickFalse,exception);
8809 break;
8810 }
8811 case 37: /* CycleColormap */
8812 {
8813 if (attribute_flag[0] == 0)
8814 argument_list[0].integer_reference=6;
8815 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8816 exception);
8817 break;
8818 }
8819 case 38: /* Draw */
8820 {
8821 DrawInfo
8822 *draw_info;
8823
8824 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8825 (DrawInfo *) NULL);
8826 (void) CloneString(&draw_info->primitive,"point");
8827 if (attribute_flag[0] != 0)
8828 {
8829 if (argument_list[0].integer_reference < 0)
8830 (void) CloneString(&draw_info->primitive,
8831 argument_list[0].string_reference);
8832 else
8833 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8834 MagickPrimitiveOptions,argument_list[0].integer_reference));
8835 }
8836 if (attribute_flag[1] != 0)
8837 {
8838 if (LocaleCompare(draw_info->primitive,"path") == 0)
8839 {
8840 (void) ConcatenateString(&draw_info->primitive," '");
8841 ConcatenateString(&draw_info->primitive,
8842 argument_list[1].string_reference);
8843 (void) ConcatenateString(&draw_info->primitive,"'");
8844 }
8845 else
8846 {
8847 (void) ConcatenateString(&draw_info->primitive," ");
8848 ConcatenateString(&draw_info->primitive,
8849 argument_list[1].string_reference);
8850 }
8851 }
8852 if (attribute_flag[2] != 0)
8853 {
8854 (void) ConcatenateString(&draw_info->primitive," ");
8855 (void) ConcatenateString(&draw_info->primitive,
8856 CommandOptionToMnemonic(MagickMethodOptions,
8857 argument_list[2].integer_reference));
8858 }
8859 if (attribute_flag[3] != 0)
8860 {
8861 (void) QueryColorCompliance(argument_list[3].string_reference,
8862 AllCompliance,&draw_info->stroke,exception);
8863 if (argument_list[3].image_reference != (Image *) NULL)
8864 draw_info->stroke_pattern=CloneImage(
8865 argument_list[3].image_reference,0,0,MagickTrue,exception);
8866 }
8867 if (attribute_flag[4] != 0)
8868 {
8869 (void) QueryColorCompliance(argument_list[4].string_reference,
8870 AllCompliance,&draw_info->fill,exception);
8871 if (argument_list[4].image_reference != (Image *) NULL)
8872 draw_info->fill_pattern=CloneImage(
8873 argument_list[4].image_reference,0,0,MagickTrue,exception);
8874 }
8875 if (attribute_flag[5] != 0)
8876 draw_info->stroke_width=argument_list[5].real_reference;
8877 if (attribute_flag[6] != 0)
8878 (void) CloneString(&draw_info->font,
8879 argument_list[6].string_reference);
8880 if (attribute_flag[7] != 0)
8881 (void) QueryColorCompliance(argument_list[7].string_reference,
8882 AllCompliance,&draw_info->border_color,exception);
8883 if (attribute_flag[8] != 0)
8884 draw_info->affine.tx=argument_list[8].real_reference;
8885 if (attribute_flag[9] != 0)
8886 draw_info->affine.ty=argument_list[9].real_reference;
8887 if (attribute_flag[20] != 0)
8888 {
8889 AV
8890 *av;
8891
8892 av=(AV *) argument_list[20].array_reference;
8893 if ((av_len(av) != 3) && (av_len(av) != 5))
8894 {
8895 ThrowPerlException(exception,OptionError,
8896 "affine matrix must have 4 or 6 elements",PackageName);
8897 goto PerlException;
8898 }
8899 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8900 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8901 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8902 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8903 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8904 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8905 {
8906 ThrowPerlException(exception,OptionError,
8907 "affine matrix is singular",PackageName);
8908 goto PerlException;
8909 }
8910 if (av_len(av) == 5)
8911 {
8912 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8913 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8914 }
8915 }
8916 for (j=10; j < 15; j++)
8917 {
8918 if (attribute_flag[j] == 0)
8919 continue;
8920 value=argument_list[j].string_reference;
8921 angle=argument_list[j].real_reference;
8922 current=draw_info->affine;
8923 GetAffineMatrix(&affine);
8924 switch (j)
8925 {
8926 case 10:
8927 {
8928 /*
8929 Translate.
8930 */
8931 flags=ParseGeometry(value,&geometry_info);
8932 affine.tx=geometry_info.xi;
8933 affine.ty=geometry_info.psi;
8934 if ((flags & PsiValue) == 0)
8935 affine.ty=affine.tx;
8936 break;
8937 }
8938 case 11:
8939 {
8940 /*
8941 Scale.
8942 */
8943 flags=ParseGeometry(value,&geometry_info);
8944 affine.sx=geometry_info.rho;
8945 affine.sy=geometry_info.sigma;
8946 if ((flags & SigmaValue) == 0)
8947 affine.sy=affine.sx;
8948 break;
8949 }
8950 case 12:
8951 {
8952 /*
8953 Rotate.
8954 */
8955 if (angle == 0.0)
8956 break;
8957 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8958 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8959 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8960 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8961 break;
8962 }
8963 case 13:
8964 {
8965 /*
8966 SkewX.
8967 */
8968 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8969 break;
8970 }
8971 case 14:
8972 {
8973 /*
8974 SkewY.
8975 */
8976 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8977 break;
8978 }
8979 }
8980 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8981 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8982 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8983 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8984 draw_info->affine.tx=
8985 current.sx*affine.tx+current.ry*affine.ty+current.tx;
8986 draw_info->affine.ty=
8987 current.rx*affine.tx+current.sy*affine.ty+current.ty;
8988 }
8989 if (attribute_flag[15] != 0)
8990 draw_info->fill_pattern=CloneImage(
8991 argument_list[15].image_reference,0,0,MagickTrue,exception);
8992 if (attribute_flag[16] != 0)
8993 draw_info->pointsize=argument_list[16].real_reference;
8994 if (attribute_flag[17] != 0)
8995 {
8996 draw_info->stroke_antialias=argument_list[17].integer_reference != 0
8997 ? MagickTrue : MagickFalse;
8998 draw_info->text_antialias=draw_info->stroke_antialias;
8999 }
9000 if (attribute_flag[18] != 0)
9001 (void) CloneString(&draw_info->density,
9002 argument_list[18].string_reference);
9003 if (attribute_flag[19] != 0)
9004 draw_info->stroke_width=argument_list[19].real_reference;
9005 if (attribute_flag[21] != 0)
9006 draw_info->dash_offset=argument_list[21].real_reference;
9007 if (attribute_flag[22] != 0)
9008 {
9009 AV
9010 *av;
9011
9012 av=(AV *) argument_list[22].array_reference;
9013 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9014 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9015 if (draw_info->dash_pattern != (double *) NULL)
9016 {
9017 for (i=0; i <= av_len(av); i++)
9018 draw_info->dash_pattern[i]=(double)
9019 SvNV(*(av_fetch(av,i,0)));
9020 draw_info->dash_pattern[i]=0.0;
9021 }
9022 }
9023 if (attribute_flag[23] != 0)
9024 image->interpolate=(PixelInterpolateMethod)
9025 argument_list[23].integer_reference;
9026 if ((attribute_flag[24] != 0) &&
9027 (draw_info->fill_pattern != (Image *) NULL))
9028 flags=ParsePageGeometry(draw_info->fill_pattern,
9029 argument_list[24].string_reference,
9030 &draw_info->fill_pattern->tile_offset,exception);
9031 if (attribute_flag[25] != 0)
9032 {
9033 (void) ConcatenateString(&draw_info->primitive," '");
9034 (void) ConcatenateString(&draw_info->primitive,
9035 argument_list[25].string_reference);
9036 (void) ConcatenateString(&draw_info->primitive,"'");
9037 }
9038 if (attribute_flag[26] != 0)
9039 draw_info->fill_pattern=CloneImage(
9040 argument_list[26].image_reference,0,0,MagickTrue,exception);
9041 if (attribute_flag[27] != 0)
9042 draw_info->stroke_pattern=CloneImage(
9043 argument_list[27].image_reference,0,0,MagickTrue,exception);
9044 if (attribute_flag[28] != 0)
9045 (void) CloneString(&draw_info->primitive,
9046 argument_list[28].string_reference);
9047 if (attribute_flag[29] != 0)
9048 draw_info->kerning=argument_list[29].real_reference;
9049 if (attribute_flag[30] != 0)
9050 draw_info->interline_spacing=argument_list[30].real_reference;
9051 if (attribute_flag[31] != 0)
9052 draw_info->interword_spacing=argument_list[31].real_reference;
9053 if (attribute_flag[32] != 0)
9054 draw_info->direction=(DirectionType)
9055 argument_list[32].integer_reference;
9056 DrawImage(image,draw_info,exception);
9057 draw_info=DestroyDrawInfo(draw_info);
9058 break;
9059 }
9060 case 39: /* Equalize */
9061 {
9062 if (attribute_flag[0] != 0)
9063 channel=(ChannelType) argument_list[0].integer_reference;
9064 channel_mask=SetImageChannelMask(image,channel);
9065 EqualizeImage(image,exception);
9066 (void) SetImageChannelMask(image,channel_mask);
9067 break;
9068 }
9069 case 40: /* Gamma */
9070 {
9071 if (attribute_flag[1] != 0)
9072 channel=(ChannelType) argument_list[1].integer_reference;
9073 if (attribute_flag[2] == 0)
9074 argument_list[2].real_reference=1.0;
9075 if (attribute_flag[3] == 0)
9076 argument_list[3].real_reference=1.0;
9077 if (attribute_flag[4] == 0)
9078 argument_list[4].real_reference=1.0;
9079 if (attribute_flag[0] == 0)
9080 {
9081 (void) FormatLocaleString(message,MagickPathExtent,
9082 "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
9083 (double) argument_list[3].real_reference,
9084 (double) argument_list[4].real_reference);
9085 argument_list[0].string_reference=message;
9086 }
9087 (void) GammaImage(image,StringToDouble(
9088 argument_list[0].string_reference,(char **) NULL),exception);
9089 break;
9090 }
9091 case 41: /* Map */
9092 {
9093 QuantizeInfo
9094 *quantize_info;
9095
9096 if (attribute_flag[0] == 0)
9097 {
9098 ThrowPerlException(exception,OptionError,"MapImageRequired",
9099 PackageName);
9100 goto PerlException;
9101 }
9102 quantize_info=AcquireQuantizeInfo(info->image_info);
9103 if (attribute_flag[1] != 0)
9104 quantize_info->dither_method=(DitherMethod)
9105 argument_list[1].integer_reference;
9106 (void) RemapImages(quantize_info,image,
9107 argument_list[0].image_reference,exception);
9108 quantize_info=DestroyQuantizeInfo(quantize_info);
9109 break;
9110 }
9111 case 42: /* MatteFloodfill */
9112 {
9113 DrawInfo
9114 *draw_info;
9115
9116 MagickBooleanType
9117 invert;
9118
9119 PixelInfo
9120 target;
9121
9122 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9123 (DrawInfo *) NULL);
9124 if (attribute_flag[0] != 0)
9125 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9126 &geometry,exception);
9127 if (attribute_flag[1] != 0)
9128 geometry.x=argument_list[1].integer_reference;
9129 if (attribute_flag[2] != 0)
9130 geometry.y=argument_list[2].integer_reference;
9131 if (image->alpha_trait == UndefinedPixelTrait)
9132 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9133 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9134 geometry.x,geometry.y,&target,exception);
9135 if (attribute_flag[4] != 0)
9136 QueryColorCompliance(argument_list[4].string_reference,
9137 AllCompliance,&target,exception);
9138 if (attribute_flag[3] != 0)
9139 target.alpha=StringToDoubleInterval(
9140 argument_list[3].string_reference,(double) (double) QuantumRange+
9141 1.0);
9142 if (attribute_flag[5] != 0)
9143 image->fuzz=StringToDoubleInterval(
9144 argument_list[5].string_reference,(double) QuantumRange+1.0);
9145 invert=MagickFalse;
9146 if (attribute_flag[6] != 0)
9147 invert=(MagickBooleanType) argument_list[6].integer_reference;
9148 channel_mask=SetImageChannelMask(image,AlphaChannel);
9149 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9150 geometry.y,invert,exception);
9151 (void) SetImageChannelMask(image,channel_mask);
9152 draw_info=DestroyDrawInfo(draw_info);
9153 break;
9154 }
9155 case 43: /* Modulate */
9156 {
9157 char
9158 modulate[MagickPathExtent];
9159
9160 geometry_info.rho=100.0;
9161 geometry_info.sigma=100.0;
9162 geometry_info.xi=100.0;
9163 if (attribute_flag[0] != 0)
9164 (void)ParseGeometry(argument_list[0].string_reference,
9165 &geometry_info);
9166 if (attribute_flag[1] != 0)
9167 geometry_info.xi=argument_list[1].real_reference;
9168 if (attribute_flag[2] != 0)
9169 geometry_info.sigma=argument_list[2].real_reference;
9170 if (attribute_flag[3] != 0)
9171 {
9172 geometry_info.sigma=argument_list[3].real_reference;
9173 SetImageArtifact(image,"modulate:colorspace","HWB");
9174 }
9175 if (attribute_flag[4] != 0)
9176 {
9177 geometry_info.rho=argument_list[4].real_reference;
9178 SetImageArtifact(image,"modulate:colorspace","HSB");
9179 }
9180 if (attribute_flag[5] != 0)
9181 {
9182 geometry_info.sigma=argument_list[5].real_reference;
9183 SetImageArtifact(image,"modulate:colorspace","HSL");
9184 }
9185 if (attribute_flag[6] != 0)
9186 {
9187 geometry_info.rho=argument_list[6].real_reference;
9188 SetImageArtifact(image,"modulate:colorspace","HWB");
9189 }
9190 (void) FormatLocaleString(modulate,MagickPathExtent,"%.15g,%.15g,%.15g",
9191 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9192 (void) ModulateImage(image,modulate,exception);
9193 break;
9194 }
9195 case 44: /* Negate */
9196 {
9197 if (attribute_flag[0] == 0)
9198 argument_list[0].integer_reference=0;
9199 if (attribute_flag[1] != 0)
9200 channel=(ChannelType) argument_list[1].integer_reference;
9201 channel_mask=SetImageChannelMask(image,channel);
9202 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9203 MagickTrue : MagickFalse,exception);
9204 (void) SetImageChannelMask(image,channel_mask);
9205 break;
9206 }
9207 case 45: /* Normalize */
9208 {
9209 if (attribute_flag[0] != 0)
9210 channel=(ChannelType) argument_list[0].integer_reference;
9211 channel_mask=SetImageChannelMask(image,channel);
9212 NormalizeImage(image,exception);
9213 (void) SetImageChannelMask(image,channel_mask);
9214 break;
9215 }
9216 case 46: /* NumberColors */
9217 break;
9218 case 47: /* Opaque */
9219 {
9220 MagickBooleanType
9221 invert;
9222
9223 PixelInfo
9224 fill_color,
9225 target;
9226
9227 (void) QueryColorCompliance("none",AllCompliance,&target,
9228 exception);
9229 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9230 exception);
9231 if (attribute_flag[0] != 0)
9232 (void) QueryColorCompliance(argument_list[0].string_reference,
9233 AllCompliance,&target,exception);
9234 if (attribute_flag[1] != 0)
9235 (void) QueryColorCompliance(argument_list[1].string_reference,
9236 AllCompliance,&fill_color,exception);
9237 if (attribute_flag[2] != 0)
9238 image->fuzz=StringToDoubleInterval(
9239 argument_list[2].string_reference,(double) QuantumRange+1.0);
9240 if (attribute_flag[3] != 0)
9241 channel=(ChannelType) argument_list[3].integer_reference;
9242 invert=MagickFalse;
9243 if (attribute_flag[4] != 0)
9244 invert=(MagickBooleanType) argument_list[4].integer_reference;
9245 channel_mask=SetImageChannelMask(image,channel);
9246 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9247 (void) SetImageChannelMask(image,channel_mask);
9248 break;
9249 }
9250 case 48: /* Quantize */
9251 {
9252 QuantizeInfo
9253 *quantize_info;
9254
9255 quantize_info=AcquireQuantizeInfo(info->image_info);
9256 if (attribute_flag[0] != 0)
9257 quantize_info->number_colors=(size_t)
9258 argument_list[0].integer_reference;
9259 if (attribute_flag[1] != 0)
9260 quantize_info->tree_depth=(size_t)
9261 argument_list[1].integer_reference;
9262 if (attribute_flag[2] != 0)
9263 quantize_info->colorspace=(ColorspaceType)
9264 argument_list[2].integer_reference;
9265 if (attribute_flag[3] != 0)
9266 quantize_info->dither_method=(DitherMethod)
9267 argument_list[3].integer_reference;
9268 if (attribute_flag[4] != 0)
9269 quantize_info->measure_error=
9270 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
9271 if (attribute_flag[6] != 0)
9272 (void) QueryColorCompliance(argument_list[6].string_reference,
9273 AllCompliance,&image->transparent_color,exception);
9274 if (attribute_flag[7] != 0)
9275 quantize_info->dither_method=(DitherMethod)
9276 argument_list[7].integer_reference;
9277 if (attribute_flag[5] && argument_list[5].integer_reference)
9278 (void) QuantizeImages(quantize_info,image,exception);
9279 else
9280 if ((image->storage_class == DirectClass) ||
9281 (image->colors > quantize_info->number_colors) ||
9282 (quantize_info->colorspace == GRAYColorspace))
9283 (void) QuantizeImage(quantize_info,image,exception);
9284 else
9285 CompressImageColormap(image,exception);
9286 quantize_info=DestroyQuantizeInfo(quantize_info);
9287 break;
9288 }
9289 case 49: /* Raise */
9290 {
9291 if (attribute_flag[0] != 0)
9292 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9293 &geometry,exception);
9294 if (attribute_flag[1] != 0)
9295 geometry.width=argument_list[1].integer_reference;
9296 if (attribute_flag[2] != 0)
9297 geometry.height=argument_list[2].integer_reference;
9298 if (attribute_flag[3] == 0)
9299 argument_list[3].integer_reference=1;
9300 (void) RaiseImage(image,&geometry,
9301 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9302 exception);
9303 break;
9304 }
9305 case 50: /* Segment */
9306 {
9307 ColorspaceType
9308 colorspace;
9309
9310 double
9311 cluster_threshold,
9312 smoothing_threshold;
9313
9314 MagickBooleanType
9315 verbose;
9316
9317 cluster_threshold=1.0;
9318 smoothing_threshold=1.5;
9319 colorspace=sRGBColorspace;
9320 verbose=MagickFalse;
9321 if (attribute_flag[0] != 0)
9322 {
9323 flags=ParseGeometry(argument_list[0].string_reference,
9324 &geometry_info);
9325 cluster_threshold=geometry_info.rho;
9326 if (flags & SigmaValue)
9327 smoothing_threshold=geometry_info.sigma;
9328 }
9329 if (attribute_flag[1] != 0)
9330 cluster_threshold=argument_list[1].real_reference;
9331 if (attribute_flag[2] != 0)
9332 smoothing_threshold=argument_list[2].real_reference;
9333 if (attribute_flag[3] != 0)
9334 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9335 if (attribute_flag[4] != 0)
9336 verbose=argument_list[4].integer_reference != 0 ?
9337 MagickTrue : MagickFalse;
9338 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9339 smoothing_threshold,exception);
9340 break;
9341 }
9342 case 51: /* Signature */
9343 {
9344 (void) SignatureImage(image,exception);
9345 break;
9346 }
9347 case 52: /* Solarize */
9348 {
9349 geometry_info.rho=QuantumRange/2.0;
9350 if (attribute_flag[0] != 0)
9351 flags=ParseGeometry(argument_list[0].string_reference,
9352 &geometry_info);
9353 if (attribute_flag[1] != 0)
9354 geometry_info.rho=StringToDoubleInterval(
9355 argument_list[1].string_reference,(double) QuantumRange+1.0);
9356 (void) SolarizeImage(image,geometry_info.rho,exception);
9357 break;
9358 }
9359 case 53: /* Sync */
9360 {
9361 (void) SyncImage(image,exception);
9362 break;
9363 }
9364 case 54: /* Texture */
9365 {
9366 if (attribute_flag[0] == 0)
9367 break;
9368 TextureImage(image,argument_list[0].image_reference,exception);
9369 break;
9370 }
9371 case 55: /* Evalute */
9372 {
9373 MagickEvaluateOperator
9374 op;
9375
9376 op=SetEvaluateOperator;
9377 if (attribute_flag[0] == MagickFalse)
9378 argument_list[0].real_reference=0.0;
9379 if (attribute_flag[1] != MagickFalse)
9380 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9381 if (attribute_flag[2] != MagickFalse)
9382 channel=(ChannelType) argument_list[2].integer_reference;
9383 channel_mask=SetImageChannelMask(image,channel);
9384 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9385 exception);
9386 (void) SetImageChannelMask(image,channel_mask);
9387 break;
9388 }
9389 case 56: /* Transparent */
9390 {
9391 double
9392 opacity;
9393
9394 MagickBooleanType
9395 invert;
9396
9397 PixelInfo
9398 target;
9399
9400 (void) QueryColorCompliance("none",AllCompliance,&target,
9401 exception);
9402 if (attribute_flag[0] != 0)
9403 (void) QueryColorCompliance(argument_list[0].string_reference,
9404 AllCompliance,&target,exception);
9405 opacity=TransparentAlpha;
9406 if (attribute_flag[1] != 0)
9407 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9408 (double) QuantumRange+1.0);
9409 if (attribute_flag[2] != 0)
9410 image->fuzz=StringToDoubleInterval(
9411 argument_list[2].string_reference,(double) QuantumRange+1.0);
9412 if (attribute_flag[3] == 0)
9413 argument_list[3].integer_reference=0;
9414 invert=MagickFalse;
9415 if (attribute_flag[3] != 0)
9416 invert=(MagickBooleanType) argument_list[3].integer_reference;
9417 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9418 invert,exception);
9419 break;
9420 }
9421 case 57: /* Threshold */
9422 {
9423 double
9424 threshold;
9425
9426 if (attribute_flag[0] == 0)
9427 argument_list[0].string_reference="50%";
9428 if (attribute_flag[1] != 0)
9429 channel=(ChannelType) argument_list[1].integer_reference;
9430 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9431 (double) QuantumRange+1.0);
9432 channel_mask=SetImageChannelMask(image,channel);
9433 (void) BilevelImage(image,threshold,exception);
9434 (void) SetImageChannelMask(image,channel_mask);
9435 break;
9436 }
9437 case 58: /* Charcoal */
9438 {
9439 if (attribute_flag[0] != 0)
9440 {
9441 flags=ParseGeometry(argument_list[0].string_reference,
9442 &geometry_info);
9443 if ((flags & SigmaValue) == 0)
9444 geometry_info.sigma=1.0;
9445 }
9446 if (attribute_flag[1] != 0)
9447 geometry_info.rho=argument_list[1].real_reference;
9448 if (attribute_flag[2] != 0)
9449 geometry_info.sigma=argument_list[2].real_reference;
9450 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9451 exception);
9452 break;
9453 }
9454 case 59: /* Trim */
9455 {
9456 if (attribute_flag[0] != 0)
9457 image->fuzz=StringToDoubleInterval(
9458 argument_list[0].string_reference,(double) QuantumRange+1.0);
9459 image=TrimImage(image,exception);
9460 break;
9461 }
9462 case 60: /* Wave */
9463 {
9464 PixelInterpolateMethod
9465 method;
9466
9467 if (attribute_flag[0] != 0)
9468 {
9469 flags=ParseGeometry(argument_list[0].string_reference,
9470 &geometry_info);
9471 if ((flags & SigmaValue) == 0)
9472 geometry_info.sigma=1.0;
9473 }
9474 if (attribute_flag[1] != 0)
9475 geometry_info.rho=argument_list[1].real_reference;
9476 if (attribute_flag[2] != 0)
9477 geometry_info.sigma=argument_list[2].real_reference;
9478 method=UndefinedInterpolatePixel;
9479 if (attribute_flag[3] != 0)
9480 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9481 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9482 method,exception);
9483 break;
9484 }
9485 case 61: /* Separate */
9486 {
9487 if (attribute_flag[0] != 0)
9488 channel=(ChannelType) argument_list[0].integer_reference;
9489 image=SeparateImage(image,channel,exception);
9490 break;
9491 }
9492 case 63: /* Stereo */
9493 {
9494 if (attribute_flag[0] == 0)
9495 {
9496 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9497 PackageName);
9498 goto PerlException;
9499 }
9500 if (attribute_flag[1] != 0)
9501 geometry.x=argument_list[1].integer_reference;
9502 if (attribute_flag[2] != 0)
9503 geometry.y=argument_list[2].integer_reference;
9504 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9505 geometry.x,geometry.y,exception);
9506 break;
9507 }
9508 case 64: /* Stegano */
9509 {
9510 if (attribute_flag[0] == 0)
9511 {
9512 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9513 PackageName);
9514 goto PerlException;
9515 }
9516 if (attribute_flag[1] == 0)
9517 argument_list[1].integer_reference=0;
9518 image->offset=argument_list[1].integer_reference;
9519 image=SteganoImage(image,argument_list[0].image_reference,exception);
9520 break;
9521 }
9522 case 65: /* Deconstruct */
9523 {
9524 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9525 break;
9526 }
9527 case 66: /* GaussianBlur */
9528 {
9529 if (attribute_flag[0] != 0)
9530 {
9531 flags=ParseGeometry(argument_list[0].string_reference,
9532 &geometry_info);
9533 if ((flags & SigmaValue) == 0)
9534 geometry_info.sigma=1.0;
9535 }
9536 if (attribute_flag[1] != 0)
9537 geometry_info.rho=argument_list[1].real_reference;
9538 if (attribute_flag[2] != 0)
9539 geometry_info.sigma=argument_list[2].real_reference;
9540 if (attribute_flag[3] != 0)
9541 channel=(ChannelType) argument_list[3].integer_reference;
9542 channel_mask=SetImageChannelMask(image,channel);
9543 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9544 exception);
9545 if (image != (Image *) NULL)
9546 (void) SetImageChannelMask(image,channel_mask);
9547 break;
9548 }
9549 case 67: /* Convolve */
9550 {
9551 KernelInfo
9552 *kernel;
9553
9554 kernel=(KernelInfo *) NULL;
9555 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9556 break;
9557 if (attribute_flag[0] != 0)
9558 {
9559 AV
9560 *av;
9561
9562 size_t
9563 order;
9564
9565 kernel=AcquireKernelInfo((const char *) NULL,exception);
9566 if (kernel == (KernelInfo *) NULL)
9567 break;
9568 av=(AV *) argument_list[0].array_reference;
9569 order=(size_t) sqrt(av_len(av)+1);
9570 kernel->width=order;
9571 kernel->height=order;
9572 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9573 order*sizeof(*kernel->values));
9574 if (kernel->values == (MagickRealType *) NULL)
9575 {
9576 kernel=DestroyKernelInfo(kernel);
9577 ThrowPerlException(exception,ResourceLimitFatalError,
9578 "MemoryAllocationFailed",PackageName);
9579 goto PerlException;
9580 }
9581 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9582 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9583 for ( ; j < (ssize_t) (order*order); j++)
9584 kernel->values[j]=0.0;
9585 }
9586 if (attribute_flag[1] != 0)
9587 channel=(ChannelType) argument_list[1].integer_reference;
9588 if (attribute_flag[2] != 0)
9589 SetImageArtifact(image,"filter:blur",
9590 argument_list[2].string_reference);
9591 if (attribute_flag[3] != 0)
9592 {
9593 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9594 exception);
9595 if (kernel == (KernelInfo *) NULL)
9596 break;
9597 }
9598 channel_mask=SetImageChannelMask(image,channel);
9599 image=ConvolveImage(image,kernel,exception);
9600 if (image != (Image *) NULL)
9601 (void) SetImageChannelMask(image,channel_mask);
9602 kernel=DestroyKernelInfo(kernel);
9603 break;
9604 }
9605 case 68: /* Profile */
9606 {
9607 const char
9608 *name;
9609
9610 Image
9611 *profile_image;
9612
9613 ImageInfo
9614 *profile_info;
9615
9616 StringInfo
9617 *profile;
9618
9619 name="*";
9620 if (attribute_flag[0] != 0)
9621 name=argument_list[0].string_reference;
9622 if (attribute_flag[2] != 0)
9623 image->rendering_intent=(RenderingIntent)
9624 argument_list[2].integer_reference;
9625 if (attribute_flag[3] != 0)
9626 image->black_point_compensation=
9627 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9628 if (attribute_flag[1] != 0)
9629 {
9630 if (argument_list[1].length == 0)
9631 {
9632 /*
9633 Remove a profile from the image.
9634 */
9635 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9636 exception);
9637 break;
9638 }
9639 /*
9640 Associate user supplied profile with the image.
9641 */
9642 profile=AcquireStringInfo(argument_list[1].length);
9643 SetStringInfoDatum(profile,(const unsigned char *)
9644 argument_list[1].string_reference);
9645 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9646 (size_t) GetStringInfoLength(profile),exception);
9647 profile=DestroyStringInfo(profile);
9648 break;
9649 }
9650 /*
9651 Associate a profile with the image.
9652 */
9653 profile_info=CloneImageInfo(info ? info->image_info :
9654 (ImageInfo *) NULL);
9655 profile_image=ReadImages(profile_info,name,exception);
9656 if (profile_image == (Image *) NULL)
9657 break;
9658 ResetImageProfileIterator(profile_image);
9659 name=GetNextImageProfile(profile_image);
9660 while (name != (const char *) NULL)
9661 {
9662 const StringInfo
9663 *profile;
9664
9665 profile=GetImageProfile(profile_image,name);
9666 if (profile != (const StringInfo *) NULL)
9667 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9668 (size_t) GetStringInfoLength(profile),exception);
9669 name=GetNextImageProfile(profile_image);
9670 }
9671 profile_image=DestroyImage(profile_image);
9672 profile_info=DestroyImageInfo(profile_info);
9673 break;
9674 }
9675 case 69: /* UnsharpMask */
9676 {
9677 if (attribute_flag[0] != 0)
9678 {
9679 flags=ParseGeometry(argument_list[0].string_reference,
9680 &geometry_info);
9681 if ((flags & SigmaValue) == 0)
9682 geometry_info.sigma=1.0;
9683 if ((flags & XiValue) == 0)
9684 geometry_info.xi=1.0;
9685 if ((flags & PsiValue) == 0)
9686 geometry_info.psi=0.5;
9687 }
9688 if (attribute_flag[1] != 0)
9689 geometry_info.rho=argument_list[1].real_reference;
9690 if (attribute_flag[2] != 0)
9691 geometry_info.sigma=argument_list[2].real_reference;
9692 if (attribute_flag[3] != 0)
9693 geometry_info.xi=argument_list[3].real_reference;
9694 if (attribute_flag[4] != 0)
9695 geometry_info.psi=argument_list[4].real_reference;
9696 if (attribute_flag[5] != 0)
9697 channel=(ChannelType) argument_list[5].integer_reference;
9698 channel_mask=SetImageChannelMask(image,channel);
9699 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9700 geometry_info.xi,geometry_info.psi,exception);
9701 if (image != (Image *) NULL)
9702 (void) SetImageChannelMask(image,channel_mask);
9703 break;
9704 }
9705 case 70: /* MotionBlur */
9706 {
9707 if (attribute_flag[0] != 0)
9708 {
9709 flags=ParseGeometry(argument_list[0].string_reference,
9710 &geometry_info);
9711 if ((flags & SigmaValue) == 0)
9712 geometry_info.sigma=1.0;
9713 if ((flags & XiValue) == 0)
9714 geometry_info.xi=1.0;
9715 }
9716 if (attribute_flag[1] != 0)
9717 geometry_info.rho=argument_list[1].real_reference;
9718 if (attribute_flag[2] != 0)
9719 geometry_info.sigma=argument_list[2].real_reference;
9720 if (attribute_flag[3] != 0)
9721 geometry_info.xi=argument_list[3].real_reference;
9722 if (attribute_flag[4] != 0)
9723 channel=(ChannelType) argument_list[4].integer_reference;
9724 channel_mask=SetImageChannelMask(image,channel);
9725 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9726 geometry_info.xi,exception);
9727 if (image != (Image *) NULL)
9728 (void) SetImageChannelMask(image,channel_mask);
9729 break;
9730 }
9731 case 71: /* OrderedDither */
9732 {
9733 if (attribute_flag[0] == 0)
9734 argument_list[0].string_reference="o8x8";
9735 if (attribute_flag[1] != 0)
9736 channel=(ChannelType) argument_list[1].integer_reference;
9737 channel_mask=SetImageChannelMask(image,channel);
9738 (void) OrderedDitherImage(image,argument_list[0].string_reference,
9739 exception);
9740 (void) SetImageChannelMask(image,channel_mask);
9741 break;
9742 }
9743 case 72: /* Shave */
9744 {
9745 if (attribute_flag[0] != 0)
9746 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9747 &geometry,exception);
9748 if (attribute_flag[1] != 0)
9749 geometry.width=argument_list[1].integer_reference;
9750 if (attribute_flag[2] != 0)
9751 geometry.height=argument_list[2].integer_reference;
9752 image=ShaveImage(image,&geometry,exception);
9753 break;
9754 }
9755 case 73: /* Level */
9756 {
9757 double
9758 black_point,
9759 gamma,
9760 white_point;
9761
9762 black_point=0.0;
9763 white_point=(double) image->columns*image->rows;
9764 gamma=1.0;
9765 if (attribute_flag[0] != 0)
9766 {
9767 flags=ParseGeometry(argument_list[0].string_reference,
9768 &geometry_info);
9769 black_point=geometry_info.rho;
9770 if ((flags & SigmaValue) != 0)
9771 white_point=geometry_info.sigma;
9772 if ((flags & XiValue) != 0)
9773 gamma=geometry_info.xi;
9774 if ((flags & PercentValue) != 0)
9775 {
9776 black_point*=(double) (QuantumRange/100.0);
9777 white_point*=(double) (QuantumRange/100.0);
9778 }
9779 if ((flags & SigmaValue) == 0)
9780 white_point=(double) QuantumRange-black_point;
9781 }
9782 if (attribute_flag[1] != 0)
9783 black_point=argument_list[1].real_reference;
9784 if (attribute_flag[2] != 0)
9785 white_point=argument_list[2].real_reference;
9786 if (attribute_flag[3] != 0)
9787 gamma=argument_list[3].real_reference;
9788 if (attribute_flag[4] != 0)
9789 channel=(ChannelType) argument_list[4].integer_reference;
9790 if (attribute_flag[5] != 0)
9791 {
9792 argument_list[0].real_reference=argument_list[5].real_reference;
9793 attribute_flag[0]=attribute_flag[5];
9794 }
9795 channel_mask=SetImageChannelMask(image,channel);
9796 (void) LevelImage(image,black_point,white_point,gamma,exception);
9797 (void) SetImageChannelMask(image,channel_mask);
9798 break;
9799 }
9800 case 74: /* Clip */
9801 {
9802 if (attribute_flag[0] == 0)
9803 argument_list[0].string_reference="#1";
9804 if (attribute_flag[1] == 0)
9805 argument_list[1].integer_reference=MagickTrue;
9806 (void) ClipImagePath(image,argument_list[0].string_reference,
9807 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9808 exception);
9809 break;
9810 }
9811 case 75: /* AffineTransform */
9812 {
9813 DrawInfo
9814 *draw_info;
9815
9816 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9817 (DrawInfo *) NULL);
9818 if (attribute_flag[0] != 0)
9819 {
9820 AV
9821 *av;
9822
9823 av=(AV *) argument_list[0].array_reference;
9824 if ((av_len(av) != 3) && (av_len(av) != 5))
9825 {
9826 ThrowPerlException(exception,OptionError,
9827 "affine matrix must have 4 or 6 elements",PackageName);
9828 goto PerlException;
9829 }
9830 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9831 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9832 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9833 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9834 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9835 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9836 {
9837 ThrowPerlException(exception,OptionError,
9838 "affine matrix is singular",PackageName);
9839 goto PerlException;
9840 }
9841 if (av_len(av) == 5)
9842 {
9843 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9844 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9845 }
9846 }
9847 for (j=1; j < 6; j++)
9848 {
9849 if (attribute_flag[j] == 0)
9850 continue;
9851 value=argument_list[j].string_reference;
9852 angle=argument_list[j].real_reference;
9853 current=draw_info->affine;
9854 GetAffineMatrix(&affine);
9855 switch (j)
9856 {
9857 case 1:
9858 {
9859 /*
9860 Translate.
9861 */
9862 flags=ParseGeometry(value,&geometry_info);
9863 affine.tx=geometry_info.xi;
9864 affine.ty=geometry_info.psi;
9865 if ((flags & PsiValue) == 0)
9866 affine.ty=affine.tx;
9867 break;
9868 }
9869 case 2:
9870 {
9871 /*
9872 Scale.
9873 */
9874 flags=ParseGeometry(value,&geometry_info);
9875 affine.sx=geometry_info.rho;
9876 affine.sy=geometry_info.sigma;
9877 if ((flags & SigmaValue) == 0)
9878 affine.sy=affine.sx;
9879 break;
9880 }
9881 case 3:
9882 {
9883 /*
9884 Rotate.
9885 */
9886 if (angle == 0.0)
9887 break;
9888 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9889 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9890 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9891 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9892 break;
9893 }
9894 case 4:
9895 {
9896 /*
9897 SkewX.
9898 */
9899 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9900 break;
9901 }
9902 case 5:
9903 {
9904 /*
9905 SkewY.
9906 */
9907 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9908 break;
9909 }
9910 }
9911 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9912 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9913 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9914 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9915 draw_info->affine.tx=
9916 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9917 draw_info->affine.ty=
9918 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9919 }
9920 if (attribute_flag[6] != 0)
9921 image->interpolate=(PixelInterpolateMethod)
9922 argument_list[6].integer_reference;
9923 if (attribute_flag[7] != 0)
9924 QueryColorCompliance(argument_list[7].string_reference,
9925 AllCompliance,&image->background_color,exception);
9926 image=AffineTransformImage(image,&draw_info->affine,exception);
9927 draw_info=DestroyDrawInfo(draw_info);
9928 break;
9929 }
9930 case 76: /* Difference */
9931 {
9932 if (attribute_flag[0] == 0)
9933 {
9934 ThrowPerlException(exception,OptionError,
9935 "ReferenceImageRequired",PackageName);
9936 goto PerlException;
9937 }
9938 if (attribute_flag[1] != 0)
9939 image->fuzz=StringToDoubleInterval(
9940 argument_list[1].string_reference,(double) QuantumRange+1.0);
9941 (void) SetImageColorMetric(image,argument_list[0].image_reference,
9942 exception);
9943 break;
9944 }
9945 case 77: /* AdaptiveThreshold */
9946 {
9947 if (attribute_flag[0] != 0)
9948 {
9949 flags=ParseGeometry(argument_list[0].string_reference,
9950 &geometry_info);
9951 if ((flags & PercentValue) != 0)
9952 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9953 }
9954 if (attribute_flag[1] != 0)
9955 geometry_info.rho=argument_list[1].integer_reference;
9956 if (attribute_flag[2] != 0)
9957 geometry_info.sigma=argument_list[2].integer_reference;
9958 if (attribute_flag[3] != 0)
9959 geometry_info.xi=argument_list[3].integer_reference;;
9960 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9961 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9962 break;
9963 }
9964 case 78: /* Resample */
9965 {
9966 size_t
9967 height,
9968 width;
9969
9970 if (attribute_flag[0] != 0)
9971 {
9972 flags=ParseGeometry(argument_list[0].string_reference,
9973 &geometry_info);
9974 if ((flags & SigmaValue) == 0)
9975 geometry_info.sigma=geometry_info.rho;
9976 }
9977 if (attribute_flag[1] != 0)
9978 geometry_info.rho=argument_list[1].real_reference;
9979 if (attribute_flag[2] != 0)
9980 geometry_info.sigma=argument_list[2].real_reference;
9981 if (attribute_flag[3] == 0)
9982 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
9983 if (attribute_flag[4] == 0)
9984 SetImageArtifact(image,"filter:support",
9985 argument_list[4].string_reference);
9986 width=(size_t) (geometry_info.rho*image->columns/
9987 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
9988 height=(size_t) (geometry_info.sigma*image->rows/
9989 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
9990 image=ResizeImage(image,width,height,(FilterType)
9991 argument_list[3].integer_reference,exception);
9992 if (image != (Image *) NULL)
9993 {
9994 image->resolution.x=geometry_info.rho;
9995 image->resolution.y=geometry_info.sigma;
9996 }
9997 break;
9998 }
9999 case 79: /* Describe */
10000 {
10001 if (attribute_flag[0] == 0)
10002 argument_list[0].file_reference=(FILE *) NULL;
10003 if (attribute_flag[1] != 0)
10004 (void) SetImageArtifact(image,"identify:features",
10005 argument_list[1].string_reference);
10006 (void) IdentifyImage(image,argument_list[0].file_reference,
10007 MagickTrue,exception);
10008 break;
10009 }
10010 case 80: /* BlackThreshold */
10011 {
10012 if (attribute_flag[0] == 0)
10013 argument_list[0].string_reference="50%";
10014 if (attribute_flag[2] != 0)
10015 channel=(ChannelType) argument_list[2].integer_reference;
10016 channel_mask=SetImageChannelMask(image,channel);
10017 BlackThresholdImage(image,argument_list[0].string_reference,
10018 exception);
10019 (void) SetImageChannelMask(image,channel_mask);
10020 break;
10021 }
10022 case 81: /* WhiteThreshold */
10023 {
10024 if (attribute_flag[0] == 0)
10025 argument_list[0].string_reference="50%";
10026 if (attribute_flag[2] != 0)
10027 channel=(ChannelType) argument_list[2].integer_reference;
10028 channel_mask=SetImageChannelMask(image,channel);
10029 WhiteThresholdImage(image,argument_list[0].string_reference,
10030 exception);
10031 (void) SetImageChannelMask(image,channel_mask);
10032 break;
10033 }
10034 case 82: /* RotationalBlur */
10035 {
10036 if (attribute_flag[0] != 0)
10037 {
10038 flags=ParseGeometry(argument_list[0].string_reference,
10039 &geometry_info);
10040 }
10041 if (attribute_flag[1] != 0)
10042 geometry_info.rho=argument_list[1].real_reference;
10043 if (attribute_flag[2] != 0)
10044 channel=(ChannelType) argument_list[2].integer_reference;
10045 channel_mask=SetImageChannelMask(image,channel);
10046 image=RotationalBlurImage(image,geometry_info.rho,exception);
10047 if (image != (Image *) NULL)
10048 (void) SetImageChannelMask(image,channel_mask);
10049 break;
10050 }
10051 case 83: /* Thumbnail */
10052 {
10053 if (attribute_flag[0] != 0)
10054 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10055 &geometry,exception);
10056 if (attribute_flag[1] != 0)
10057 geometry.width=argument_list[1].integer_reference;
10058 if (attribute_flag[2] != 0)
10059 geometry.height=argument_list[2].integer_reference;
10060 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10061 break;
10062 }
10063 case 84: /* Strip */
10064 {
10065 (void) StripImage(image,exception);
10066 break;
10067 }
10068 case 85: /* Tint */
10069 {
10070 PixelInfo
10071 tint;
10072
10073 GetPixelInfo(image,&tint);
10074 if (attribute_flag[0] != 0)
10075 (void) QueryColorCompliance(argument_list[0].string_reference,
10076 AllCompliance,&tint,exception);
10077 if (attribute_flag[1] == 0)
10078 argument_list[1].string_reference="100";
10079 image=TintImage(image,argument_list[1].string_reference,&tint,
10080 exception);
10081 break;
10082 }
10083 case 86: /* Channel */
10084 {
10085 if (attribute_flag[0] != 0)
10086 channel=(ChannelType) argument_list[0].integer_reference;
10087 image=SeparateImage(image,channel,exception);
10088 break;
10089 }
10090 case 87: /* Splice */
10091 {
10092 if (attribute_flag[7] != 0)
10093 image->gravity=(GravityType) argument_list[7].integer_reference;
10094 if (attribute_flag[0] != 0)
10095 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10096 &geometry,exception);
10097 if (attribute_flag[1] != 0)
10098 geometry.width=argument_list[1].integer_reference;
10099 if (attribute_flag[2] != 0)
10100 geometry.height=argument_list[2].integer_reference;
10101 if (attribute_flag[3] != 0)
10102 geometry.x=argument_list[3].integer_reference;
10103 if (attribute_flag[4] != 0)
10104 geometry.y=argument_list[4].integer_reference;
10105 if (attribute_flag[5] != 0)
10106 image->fuzz=StringToDoubleInterval(
10107 argument_list[5].string_reference,(double) QuantumRange+1.0);
10108 if (attribute_flag[6] != 0)
10109 (void) QueryColorCompliance(argument_list[6].string_reference,
10110 AllCompliance,&image->background_color,exception);
10111 image=SpliceImage(image,&geometry,exception);
10112 break;
10113 }
10114 case 88: /* Posterize */
10115 {
10116 if (attribute_flag[0] == 0)
10117 argument_list[0].integer_reference=3;
10118 if (attribute_flag[1] == 0)
10119 argument_list[1].integer_reference=0;
10120 (void) PosterizeImage(image,argument_list[0].integer_reference,
10121 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10122 NoDitherMethod,exception);
10123 break;
10124 }
10125 case 89: /* Shadow */
10126 {
10127 if (attribute_flag[0] != 0)
10128 {
10129 flags=ParseGeometry(argument_list[0].string_reference,
10130 &geometry_info);
10131 if ((flags & SigmaValue) == 0)
10132 geometry_info.sigma=1.0;
10133 if ((flags & XiValue) == 0)
10134 geometry_info.xi=4.0;
10135 if ((flags & PsiValue) == 0)
10136 geometry_info.psi=4.0;
10137 }
10138 if (attribute_flag[1] != 0)
10139 geometry_info.rho=argument_list[1].real_reference;
10140 if (attribute_flag[2] != 0)
10141 geometry_info.sigma=argument_list[2].real_reference;
10142 if (attribute_flag[3] != 0)
10143 geometry_info.xi=argument_list[3].integer_reference;
10144 if (attribute_flag[4] != 0)
10145 geometry_info.psi=argument_list[4].integer_reference;
10146 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10147 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10148 ceil(geometry_info.psi-0.5),exception);
10149 break;
10150 }
10151 case 90: /* Identify */
10152 {
10153 if (attribute_flag[0] == 0)
10154 argument_list[0].file_reference=(FILE *) NULL;
10155 if (attribute_flag[1] != 0)
10156 (void) SetImageArtifact(image,"identify:features",
10157 argument_list[1].string_reference);
10158 if ((attribute_flag[2] != 0) &&
10159 (argument_list[2].integer_reference != 0))
10160 (void) SetImageArtifact(image,"identify:unique","true");
10161 (void) IdentifyImage(image,argument_list[0].file_reference,
10162 MagickTrue,exception);
10163 break;
10164 }
10165 case 91: /* SepiaTone */
10166 {
10167 if (attribute_flag[0] == 0)
10168 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10169 image=SepiaToneImage(image,argument_list[0].real_reference,
10170 exception);
10171 break;
10172 }
10173 case 92: /* SigmoidalContrast */
10174 {
10175 MagickBooleanType
10176 sharpen;
10177
10178 if (attribute_flag[0] != 0)
10179 {
10180 flags=ParseGeometry(argument_list[0].string_reference,
10181 &geometry_info);
10182 if ((flags & SigmaValue) == 0)
10183 geometry_info.sigma=QuantumRange/2.0;
10184 if ((flags & PercentValue) != 0)
10185 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10186 }
10187 if (attribute_flag[1] != 0)
10188 geometry_info.rho=argument_list[1].real_reference;
10189 if (attribute_flag[2] != 0)
10190 geometry_info.sigma=argument_list[2].real_reference;
10191 if (attribute_flag[3] != 0)
10192 channel=(ChannelType) argument_list[3].integer_reference;
10193 sharpen=MagickTrue;
10194 if (attribute_flag[4] != 0)
10195 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10196 MagickFalse;
10197 channel_mask=SetImageChannelMask(image,channel);
10198 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10199 geometry_info.sigma,exception);
10200 (void) SetImageChannelMask(image,channel_mask);
10201 break;
10202 }
10203 case 93: /* Extent */
10204 {
10205 if (attribute_flag[7] != 0)
10206 image->gravity=(GravityType) argument_list[7].integer_reference;
10207 if (attribute_flag[0] != 0)
10208 {
10209 int
10210 flags;
10211
10212 flags=ParseGravityGeometry(image,
10213 argument_list[0].string_reference,&geometry,exception);
10214 (void) flags;
10215 if (geometry.width == 0)
10216 geometry.width=image->columns;
10217 if (geometry.height == 0)
10218 geometry.height=image->rows;
10219 }
10220 if (attribute_flag[1] != 0)
10221 geometry.width=argument_list[1].integer_reference;
10222 if (attribute_flag[2] != 0)
10223 geometry.height=argument_list[2].integer_reference;
10224 if (attribute_flag[3] != 0)
10225 geometry.x=argument_list[3].integer_reference;
10226 if (attribute_flag[4] != 0)
10227 geometry.y=argument_list[4].integer_reference;
10228 if (attribute_flag[5] != 0)
10229 image->fuzz=StringToDoubleInterval(
10230 argument_list[5].string_reference,(double) QuantumRange+1.0);
10231 if (attribute_flag[6] != 0)
10232 (void) QueryColorCompliance(argument_list[6].string_reference,
10233 AllCompliance,&image->background_color,exception);
10234 image=ExtentImage(image,&geometry,exception);
10235 break;
10236 }
10237 case 94: /* Vignette */
10238 {
10239 if (attribute_flag[0] != 0)
10240 {
10241 flags=ParseGeometry(argument_list[0].string_reference,
10242 &geometry_info);
10243 if ((flags & SigmaValue) == 0)
10244 geometry_info.sigma=1.0;
10245 if ((flags & XiValue) == 0)
10246 geometry_info.xi=0.1*image->columns;
10247 if ((flags & PsiValue) == 0)
10248 geometry_info.psi=0.1*image->rows;
10249 }
10250 if (attribute_flag[1] != 0)
10251 geometry_info.rho=argument_list[1].real_reference;
10252 if (attribute_flag[2] != 0)
10253 geometry_info.sigma=argument_list[2].real_reference;
10254 if (attribute_flag[3] != 0)
10255 geometry_info.xi=argument_list[3].integer_reference;
10256 if (attribute_flag[4] != 0)
10257 geometry_info.psi=argument_list[4].integer_reference;
10258 if (attribute_flag[5] != 0)
10259 (void) QueryColorCompliance(argument_list[5].string_reference,
10260 AllCompliance,&image->background_color,exception);
10261 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10262 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10263 ceil(geometry_info.psi-0.5),exception);
10264 break;
10265 }
10266 case 95: /* ContrastStretch */
10267 {
10268 double
10269 black_point,
10270 white_point;
10271
10272 black_point=0.0;
10273 white_point=(double) image->columns*image->rows;
10274 if (attribute_flag[0] != 0)
10275 {
10276 flags=ParseGeometry(argument_list[0].string_reference,
10277 &geometry_info);
10278 black_point=geometry_info.rho;
10279 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10280 black_point;
10281 if ((flags & PercentValue) != 0)
10282 {
10283 black_point*=(double) image->columns*image->rows/100.0;
10284 white_point*=(double) image->columns*image->rows/100.0;
10285 }
10286 white_point=(double) image->columns*image->rows-
10287 white_point;
10288 }
10289 if (attribute_flag[1] != 0)
10290 black_point=argument_list[1].real_reference;
10291 if (attribute_flag[2] != 0)
10292 white_point=argument_list[2].real_reference;
10293 if (attribute_flag[4] != 0)
10294 channel=(ChannelType) argument_list[4].integer_reference;
10295 channel_mask=SetImageChannelMask(image,channel);
10296 (void) ContrastStretchImage(image,black_point,white_point,exception);
10297 (void) SetImageChannelMask(image,channel_mask);
10298 break;
10299 }
10300 case 96: /* Sans0 */
10301 {
10302 break;
10303 }
10304 case 97: /* Sans1 */
10305 {
10306 break;
10307 }
10308 case 98: /* AdaptiveSharpen */
10309 {
10310 if (attribute_flag[0] != 0)
10311 {
10312 flags=ParseGeometry(argument_list[0].string_reference,
10313 &geometry_info);
10314 if ((flags & SigmaValue) == 0)
10315 geometry_info.sigma=1.0;
10316 if ((flags & XiValue) == 0)
10317 geometry_info.xi=0.0;
10318 }
10319 if (attribute_flag[1] != 0)
10320 geometry_info.rho=argument_list[1].real_reference;
10321 if (attribute_flag[2] != 0)
10322 geometry_info.sigma=argument_list[2].real_reference;
10323 if (attribute_flag[3] != 0)
10324 geometry_info.xi=argument_list[3].real_reference;
10325 if (attribute_flag[4] != 0)
10326 channel=(ChannelType) argument_list[4].integer_reference;
10327 channel_mask=SetImageChannelMask(image,channel);
10328 image=AdaptiveSharpenImage(image,geometry_info.rho,
10329 geometry_info.sigma,exception);
10330 if (image != (Image *) NULL)
10331 (void) SetImageChannelMask(image,channel_mask);
10332 break;
10333 }
10334 case 99: /* Transpose */
10335 {
10336 image=TransposeImage(image,exception);
10337 break;
10338 }
10339 case 100: /* Tranverse */
10340 {
10341 image=TransverseImage(image,exception);
10342 break;
10343 }
10344 case 101: /* AutoOrient */
10345 {
10346 image=AutoOrientImage(image,image->orientation,exception);
10347 break;
10348 }
10349 case 102: /* AdaptiveBlur */
10350 {
10351 if (attribute_flag[0] != 0)
10352 {
10353 flags=ParseGeometry(argument_list[0].string_reference,
10354 &geometry_info);
10355 if ((flags & SigmaValue) == 0)
10356 geometry_info.sigma=1.0;
10357 if ((flags & XiValue) == 0)
10358 geometry_info.xi=0.0;
10359 }
10360 if (attribute_flag[1] != 0)
10361 geometry_info.rho=argument_list[1].real_reference;
10362 if (attribute_flag[2] != 0)
10363 geometry_info.sigma=argument_list[2].real_reference;
10364 if (attribute_flag[3] != 0)
10365 channel=(ChannelType) argument_list[3].integer_reference;
10366 channel_mask=SetImageChannelMask(image,channel);
10367 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10368 exception);
10369 if (image != (Image *) NULL)
10370 (void) SetImageChannelMask(image,channel_mask);
10371 break;
10372 }
10373 case 103: /* Sketch */
10374 {
10375 if (attribute_flag[0] != 0)
10376 {
10377 flags=ParseGeometry(argument_list[0].string_reference,
10378 &geometry_info);
10379 if ((flags & SigmaValue) == 0)
10380 geometry_info.sigma=1.0;
10381 if ((flags & XiValue) == 0)
10382 geometry_info.xi=1.0;
10383 }
10384 if (attribute_flag[1] != 0)
10385 geometry_info.rho=argument_list[1].real_reference;
10386 if (attribute_flag[2] != 0)
10387 geometry_info.sigma=argument_list[2].real_reference;
10388 if (attribute_flag[3] != 0)
10389 geometry_info.xi=argument_list[3].real_reference;
10390 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10391 geometry_info.xi,exception);
10392 break;
10393 }
10394 case 104: /* UniqueColors */
10395 {
10396 image=UniqueImageColors(image,exception);
10397 break;
10398 }
10399 case 105: /* AdaptiveResize */
10400 {
10401 if (attribute_flag[0] != 0)
10402 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10403 &geometry,exception);
10404 if (attribute_flag[1] != 0)
10405 geometry.width=argument_list[1].integer_reference;
10406 if (attribute_flag[2] != 0)
10407 geometry.height=argument_list[2].integer_reference;
10408 if (attribute_flag[3] != 0)
10409 image->filter=(FilterType) argument_list[4].integer_reference;
10410 if (attribute_flag[4] != 0)
10411 SetImageArtifact(image,"filter:support",
10412 argument_list[4].string_reference);
10413 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10414 exception);
10415 break;
10416 }
10417 case 106: /* ClipMask */
10418 {
10419 Image
10420 *mask_image;
10421
10422 if (attribute_flag[0] == 0)
10423 {
10424 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10425 PackageName);
10426 goto PerlException;
10427 }
10428 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10429 exception);
10430 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
10431 mask_image=DestroyImage(mask_image);
10432 break;
10433 }
10434 case 107: /* LinearStretch */
10435 {
10436 double
10437 black_point,
10438 white_point;
10439
10440 black_point=0.0;
10441 white_point=(double) image->columns*image->rows;
10442 if (attribute_flag[0] != 0)
10443 {
10444 flags=ParseGeometry(argument_list[0].string_reference,
10445 &geometry_info);
10446 if ((flags & SigmaValue) != 0)
10447 white_point=geometry_info.sigma;
10448 if ((flags & PercentValue) != 0)
10449 {
10450 black_point*=(double) image->columns*image->rows/100.0;
10451 white_point*=(double) image->columns*image->rows/100.0;
10452 }
10453 if ((flags & SigmaValue) == 0)
10454 white_point=(double) image->columns*image->rows-black_point;
10455 }
10456 if (attribute_flag[1] != 0)
10457 black_point=argument_list[1].real_reference;
10458 if (attribute_flag[2] != 0)
10459 white_point=argument_list[2].real_reference;
10460 (void) LinearStretchImage(image,black_point,white_point,exception);
10461 break;
10462 }
10463 case 108: /* ColorMatrix */
10464 {
10465 AV
10466 *av;
10467
10468 double
10469 *color_matrix;
10470
10471 KernelInfo
10472 *kernel_info;
10473
10474 size_t
10475 order;
10476
10477 if (attribute_flag[0] == 0)
10478 break;
10479 av=(AV *) argument_list[0].array_reference;
10480 order=(size_t) sqrt(av_len(av)+1);
10481 color_matrix=(double *) AcquireQuantumMemory(order,order*
10482 sizeof(*color_matrix));
10483 if (color_matrix == (double *) NULL)
10484 {
10485 ThrowPerlException(exception,ResourceLimitFatalError,
10486 "MemoryAllocationFailed",PackageName);
10487 goto PerlException;
10488 }
10489 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10490 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10491 for ( ; j < (ssize_t) (order*order); j++)
10492 color_matrix[j]=0.0;
10493 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
10494 if (kernel_info == (KernelInfo *) NULL)
10495 break;
10496 kernel_info->width=order;
10497 kernel_info->height=order;
10498 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10499 order*sizeof(*kernel_info->values));
10500 if (kernel_info->values != (MagickRealType *) NULL)
10501 {
10502 for (i=0; i < (ssize_t) (order*order); i++)
10503 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10504 image=ColorMatrixImage(image,kernel_info,exception);
10505 }
10506 kernel_info=DestroyKernelInfo(kernel_info);
10507 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10508 break;
10509 }
10510 case 109: /* Mask */
10511 {
10512 Image
10513 *mask_image;
10514
10515 if (attribute_flag[0] == 0)
10516 {
10517 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10518 PackageName);
10519 goto PerlException;
10520 }
10521 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10522 MagickTrue,exception);
10523 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
10524 mask_image=DestroyImage(mask_image);
10525 break;
10526 }
10527 case 110: /* Polaroid */
10528 {
10529 char
10530 *caption;
10531
10532 DrawInfo
10533 *draw_info;
10534
10535 double
10536 angle;
10537
10538 PixelInterpolateMethod
10539 method;
10540
10541 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10542 (DrawInfo *) NULL);
10543 caption=(char *) NULL;
10544 if (attribute_flag[0] != 0)
10545 caption=InterpretImageProperties(info ? info->image_info :
10546 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10547 exception);
10548 angle=0.0;
10549 if (attribute_flag[1] != 0)
10550 angle=argument_list[1].real_reference;
10551 if (attribute_flag[2] != 0)
10552 (void) CloneString(&draw_info->font,
10553 argument_list[2].string_reference);
10554 if (attribute_flag[3] != 0)
10555 (void) QueryColorCompliance(argument_list[3].string_reference,
10556 AllCompliance,&draw_info->stroke,exception);
10557 if (attribute_flag[4] != 0)
10558 (void) QueryColorCompliance(argument_list[4].string_reference,
10559 AllCompliance,&draw_info->fill,exception);
10560 if (attribute_flag[5] != 0)
10561 draw_info->stroke_width=argument_list[5].real_reference;
10562 if (attribute_flag[6] != 0)
10563 draw_info->pointsize=argument_list[6].real_reference;
10564 if (attribute_flag[7] != 0)
10565 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10566 if (attribute_flag[8] != 0)
10567 (void) QueryColorCompliance(argument_list[8].string_reference,
10568 AllCompliance,&image->background_color,exception);
10569 method=UndefinedInterpolatePixel;
10570 if (attribute_flag[9] != 0)
10571 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10572 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10573 draw_info=DestroyDrawInfo(draw_info);
10574 if (caption != (char *) NULL)
10575 caption=DestroyString(caption);
10576 break;
10577 }
10578 case 111: /* FloodfillPaint */
10579 {
10580 DrawInfo
10581 *draw_info;
10582
10583 MagickBooleanType
10584 invert;
10585
10586 PixelInfo
10587 target;
10588
10589 draw_info=CloneDrawInfo(info ? info->image_info :
10590 (ImageInfo *) NULL,(DrawInfo *) NULL);
10591 if (attribute_flag[0] != 0)
10592 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10593 &geometry,exception);
10594 if (attribute_flag[1] != 0)
10595 geometry.x=argument_list[1].integer_reference;
10596 if (attribute_flag[2] != 0)
10597 geometry.y=argument_list[2].integer_reference;
10598 if (attribute_flag[3] != 0)
10599 (void) QueryColorCompliance(argument_list[3].string_reference,
10600 AllCompliance,&draw_info->fill,exception);
10601 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10602 geometry.x,geometry.y,&target,exception);
10603 if (attribute_flag[4] != 0)
10604 QueryColorCompliance(argument_list[4].string_reference,
10605 AllCompliance,&target,exception);
10606 if (attribute_flag[5] != 0)
10607 image->fuzz=StringToDoubleInterval(
10608 argument_list[5].string_reference,(double) QuantumRange+1.0);
10609 if (attribute_flag[6] != 0)
10610 channel=(ChannelType) argument_list[6].integer_reference;
10611 invert=MagickFalse;
10612 if (attribute_flag[7] != 0)
10613 invert=(MagickBooleanType) argument_list[7].integer_reference;
10614 channel_mask=SetImageChannelMask(image,channel);
10615 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10616 geometry.y,invert,exception);
10617 (void) SetImageChannelMask(image,channel_mask);
10618 draw_info=DestroyDrawInfo(draw_info);
10619 break;
10620 }
10621 case 112: /* Distort */
10622 {
10623 AV
10624 *av;
10625
10626 double
10627 *coordinates;
10628
10629 DistortMethod
10630 method;
10631
10632 size_t
10633 number_coordinates;
10634
10635 VirtualPixelMethod
10636 virtual_pixel;
10637
10638 if (attribute_flag[0] == 0)
10639 break;
10640 method=UndefinedDistortion;
10641 if (attribute_flag[1] != 0)
10642 method=(DistortMethod) argument_list[1].integer_reference;
10643 av=(AV *) argument_list[0].array_reference;
10644 number_coordinates=(size_t) av_len(av)+1;
10645 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10646 sizeof(*coordinates));
10647 if (coordinates == (double *) NULL)
10648 {
10649 ThrowPerlException(exception,ResourceLimitFatalError,
10650 "MemoryAllocationFailed",PackageName);
10651 goto PerlException;
10652 }
10653 for (j=0; j < (ssize_t) number_coordinates; j++)
10654 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10655 virtual_pixel=UndefinedVirtualPixelMethod;
10656 if (attribute_flag[2] != 0)
10657 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10658 argument_list[2].integer_reference,exception);
10659 image=DistortImage(image,method,number_coordinates,coordinates,
10660 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10661 exception);
10662 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10663 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10664 exception);
10665 coordinates=(double *) RelinquishMagickMemory(coordinates);
10666 break;
10667 }
10668 case 113: /* Clut */
10669 {
10670 PixelInterpolateMethod
10671 method;
10672
10673 if (attribute_flag[0] == 0)
10674 {
10675 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10676 PackageName);
10677 goto PerlException;
10678 }
10679 method=UndefinedInterpolatePixel;
10680 if (attribute_flag[1] != 0)
10681 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10682 if (attribute_flag[2] != 0)
10683 channel=(ChannelType) argument_list[2].integer_reference;
10684 channel_mask=SetImageChannelMask(image,channel);
10685 (void) ClutImage(image,argument_list[0].image_reference,method,
10686 exception);
10687 (void) SetImageChannelMask(image,channel_mask);
10688 break;
10689 }
10690 case 114: /* LiquidRescale */
10691 {
10692 if (attribute_flag[0] != 0)
10693 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10694 &geometry,exception);
10695 if (attribute_flag[1] != 0)
10696 geometry.width=argument_list[1].integer_reference;
10697 if (attribute_flag[2] != 0)
10698 geometry.height=argument_list[2].integer_reference;
10699 if (attribute_flag[3] == 0)
10700 argument_list[3].real_reference=1.0;
10701 if (attribute_flag[4] == 0)
10702 argument_list[4].real_reference=0.0;
10703 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10704 argument_list[3].real_reference,argument_list[4].real_reference,
10705 exception);
10706 break;
10707 }
10708 case 115: /* EncipherImage */
10709 {
10710 (void) EncipherImage(image,argument_list[0].string_reference,
10711 exception);
10712 break;
10713 }
10714 case 116: /* DecipherImage */
10715 {
10716 (void) DecipherImage(image,argument_list[0].string_reference,
10717 exception);
10718 break;
10719 }
10720 case 117: /* Deskew */
10721 {
10722 geometry_info.rho=QuantumRange/2.0;
10723 if (attribute_flag[0] != 0)
10724 flags=ParseGeometry(argument_list[0].string_reference,
10725 &geometry_info);
10726 if (attribute_flag[1] != 0)
10727 geometry_info.rho=StringToDoubleInterval(
10728 argument_list[1].string_reference,(double) QuantumRange+1.0);
10729 image=DeskewImage(image,geometry_info.rho,exception);
10730 break;
10731 }
10732 case 118: /* Remap */
10733 {
10734 QuantizeInfo
10735 *quantize_info;
10736
10737 if (attribute_flag[0] == 0)
10738 {
10739 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10740 PackageName);
10741 goto PerlException;
10742 }
10743 quantize_info=AcquireQuantizeInfo(info->image_info);
10744 if (attribute_flag[1] != 0)
10745 quantize_info->dither_method=(DitherMethod)
10746 argument_list[1].integer_reference;
10747 (void) RemapImages(quantize_info,image,
10748 argument_list[0].image_reference,exception);
10749 quantize_info=DestroyQuantizeInfo(quantize_info);
10750 break;
10751 }
10752 case 119: /* SparseColor */
10753 {
10754 AV
10755 *av;
10756
10757 double
10758 *coordinates;
10759
10760 SparseColorMethod
10761 method;
10762
10763 size_t
10764 number_coordinates;
10765
10766 VirtualPixelMethod
10767 virtual_pixel;
10768
10769 if (attribute_flag[0] == 0)
10770 break;
10771 method=UndefinedColorInterpolate;
10772 if (attribute_flag[1] != 0)
10773 method=(SparseColorMethod) argument_list[1].integer_reference;
10774 av=(AV *) argument_list[0].array_reference;
10775 number_coordinates=(size_t) av_len(av)+1;
10776 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10777 sizeof(*coordinates));
10778 if (coordinates == (double *) NULL)
10779 {
10780 ThrowPerlException(exception,ResourceLimitFatalError,
10781 "MemoryAllocationFailed",PackageName);
10782 goto PerlException;
10783 }
10784 for (j=0; j < (ssize_t) number_coordinates; j++)
10785 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10786 virtual_pixel=UndefinedVirtualPixelMethod;
10787 if (attribute_flag[2] != 0)
10788 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10789 argument_list[2].integer_reference,exception);
10790 if (attribute_flag[3] != 0)
10791 channel=(ChannelType) argument_list[3].integer_reference;
10792 channel_mask=SetImageChannelMask(image,channel);
10793 image=SparseColorImage(image,method,number_coordinates,coordinates,
10794 exception);
10795 if (image != (Image *) NULL)
10796 (void) SetImageChannelMask(image,channel_mask);
10797 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10798 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10799 exception);
10800 coordinates=(double *) RelinquishMagickMemory(coordinates);
10801 break;
10802 }
10803 case 120: /* Function */
10804 {
10805 AV
10806 *av;
10807
10808 double
10809 *parameters;
10810
10811 MagickFunction
10812 function;
10813
10814 size_t
10815 number_parameters;
10816
10817 VirtualPixelMethod
10818 virtual_pixel;
10819
10820 if (attribute_flag[0] == 0)
10821 break;
10822 function=UndefinedFunction;
10823 if (attribute_flag[1] != 0)
10824 function=(MagickFunction) argument_list[1].integer_reference;
10825 av=(AV *) argument_list[0].array_reference;
10826 number_parameters=(size_t) av_len(av)+1;
10827 parameters=(double *) AcquireQuantumMemory(number_parameters,
10828 sizeof(*parameters));
10829 if (parameters == (double *) NULL)
10830 {
10831 ThrowPerlException(exception,ResourceLimitFatalError,
10832 "MemoryAllocationFailed",PackageName);
10833 goto PerlException;
10834 }
10835 for (j=0; j < (ssize_t) number_parameters; j++)
10836 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10837 virtual_pixel=UndefinedVirtualPixelMethod;
10838 if (attribute_flag[2] != 0)
10839 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10840 argument_list[2].integer_reference,exception);
10841 (void) FunctionImage(image,function,number_parameters,parameters,
10842 exception);
10843 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10844 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10845 exception);
10846 parameters=(double *) RelinquishMagickMemory(parameters);
10847 break;
10848 }
10849 case 121: /* SelectiveBlur */
10850 {
10851 if (attribute_flag[0] != 0)
10852 {
10853 flags=ParseGeometry(argument_list[0].string_reference,
10854 &geometry_info);
10855 if ((flags & SigmaValue) == 0)
10856 geometry_info.sigma=1.0;
10857 if ((flags & PercentValue) != 0)
10858 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10859 }
10860 if (attribute_flag[1] != 0)
10861 geometry_info.rho=argument_list[1].real_reference;
10862 if (attribute_flag[2] != 0)
10863 geometry_info.sigma=argument_list[2].real_reference;
10864 if (attribute_flag[3] != 0)
10865 geometry_info.xi=argument_list[3].integer_reference;;
10866 if (attribute_flag[5] != 0)
10867 channel=(ChannelType) argument_list[5].integer_reference;
10868 channel_mask=SetImageChannelMask(image,channel);
10869 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10870 geometry_info.xi,exception);
10871 if (image != (Image *) NULL)
10872 (void) SetImageChannelMask(image,channel_mask);
10873 break;
10874 }
10875 case 122: /* HaldClut */
10876 {
10877 if (attribute_flag[0] == 0)
10878 {
10879 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10880 PackageName);
10881 goto PerlException;
10882 }
10883 if (attribute_flag[1] != 0)
10884 channel=(ChannelType) argument_list[1].integer_reference;
10885 channel_mask=SetImageChannelMask(image,channel);
10886 (void) HaldClutImage(image,argument_list[0].image_reference,
10887 exception);
10888 (void) SetImageChannelMask(image,channel_mask);
10889 break;
10890 }
10891 case 123: /* BlueShift */
10892 {
10893 if (attribute_flag[0] != 0)
10894 (void) ParseGeometry(argument_list[0].string_reference,
10895 &geometry_info);
10896 image=BlueShiftImage(image,geometry_info.rho,exception);
10897 break;
10898 }
10899 case 124: /* ForwardFourierTransformImage */
10900 {
10901 image=ForwardFourierTransformImage(image,
10902 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10903 exception);
10904 break;
10905 }
10906 case 125: /* InverseFourierTransformImage */
10907 {
10908 image=InverseFourierTransformImage(image,image->next,
10909 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10910 exception);
10911 break;
10912 }
10913 case 126: /* ColorDecisionList */
10914 {
10915 if (attribute_flag[0] == 0)
10916 argument_list[0].string_reference=(char *) NULL;
10917 (void) ColorDecisionListImage(image,
10918 argument_list[0].string_reference,exception);
10919 break;
10920 }
10921 case 127: /* AutoGamma */
10922 {
10923 if (attribute_flag[0] != 0)
10924 channel=(ChannelType) argument_list[0].integer_reference;
10925 channel_mask=SetImageChannelMask(image,channel);
10926 (void) AutoGammaImage(image,exception);
10927 (void) SetImageChannelMask(image,channel_mask);
10928 break;
10929 }
10930 case 128: /* AutoLevel */
10931 {
10932 if (attribute_flag[0] != 0)
10933 channel=(ChannelType) argument_list[0].integer_reference;
10934 channel_mask=SetImageChannelMask(image,channel);
10935 (void) AutoLevelImage(image,exception);
10936 (void) SetImageChannelMask(image,channel_mask);
10937 break;
10938 }
10939 case 129: /* LevelColors */
10940 {
10941 PixelInfo
10942 black_point,
10943 white_point;
10944
10945 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10946 exception);
10947 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10948 exception);
10949 if (attribute_flag[1] != 0)
10950 (void) QueryColorCompliance(
10951 argument_list[1].string_reference,AllCompliance,&black_point,
10952 exception);
10953 if (attribute_flag[2] != 0)
10954 (void) QueryColorCompliance(
10955 argument_list[2].string_reference,AllCompliance,&white_point,
10956 exception);
10957 if (attribute_flag[3] != 0)
10958 channel=(ChannelType) argument_list[3].integer_reference;
10959 channel_mask=SetImageChannelMask(image,channel);
10960 (void) LevelImageColors(image,&black_point,&white_point,
10961 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10962 exception);
10963 (void) SetImageChannelMask(image,channel_mask);
10964 break;
10965 }
10966 case 130: /* Clamp */
10967 {
10968 if (attribute_flag[0] != 0)
10969 channel=(ChannelType) argument_list[0].integer_reference;
10970 channel_mask=SetImageChannelMask(image,channel);
10971 (void) ClampImage(image,exception);
10972 (void) SetImageChannelMask(image,channel_mask);
10973 break;
10974 }
10975 case 131: /* BrightnessContrast */
10976 {
10977 double
10978 brightness,
10979 contrast;
10980
10981 brightness=0.0;
10982 contrast=0.0;
10983 if (attribute_flag[0] != 0)
10984 {
10985 flags=ParseGeometry(argument_list[0].string_reference,
10986 &geometry_info);
10987 brightness=geometry_info.rho;
10988 if ((flags & SigmaValue) == 0)
10989 contrast=geometry_info.sigma;
10990 }
10991 if (attribute_flag[1] != 0)
10992 brightness=argument_list[1].real_reference;
10993 if (attribute_flag[2] != 0)
10994 contrast=argument_list[2].real_reference;
10995 if (attribute_flag[4] != 0)
10996 channel=(ChannelType) argument_list[4].integer_reference;
10997 channel_mask=SetImageChannelMask(image,channel);
10998 (void) BrightnessContrastImage(image,brightness,contrast,exception);
10999 (void) SetImageChannelMask(image,channel_mask);
11000 break;
11001 }
11002 case 132: /* Morphology */
11003 {
11004 KernelInfo
11005 *kernel;
11006
11007 MorphologyMethod
11008 method;
11009
11010 ssize_t
11011 iterations;
11012
11013 if (attribute_flag[0] == 0)
11014 break;
11015 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
11016 if (kernel == (KernelInfo *) NULL)
11017 break;
11018 if (attribute_flag[1] != 0)
11019 channel=(ChannelType) argument_list[1].integer_reference;
11020 method=UndefinedMorphology;
11021 if (attribute_flag[2] != 0)
11022 method=argument_list[2].integer_reference;
11023 iterations=1;
11024 if (attribute_flag[3] != 0)
11025 iterations=argument_list[3].integer_reference;
11026 channel_mask=SetImageChannelMask(image,channel);
11027 image=MorphologyImage(image,method,iterations,kernel,exception);
11028 if (image != (Image *) NULL)
11029 (void) SetImageChannelMask(image,channel_mask);
11030 kernel=DestroyKernelInfo(kernel);
11031 break;
11032 }
11033 case 133: /* Mode */
11034 {
11035 if (attribute_flag[0] != 0)
11036 {
11037 flags=ParseGeometry(argument_list[0].string_reference,
11038 &geometry_info);
11039 if ((flags & SigmaValue) == 0)
11040 geometry_info.sigma=1.0;
11041 }
11042 if (attribute_flag[1] != 0)
11043 geometry_info.rho=argument_list[1].real_reference;
11044 if (attribute_flag[2] != 0)
11045 geometry_info.sigma=argument_list[2].real_reference;
11046 if (attribute_flag[3] != 0)
11047 channel=(ChannelType) argument_list[3].integer_reference;
11048 channel_mask=SetImageChannelMask(image,channel);
11049 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11050 (size_t) geometry_info.sigma,exception);
11051 if (image != (Image *) NULL)
11052 (void) SetImageChannelMask(image,channel_mask);
11053 break;
11054 }
11055 case 134: /* Statistic */
11056 {
11057 StatisticType
11058 statistic;
11059
11060 statistic=UndefinedStatistic;
11061 if (attribute_flag[0] != 0)
11062 {
11063 flags=ParseGeometry(argument_list[0].string_reference,
11064 &geometry_info);
11065 if ((flags & SigmaValue) == 0)
11066 geometry_info.sigma=1.0;
11067 }
11068 if (attribute_flag[1] != 0)
11069 geometry_info.rho=argument_list[1].real_reference;
11070 if (attribute_flag[2] != 0)
11071 geometry_info.sigma=argument_list[2].real_reference;
11072 if (attribute_flag[3] != 0)
11073 channel=(ChannelType) argument_list[3].integer_reference;
11074 if (attribute_flag[4] != 0)
11075 statistic=(StatisticType) argument_list[4].integer_reference;
11076 channel_mask=SetImageChannelMask(image,channel);
11077 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11078 (size_t) geometry_info.sigma,exception);
11079 if (image != (Image *) NULL)
11080 (void) SetImageChannelMask(image,channel_mask);
11081 break;
11082 }
11083 case 135: /* Perceptible */
11084 {
11085 double
11086 epsilon;
11087
11088 epsilon=MagickEpsilon;
11089 if (attribute_flag[0] != 0)
11090 epsilon=argument_list[0].real_reference;
11091 if (attribute_flag[1] != 0)
11092 channel=(ChannelType) argument_list[1].integer_reference;
11093 channel_mask=SetImageChannelMask(image,channel);
11094 (void) PerceptibleImage(image,epsilon,exception);
11095 (void) SetImageChannelMask(image,channel_mask);
11096 break;
11097 }
11098 case 136: /* Poly */
11099 {
11100 AV
11101 *av;
11102
11103 double
11104 *terms;
11105
11106 size_t
11107 number_terms;
11108
11109 if (attribute_flag[0] == 0)
11110 break;
11111 if (attribute_flag[1] != 0)
11112 channel=(ChannelType) argument_list[1].integer_reference;
11113 av=(AV *) argument_list[0].array_reference;
11114 number_terms=(size_t) av_len(av);
11115 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11116 if (terms == (double *) NULL)
11117 {
11118 ThrowPerlException(exception,ResourceLimitFatalError,
11119 "MemoryAllocationFailed",PackageName);
11120 goto PerlException;
11121 }
11122 for (j=0; j < av_len(av); j++)
11123 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11124 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11125 terms=(double *) RelinquishMagickMemory(terms);
11126 break;
11127 }
11128 case 137: /* Grayscale */
11129 {
11130 PixelIntensityMethod
11131 method;
11132
11133 method=UndefinedPixelIntensityMethod;
11134 if (attribute_flag[0] != 0)
11135 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11136 (void) GrayscaleImage(image,method,exception);
11137 break;
11138 }
11139 case 138: /* Canny */
11140 {
11141 if (attribute_flag[0] != 0)
11142 {
11143 flags=ParseGeometry(argument_list[0].string_reference,
11144 &geometry_info);
11145 if ((flags & SigmaValue) == 0)
11146 geometry_info.sigma=1.0;
11147 if ((flags & XiValue) == 0)
11148 geometry_info.xi=0.10;
11149 if ((flags & PsiValue) == 0)
11150 geometry_info.psi=0.30;
11151 if ((flags & PercentValue) != 0)
11152 {
11153 geometry_info.xi/=100.0;
11154 geometry_info.psi/=100.0;
11155 }
11156 }
11157 if (attribute_flag[1] != 0)
11158 geometry_info.rho=argument_list[1].real_reference;
11159 if (attribute_flag[2] != 0)
11160 geometry_info.sigma=argument_list[2].real_reference;
11161 if (attribute_flag[3] != 0)
11162 geometry_info.xi=argument_list[3].real_reference;
11163 if (attribute_flag[4] != 0)
11164 geometry_info.psi=argument_list[4].real_reference;
11165 if (attribute_flag[5] != 0)
11166 channel=(ChannelType) argument_list[5].integer_reference;
11167 channel_mask=SetImageChannelMask(image,channel);
11168 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11169 geometry_info.xi,geometry_info.psi,exception);
11170 if (image != (Image *) NULL)
11171 (void) SetImageChannelMask(image,channel_mask);
11172 break;
11173 }
11174 case 139: /* HoughLine */
11175 {
11176 if (attribute_flag[0] != 0)
11177 {
11178 flags=ParseGeometry(argument_list[0].string_reference,
11179 &geometry_info);
11180 if ((flags & SigmaValue) == 0)
11181 geometry_info.sigma=geometry_info.rho;
11182 if ((flags & XiValue) == 0)
11183 geometry_info.xi=40;
11184 }
11185 if (attribute_flag[1] != 0)
11186 geometry_info.rho=(double) argument_list[1].integer_reference;
11187 if (attribute_flag[2] != 0)
11188 geometry_info.sigma=(double) argument_list[2].integer_reference;
11189 if (attribute_flag[3] != 0)
11190 geometry_info.xi=(double) argument_list[3].integer_reference;
11191 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11192 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11193 break;
11194 }
11195 case 140: /* MeanShift */
11196 {
11197 if (attribute_flag[0] != 0)
11198 {
11199 flags=ParseGeometry(argument_list[0].string_reference,
11200 &geometry_info);
11201 if ((flags & SigmaValue) == 0)
11202 geometry_info.sigma=geometry_info.rho;
11203 if ((flags & XiValue) == 0)
11204 geometry_info.xi=0.10*QuantumRange;
11205 if ((flags & PercentValue) != 0)
11206 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
11207 }
11208 if (attribute_flag[1] != 0)
11209 geometry_info.rho=(double) argument_list[1].integer_reference;
11210 if (attribute_flag[2] != 0)
11211 geometry_info.sigma=(double) argument_list[2].integer_reference;
11212 if (attribute_flag[3] != 0)
11213 geometry_info.xi=(double) argument_list[3].integer_reference;
11214 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
11215 geometry_info.sigma,geometry_info.xi,exception);
11216 break;
11217 }
11218 case 141: /* Kuwahara */
11219 {
11220 if (attribute_flag[0] != 0)
11221 {
11222 flags=ParseGeometry(argument_list[0].string_reference,
11223 &geometry_info);
11224 if ((flags & SigmaValue) == 0)
11225 geometry_info.sigma=geometry_info.rho-0.5;
11226 }
11227 if (attribute_flag[1] != 0)
11228 geometry_info.rho=argument_list[1].real_reference;
11229 if (attribute_flag[2] != 0)
11230 geometry_info.sigma=argument_list[2].real_reference;
11231 if (attribute_flag[3] != 0)
11232 channel=(ChannelType) argument_list[3].integer_reference;
11233 channel_mask=SetImageChannelMask(image,channel);
11234 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11235 exception);
11236 if (image != (Image *) NULL)
11237 (void) SetImageChannelMask(image,channel_mask);
11238 break;
11239 }
11240 case 142: /* ConnectedComponent */
11241 {
11242 size_t
11243 connectivity;
11244
11245 connectivity=4;
11246 if (attribute_flag[0] != 0)
11247 connectivity=argument_list[0].integer_reference;
11248 image=ConnectedComponentsImage(image,connectivity,
11249 (CCObjectInfo **) NULL,exception);
11250 break;
11251 }
11252 case 143: /* Copy */
11253 {
11254 Image
11255 *source_image;
11256
11257 OffsetInfo
11258 offset;
11259
11260 RectangleInfo
11261 offset_geometry;
11262
11263 source_image=image;
11264 if (attribute_flag[0] != 0)
11265 source_image=argument_list[0].image_reference;
11266 SetGeometry(source_image,&geometry);
11267 if (attribute_flag[1] != 0)
11268 flags=ParseGravityGeometry(source_image,
11269 argument_list[1].string_reference,&geometry,exception);
11270 if (attribute_flag[2] != 0)
11271 geometry.width=argument_list[2].integer_reference;
11272 if (attribute_flag[3] != 0)
11273 geometry.height=argument_list[3].integer_reference;
11274 if (attribute_flag[4] != 0)
11275 geometry.x=argument_list[4].integer_reference;
11276 if (attribute_flag[5] != 0)
11277 geometry.y=argument_list[5].integer_reference;
11278 if (attribute_flag[6] != 0)
11279 image->gravity=(GravityType) argument_list[6].integer_reference;
11280 SetGeometry(image,&offset_geometry);
11281 if (attribute_flag[7] != 0)
11282 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11283 &offset_geometry,exception);
11284 offset.x=offset_geometry.x;
11285 offset.y=offset_geometry.y;
11286 if (attribute_flag[8] != 0)
11287 offset.x=argument_list[8].integer_reference;
11288 if (attribute_flag[9] != 0)
11289 offset.y=argument_list[9].integer_reference;
11290 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11291 exception);
11292 break;
11293 }
11294 case 144: /* Color */
11295 {
11296 PixelInfo
11297 color;
11298
11299 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
11300 if (attribute_flag[0] != 0)
11301 (void) QueryColorCompliance(argument_list[0].string_reference,
11302 AllCompliance,&color,exception);
11303 (void) SetImageColor(image,&color,exception);
11304 break;
11305 }
11306 case 145: /* WaveletDenoise */
11307 {
11308 if (attribute_flag[0] != 0)
11309 {
11310 flags=ParseGeometry(argument_list[0].string_reference,
11311 &geometry_info);
11312 if ((flags & PercentValue) != 0)
11313 {
11314 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11315 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11316 }
11317 if ((flags & SigmaValue) == 0)
11318 geometry_info.sigma=0.0;
11319 }
11320 if (attribute_flag[1] != 0)
11321 geometry_info.rho=argument_list[1].real_reference;
11322 if (attribute_flag[2] != 0)
11323 geometry_info.sigma=argument_list[2].real_reference;
11324 if (attribute_flag[3] != 0)
11325 channel=(ChannelType) argument_list[3].integer_reference;
11326 channel_mask=SetImageChannelMask(image,channel);
11327 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11328 exception);
11329 if (image != (Image *) NULL)
11330 (void) SetImageChannelMask(image,channel_mask);
11331 break;
11332 }
11333 }
11334 if (next != (Image *) NULL)
11335 (void) CatchImageException(next);
11336 if (region_image != (Image *) NULL)
11337 {
11338 /*
11339 Composite region.
11340 */
11341 status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11342 region_info.x,region_info.y,exception);
11343 (void) status;
11344 (void) CatchImageException(region_image);
11345 image=DestroyImage(image);
11346 image=region_image;
11347 }
11348 if (image != (Image *) NULL)
11349 {
11350 number_images++;
11351 if (next && (next != image))
11352 {
11353 image->next=next->next;
11354 if (image->next != (Image *) NULL)
11355 image->next->previous=image;
11356 DeleteImageFromRegistry(*pv,next);
11357 }
11358 sv_setiv(*pv,PTR2IV(image));
11359 next=image;
11360 }
11361 if (*pv)
11362 pv++;
11363 }
11364
11365 PerlException:
11366 if (reference_vector)
11367 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11368 InheritPerlException(exception,perl_exception);
11369 exception=DestroyExceptionInfo(exception);
11370 sv_setiv(perl_exception,(IV) number_images);
11371 SvPOK_on(perl_exception);
11372 ST(0)=sv_2mortal(perl_exception);
11373 XSRETURN(1);
11374 }
11375
11376 #
11377 ###############################################################################
11378 # #
11379 # #
11380 # #
11381 # M o n t a g e #
11382 # #
11383 # #
11384 # #
11385 ###############################################################################
11386 #
11387 #
11388 void
Montage(ref,...)11389 Montage(ref,...)
11390 Image::Magick ref=NO_INIT
11391 ALIAS:
11392 MontageImage = 1
11393 montage = 2
11394 montageimage = 3
11395 PPCODE:
11396 {
11397 AV
11398 *av;
11399
11400 char
11401 *attribute;
11402
11403 ExceptionInfo
11404 *exception;
11405
11406 HV
11407 *hv;
11408
11409 Image
11410 *image,
11411 *next;
11412
11413 PixelInfo
11414 transparent_color;
11415
11416 MontageInfo
11417 *montage_info;
11418
11419 register ssize_t
11420 i;
11421
11422 ssize_t
11423 sp;
11424
11425 struct PackageInfo
11426 *info;
11427
11428 SV
11429 *av_reference,
11430 *perl_exception,
11431 *reference,
11432 *rv,
11433 *sv;
11434
11435 PERL_UNUSED_VAR(ref);
11436 PERL_UNUSED_VAR(ix);
11437 exception=AcquireExceptionInfo();
11438 perl_exception=newSVpv("",0);
11439 sv=NULL;
11440 attribute=NULL;
11441 if (sv_isobject(ST(0)) == 0)
11442 {
11443 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11444 PackageName);
11445 goto PerlException;
11446 }
11447 reference=SvRV(ST(0));
11448 hv=SvSTASH(reference);
11449 av=newAV();
11450 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11451 SvREFCNT_dec(av);
11452 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11453 if (image == (Image *) NULL)
11454 {
11455 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11456 PackageName);
11457 goto PerlException;
11458 }
11459 /*
11460 Get options.
11461 */
11462 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11463 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11464 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11465 exception);
11466 for (i=2; i < items; i+=2)
11467 {
11468 attribute=(char *) SvPV(ST(i-1),na);
11469 switch (*attribute)
11470 {
11471 case 'B':
11472 case 'b':
11473 {
11474 if (LocaleCompare(attribute,"background") == 0)
11475 {
11476 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11477 &montage_info->background_color,exception);
11478 for (next=image; next; next=next->next)
11479 next->background_color=montage_info->background_color;
11480 break;
11481 }
11482 if (LocaleCompare(attribute,"border") == 0)
11483 {
11484 montage_info->border_width=SvIV(ST(i));
11485 break;
11486 }
11487 if (LocaleCompare(attribute,"bordercolor") == 0)
11488 {
11489 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11490 &montage_info->border_color,exception);
11491 for (next=image; next; next=next->next)
11492 next->border_color=montage_info->border_color;
11493 break;
11494 }
11495 if (LocaleCompare(attribute,"borderwidth") == 0)
11496 {
11497 montage_info->border_width=SvIV(ST(i));
11498 break;
11499 }
11500 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11501 attribute);
11502 break;
11503 }
11504 case 'C':
11505 case 'c':
11506 {
11507 if (LocaleCompare(attribute,"compose") == 0)
11508 {
11509 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11510 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11511 if (sp < 0)
11512 {
11513 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11514 SvPV(ST(i),na));
11515 break;
11516 }
11517 for (next=image; next; next=next->next)
11518 next->compose=(CompositeOperator) sp;
11519 break;
11520 }
11521 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11522 attribute);
11523 break;
11524 }
11525 case 'F':
11526 case 'f':
11527 {
11528 if (LocaleCompare(attribute,"fill") == 0)
11529 {
11530 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11531 &montage_info->fill,exception);
11532 break;
11533 }
11534 if (LocaleCompare(attribute,"font") == 0)
11535 {
11536 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11537 break;
11538 }
11539 if (LocaleCompare(attribute,"frame") == 0)
11540 {
11541 char
11542 *p;
11543
11544 p=SvPV(ST(i),na);
11545 if (IsGeometry(p) == MagickFalse)
11546 {
11547 ThrowPerlException(exception,OptionError,"MissingGeometry",
11548 p);
11549 break;
11550 }
11551 (void) CloneString(&montage_info->frame,p);
11552 if (*p == '\0')
11553 montage_info->frame=(char *) NULL;
11554 break;
11555 }
11556 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11557 attribute);
11558 break;
11559 }
11560 case 'G':
11561 case 'g':
11562 {
11563 if (LocaleCompare(attribute,"geometry") == 0)
11564 {
11565 char
11566 *p;
11567
11568 p=SvPV(ST(i),na);
11569 if (IsGeometry(p) == MagickFalse)
11570 {
11571 ThrowPerlException(exception,OptionError,"MissingGeometry",
11572 p);
11573 break;
11574 }
11575 (void) CloneString(&montage_info->geometry,p);
11576 if (*p == '\0')
11577 montage_info->geometry=(char *) NULL;
11578 break;
11579 }
11580 if (LocaleCompare(attribute,"gravity") == 0)
11581 {
11582 ssize_t
11583 in;
11584
11585 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11586 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11587 if (in < 0)
11588 {
11589 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11590 SvPV(ST(i),na));
11591 return;
11592 }
11593 montage_info->gravity=(GravityType) in;
11594 for (next=image; next; next=next->next)
11595 next->gravity=(GravityType) in;
11596 break;
11597 }
11598 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11599 attribute);
11600 break;
11601 }
11602 case 'L':
11603 case 'l':
11604 {
11605 if (LocaleCompare(attribute,"label") == 0)
11606 {
11607 for (next=image; next; next=next->next)
11608 (void) SetImageProperty(next,"label",InterpretImageProperties(
11609 info ? info->image_info : (ImageInfo *) NULL,next,
11610 SvPV(ST(i),na),exception),exception);
11611 break;
11612 }
11613 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11614 attribute);
11615 break;
11616 }
11617 case 'M':
11618 case 'm':
11619 {
11620 if (LocaleCompare(attribute,"mattecolor") == 0)
11621 {
11622 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11623 &montage_info->alpha_color,exception);
11624 for (next=image; next; next=next->next)
11625 next->alpha_color=montage_info->alpha_color;
11626 break;
11627 }
11628 if (LocaleCompare(attribute,"mode") == 0)
11629 {
11630 ssize_t
11631 in;
11632
11633 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11634 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11635 switch (in)
11636 {
11637 default:
11638 {
11639 ThrowPerlException(exception,OptionError,
11640 "UnrecognizedModeType",SvPV(ST(i),na));
11641 break;
11642 }
11643 case FrameMode:
11644 {
11645 (void) CloneString(&montage_info->frame,"15x15+3+3");
11646 montage_info->shadow=MagickTrue;
11647 break;
11648 }
11649 case UnframeMode:
11650 {
11651 montage_info->frame=(char *) NULL;
11652 montage_info->shadow=MagickFalse;
11653 montage_info->border_width=0;
11654 break;
11655 }
11656 case ConcatenateMode:
11657 {
11658 montage_info->frame=(char *) NULL;
11659 montage_info->shadow=MagickFalse;
11660 (void) CloneString(&montage_info->geometry,"+0+0");
11661 montage_info->border_width=0;
11662 }
11663 }
11664 break;
11665 }
11666 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11667 attribute);
11668 break;
11669 }
11670 case 'P':
11671 case 'p':
11672 {
11673 if (LocaleCompare(attribute,"pointsize") == 0)
11674 {
11675 montage_info->pointsize=SvIV(ST(i));
11676 break;
11677 }
11678 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11679 attribute);
11680 break;
11681 }
11682 case 'S':
11683 case 's':
11684 {
11685 if (LocaleCompare(attribute,"shadow") == 0)
11686 {
11687 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11688 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11689 if (sp < 0)
11690 {
11691 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11692 SvPV(ST(i),na));
11693 break;
11694 }
11695 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11696 break;
11697 }
11698 if (LocaleCompare(attribute,"stroke") == 0)
11699 {
11700 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11701 &montage_info->stroke,exception);
11702 break;
11703 }
11704 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11705 attribute);
11706 break;
11707 }
11708 case 'T':
11709 case 't':
11710 {
11711 if (LocaleCompare(attribute,"texture") == 0)
11712 {
11713 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11714 break;
11715 }
11716 if (LocaleCompare(attribute,"tile") == 0)
11717 {
11718 char *p=SvPV(ST(i),na);
11719 if (IsGeometry(p) == MagickFalse)
11720 {
11721 ThrowPerlException(exception,OptionError,"MissingGeometry",
11722 p);
11723 break;
11724 }
11725 (void) CloneString(&montage_info->tile,p);
11726 if (*p == '\0')
11727 montage_info->tile=(char *) NULL;
11728 break;
11729 }
11730 if (LocaleCompare(attribute,"title") == 0)
11731 {
11732 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11733 break;
11734 }
11735 if (LocaleCompare(attribute,"transparent") == 0)
11736 {
11737 PixelInfo
11738 transparent_color;
11739
11740 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11741 &transparent_color,exception);
11742 for (next=image; next; next=next->next)
11743 (void) TransparentPaintImage(next,&transparent_color,
11744 TransparentAlpha,MagickFalse,exception);
11745 break;
11746 }
11747 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11748 attribute);
11749 break;
11750 }
11751 default:
11752 {
11753 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11754 attribute);
11755 break;
11756 }
11757 }
11758 }
11759 image=MontageImageList(info->image_info,montage_info,image,exception);
11760 montage_info=DestroyMontageInfo(montage_info);
11761 if (image == (Image *) NULL)
11762 goto PerlException;
11763 if (transparent_color.alpha != TransparentAlpha)
11764 for (next=image; next; next=next->next)
11765 (void) TransparentPaintImage(next,&transparent_color,
11766 TransparentAlpha,MagickFalse,exception);
11767 for ( ; image; image=image->next)
11768 {
11769 AddImageToRegistry(sv,image);
11770 rv=newRV(sv);
11771 av_push(av,sv_bless(rv,hv));
11772 SvREFCNT_dec(sv);
11773 }
11774 exception=DestroyExceptionInfo(exception);
11775 ST(0)=av_reference;
11776 SvREFCNT_dec(perl_exception);
11777 XSRETURN(1);
11778
11779 PerlException:
11780 InheritPerlException(exception,perl_exception);
11781 exception=DestroyExceptionInfo(exception);
11782 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11783 SvPOK_on(perl_exception);
11784 ST(0)=sv_2mortal(perl_exception);
11785 XSRETURN(1);
11786 }
11787
11788 #
11789 ###############################################################################
11790 # #
11791 # #
11792 # #
11793 # M o r p h #
11794 # #
11795 # #
11796 # #
11797 ###############################################################################
11798 #
11799 #
11800 void
Morph(ref,...)11801 Morph(ref,...)
11802 Image::Magick ref=NO_INIT
11803 ALIAS:
11804 MorphImage = 1
11805 morph = 2
11806 morphimage = 3
11807 PPCODE:
11808 {
11809 AV
11810 *av;
11811
11812 char
11813 *attribute;
11814
11815 ExceptionInfo
11816 *exception;
11817
11818 HV
11819 *hv;
11820
11821 Image
11822 *image;
11823
11824 register ssize_t
11825 i;
11826
11827 ssize_t
11828 number_frames;
11829
11830 struct PackageInfo
11831 *info;
11832
11833 SV
11834 *av_reference,
11835 *perl_exception,
11836 *reference,
11837 *rv,
11838 *sv;
11839
11840 PERL_UNUSED_VAR(ref);
11841 PERL_UNUSED_VAR(ix);
11842 exception=AcquireExceptionInfo();
11843 perl_exception=newSVpv("",0);
11844 sv=NULL;
11845 av=NULL;
11846 attribute=NULL;
11847 if (sv_isobject(ST(0)) == 0)
11848 {
11849 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11850 PackageName);
11851 goto PerlException;
11852 }
11853 reference=SvRV(ST(0));
11854 hv=SvSTASH(reference);
11855 av=newAV();
11856 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11857 SvREFCNT_dec(av);
11858 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11859 if (image == (Image *) NULL)
11860 {
11861 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11862 PackageName);
11863 goto PerlException;
11864 }
11865 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11866 /*
11867 Get attribute.
11868 */
11869 number_frames=30;
11870 for (i=2; i < items; i+=2)
11871 {
11872 attribute=(char *) SvPV(ST(i-1),na);
11873 switch (*attribute)
11874 {
11875 case 'F':
11876 case 'f':
11877 {
11878 if (LocaleCompare(attribute,"frames") == 0)
11879 {
11880 number_frames=SvIV(ST(i));
11881 break;
11882 }
11883 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11884 attribute);
11885 break;
11886 }
11887 default:
11888 {
11889 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11890 attribute);
11891 break;
11892 }
11893 }
11894 }
11895 image=MorphImages(image,number_frames,exception);
11896 if (image == (Image *) NULL)
11897 goto PerlException;
11898 for ( ; image; image=image->next)
11899 {
11900 AddImageToRegistry(sv,image);
11901 rv=newRV(sv);
11902 av_push(av,sv_bless(rv,hv));
11903 SvREFCNT_dec(sv);
11904 }
11905 exception=DestroyExceptionInfo(exception);
11906 ST(0)=av_reference;
11907 SvREFCNT_dec(perl_exception); /* can't return warning messages */
11908 XSRETURN(1);
11909
11910 PerlException:
11911 InheritPerlException(exception,perl_exception);
11912 exception=DestroyExceptionInfo(exception);
11913 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11914 SvPOK_on(perl_exception);
11915 ST(0)=sv_2mortal(perl_exception);
11916 XSRETURN(1);
11917 }
11918
11919 #
11920 ###############################################################################
11921 # #
11922 # #
11923 # #
11924 # M o s a i c #
11925 # #
11926 # #
11927 # #
11928 ###############################################################################
11929 #
11930 #
11931 void
Mosaic(ref)11932 Mosaic(ref)
11933 Image::Magick ref=NO_INIT
11934 ALIAS:
11935 MosaicImage = 1
11936 mosaic = 2
11937 mosaicimage = 3
11938 PPCODE:
11939 {
11940 AV
11941 *av;
11942
11943 ExceptionInfo
11944 *exception;
11945
11946 HV
11947 *hv;
11948
11949 Image
11950 *image;
11951
11952 struct PackageInfo
11953 *info;
11954
11955 SV
11956 *perl_exception,
11957 *reference,
11958 *rv,
11959 *sv;
11960
11961 PERL_UNUSED_VAR(ref);
11962 PERL_UNUSED_VAR(ix);
11963 exception=AcquireExceptionInfo();
11964 perl_exception=newSVpv("",0);
11965 sv=NULL;
11966 if (sv_isobject(ST(0)) == 0)
11967 {
11968 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11969 PackageName);
11970 goto PerlException;
11971 }
11972 reference=SvRV(ST(0));
11973 hv=SvSTASH(reference);
11974 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11975 if (image == (Image *) NULL)
11976 {
11977 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11978 PackageName);
11979 goto PerlException;
11980 }
11981 image=MergeImageLayers(image,MosaicLayer,exception);
11982 /*
11983 Create blessed Perl array for the returned image.
11984 */
11985 av=newAV();
11986 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11987 SvREFCNT_dec(av);
11988 AddImageToRegistry(sv,image);
11989 rv=newRV(sv);
11990 av_push(av,sv_bless(rv,hv));
11991 SvREFCNT_dec(sv);
11992 (void) CopyMagickString(info->image_info->filename,image->filename,
11993 MagickPathExtent);
11994 SetImageInfo(info->image_info,0,exception);
11995 exception=DestroyExceptionInfo(exception);
11996 SvREFCNT_dec(perl_exception);
11997 XSRETURN(1);
11998
11999 PerlException:
12000 InheritPerlException(exception,perl_exception);
12001 exception=DestroyExceptionInfo(exception);
12002 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12003 SvPOK_on(perl_exception); /* return messages in string context */
12004 ST(0)=sv_2mortal(perl_exception);
12005 XSRETURN(1);
12006 }
12007
12008 #
12009 ###############################################################################
12010 # #
12011 # #
12012 # #
12013 # P i n g #
12014 # #
12015 # #
12016 # #
12017 ###############################################################################
12018 #
12019 #
12020 void
Ping(ref,...)12021 Ping(ref,...)
12022 Image::Magick ref=NO_INIT
12023 ALIAS:
12024 PingImage = 1
12025 ping = 2
12026 pingimage = 3
12027 PPCODE:
12028 {
12029 AV
12030 *av;
12031
12032 char
12033 **keep,
12034 **list;
12035
12036 ExceptionInfo
12037 *exception;
12038
12039 Image
12040 *image,
12041 *next;
12042
12043 int
12044 n;
12045
12046 MagickBooleanType
12047 status;
12048
12049 register char
12050 **p;
12051
12052 register ssize_t
12053 i;
12054
12055 ssize_t
12056 ac;
12057
12058 STRLEN
12059 *length;
12060
12061 struct PackageInfo
12062 *info,
12063 *package_info;
12064
12065 SV
12066 *perl_exception,
12067 *reference;
12068
12069 size_t
12070 count;
12071
12072 PERL_UNUSED_VAR(ref);
12073 PERL_UNUSED_VAR(ix);
12074 exception=AcquireExceptionInfo();
12075 perl_exception=newSVpv("",0);
12076 package_info=(struct PackageInfo *) NULL;
12077 ac=(items < 2) ? 1 : items-1;
12078 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12079 keep=list;
12080 length=(STRLEN *) NULL;
12081 if (list == (char **) NULL)
12082 {
12083 ThrowPerlException(exception,ResourceLimitError,
12084 "MemoryAllocationFailed",PackageName);
12085 goto PerlException;
12086 }
12087 keep=list;
12088 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12089 if (length == (STRLEN *) NULL)
12090 {
12091 ThrowPerlException(exception,ResourceLimitError,
12092 "MemoryAllocationFailed",PackageName);
12093 goto PerlException;
12094 }
12095 if (sv_isobject(ST(0)) == 0)
12096 {
12097 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12098 PackageName);
12099 goto PerlException;
12100 }
12101 reference=SvRV(ST(0));
12102 if (SvTYPE(reference) != SVt_PVAV)
12103 {
12104 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12105 PackageName);
12106 goto PerlException;
12107 }
12108 av=(AV *) reference;
12109 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12110 exception);
12111 package_info=ClonePackageInfo(info,exception);
12112 n=1;
12113 if (items <= 1)
12114 *list=(char *) (*package_info->image_info->filename ?
12115 package_info->image_info->filename : "XC:black");
12116 else
12117 for (n=0, i=0; i < ac; i++)
12118 {
12119 list[n]=(char *) SvPV(ST(i+1),length[n]);
12120 if ((items >= 3) && strEQcase(list[n],"blob"))
12121 {
12122 void
12123 *blob;
12124
12125 i++;
12126 blob=(void *) (SvPV(ST(i+1),length[n]));
12127 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12128 }
12129 if ((items >= 3) && strEQcase(list[n],"filename"))
12130 continue;
12131 if ((items >= 3) && strEQcase(list[n],"file"))
12132 {
12133 FILE
12134 *file;
12135
12136 PerlIO
12137 *io_info;
12138
12139 i++;
12140 io_info=IoIFP(sv_2io(ST(i+1)));
12141 if (io_info == (PerlIO *) NULL)
12142 {
12143 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12144 PackageName);
12145 continue;
12146 }
12147 file=PerlIO_findFILE(io_info);
12148 if (file == (FILE *) NULL)
12149 {
12150 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12151 PackageName);
12152 continue;
12153 }
12154 SetImageInfoFile(package_info->image_info,file);
12155 }
12156 if ((items >= 3) && strEQcase(list[n],"magick"))
12157 continue;
12158 n++;
12159 }
12160 list[n]=(char *) NULL;
12161 keep=list;
12162 status=ExpandFilenames(&n,&list);
12163 if (status == MagickFalse)
12164 {
12165 ThrowPerlException(exception,ResourceLimitError,
12166 "MemoryAllocationFailed",PackageName);
12167 goto PerlException;
12168 }
12169 count=0;
12170 for (i=0; i < n; i++)
12171 {
12172 (void) CopyMagickString(package_info->image_info->filename,list[i],
12173 MagickPathExtent);
12174 image=PingImage(package_info->image_info,exception);
12175 if (image == (Image *) NULL)
12176 break;
12177 if ((package_info->image_info->file != (FILE *) NULL) ||
12178 (package_info->image_info->blob != (void *) NULL))
12179 DisassociateImageStream(image);
12180 count+=GetImageListLength(image);
12181 EXTEND(sp,4*count);
12182 for (next=image; next; next=next->next)
12183 {
12184 PUSHs(sv_2mortal(newSViv(next->columns)));
12185 PUSHs(sv_2mortal(newSViv(next->rows)));
12186 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12187 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12188 }
12189 image=DestroyImageList(image);
12190 }
12191 /*
12192 Free resources.
12193 */
12194 for (i=0; i < n; i++)
12195 if (list[i] != (char *) NULL)
12196 for (p=keep; list[i] != *p++; )
12197 if (*p == NULL)
12198 {
12199 list[i]=(char *) RelinquishMagickMemory(list[i]);
12200 break;
12201 }
12202
12203 PerlException:
12204 if (package_info != (struct PackageInfo *) NULL)
12205 DestroyPackageInfo(package_info);
12206 if (list && (list != keep))
12207 list=(char **) RelinquishMagickMemory(list);
12208 if (keep)
12209 keep=(char **) RelinquishMagickMemory(keep);
12210 if (length)
12211 length=(STRLEN *) RelinquishMagickMemory(length);
12212 InheritPerlException(exception,perl_exception);
12213 exception=DestroyExceptionInfo(exception);
12214 SvREFCNT_dec(perl_exception); /* throw away all errors */
12215 }
12216
12217 #
12218 ###############################################################################
12219 # #
12220 # #
12221 # #
12222 # P r e v i e w #
12223 # #
12224 # #
12225 # #
12226 ###############################################################################
12227 #
12228 #
12229 void
Preview(ref,...)12230 Preview(ref,...)
12231 Image::Magick ref=NO_INIT
12232 ALIAS:
12233 PreviewImage = 1
12234 preview = 2
12235 previewimage = 3
12236 PPCODE:
12237 {
12238 AV
12239 *av;
12240
12241 ExceptionInfo
12242 *exception;
12243
12244 HV
12245 *hv;
12246
12247 Image
12248 *image,
12249 *preview_image;
12250
12251 PreviewType
12252 preview_type;
12253
12254 struct PackageInfo
12255 *info;
12256
12257 SV
12258 *av_reference,
12259 *perl_exception,
12260 *reference,
12261 *rv,
12262 *sv;
12263
12264 PERL_UNUSED_VAR(ref);
12265 PERL_UNUSED_VAR(ix);
12266 exception=AcquireExceptionInfo();
12267 perl_exception=newSVpv("",0);
12268 sv=NULL;
12269 av=NULL;
12270 if (sv_isobject(ST(0)) == 0)
12271 {
12272 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12273 PackageName);
12274 goto PerlException;
12275 }
12276 reference=SvRV(ST(0));
12277 hv=SvSTASH(reference);
12278 av=newAV();
12279 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12280 SvREFCNT_dec(av);
12281 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12282 if (image == (Image *) NULL)
12283 {
12284 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12285 PackageName);
12286 goto PerlException;
12287 }
12288 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12289 preview_type=GammaPreview;
12290 if (items > 1)
12291 preview_type=(PreviewType)
12292 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12293 for ( ; image; image=image->next)
12294 {
12295 preview_image=PreviewImage(image,preview_type,exception);
12296 if (preview_image == (Image *) NULL)
12297 goto PerlException;
12298 AddImageToRegistry(sv,preview_image);
12299 rv=newRV(sv);
12300 av_push(av,sv_bless(rv,hv));
12301 SvREFCNT_dec(sv);
12302 }
12303 exception=DestroyExceptionInfo(exception);
12304 ST(0)=av_reference;
12305 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12306 XSRETURN(1);
12307
12308 PerlException:
12309 InheritPerlException(exception,perl_exception);
12310 exception=DestroyExceptionInfo(exception);
12311 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12312 SvPOK_on(perl_exception);
12313 ST(0)=sv_2mortal(perl_exception);
12314 XSRETURN(1);
12315 }
12316
12317 #
12318 ###############################################################################
12319 # #
12320 # #
12321 # #
12322 # Q u e r y C o l o r #
12323 # #
12324 # #
12325 # #
12326 ###############################################################################
12327 #
12328 #
12329 void
QueryColor(ref,...)12330 QueryColor(ref,...)
12331 Image::Magick ref=NO_INIT
12332 ALIAS:
12333 querycolor = 1
12334 PPCODE:
12335 {
12336 char
12337 *name;
12338
12339 ExceptionInfo
12340 *exception;
12341
12342 PixelInfo
12343 color;
12344
12345 register ssize_t
12346 i;
12347
12348 SV
12349 *perl_exception;
12350
12351 PERL_UNUSED_VAR(ref);
12352 PERL_UNUSED_VAR(ix);
12353 exception=AcquireExceptionInfo();
12354 perl_exception=newSVpv("",0);
12355 if (items == 1)
12356 {
12357 const ColorInfo
12358 **colorlist;
12359
12360 size_t
12361 colors;
12362
12363 colorlist=GetColorInfoList("*",&colors,exception);
12364 EXTEND(sp,colors);
12365 for (i=0; i < (ssize_t) colors; i++)
12366 {
12367 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12368 }
12369 colorlist=(const ColorInfo **)
12370 RelinquishMagickMemory((ColorInfo **) colorlist);
12371 goto PerlException;
12372 }
12373 EXTEND(sp,5*items);
12374 for (i=1; i < items; i++)
12375 {
12376 name=(char *) SvPV(ST(i),na);
12377 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12378 {
12379 PUSHs(&sv_undef);
12380 continue;
12381 }
12382 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12383 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12384 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12385 if (color.colorspace == CMYKColorspace)
12386 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
12387 if (color.alpha_trait != UndefinedPixelTrait)
12388 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12389 }
12390
12391 PerlException:
12392 InheritPerlException(exception,perl_exception);
12393 exception=DestroyExceptionInfo(exception);
12394 SvREFCNT_dec(perl_exception);
12395 }
12396
12397 #
12398 ###############################################################################
12399 # #
12400 # #
12401 # #
12402 # Q u e r y C o l o r N a m e #
12403 # #
12404 # #
12405 # #
12406 ###############################################################################
12407 #
12408 #
12409 void
QueryColorname(ref,...)12410 QueryColorname(ref,...)
12411 Image::Magick ref=NO_INIT
12412 ALIAS:
12413 querycolorname = 1
12414 PPCODE:
12415 {
12416 AV
12417 *av;
12418
12419 char
12420 message[MagickPathExtent];
12421
12422 ExceptionInfo
12423 *exception;
12424
12425 Image
12426 *image;
12427
12428 PixelInfo
12429 target_color;
12430
12431 register ssize_t
12432 i;
12433
12434 struct PackageInfo
12435 *info;
12436
12437 SV
12438 *perl_exception,
12439 *reference; /* reference is the SV* of ref=SvIV(reference) */
12440
12441 PERL_UNUSED_VAR(ref);
12442 PERL_UNUSED_VAR(ix);
12443 exception=AcquireExceptionInfo();
12444 perl_exception=newSVpv("",0);
12445 reference=SvRV(ST(0));
12446 av=(AV *) reference;
12447 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12448 exception);
12449 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12450 if (image == (Image *) NULL)
12451 {
12452 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12453 PackageName);
12454 goto PerlException;
12455 }
12456 EXTEND(sp,items);
12457 for (i=1; i < items; i++)
12458 {
12459 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12460 exception);
12461 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12462 exception);
12463 PUSHs(sv_2mortal(newSVpv(message,0)));
12464 }
12465
12466 PerlException:
12467 InheritPerlException(exception,perl_exception);
12468 exception=DestroyExceptionInfo(exception);
12469 SvREFCNT_dec(perl_exception);
12470 }
12471
12472 #
12473 ###############################################################################
12474 # #
12475 # #
12476 # #
12477 # Q u e r y F o n t #
12478 # #
12479 # #
12480 # #
12481 ###############################################################################
12482 #
12483 #
12484 void
QueryFont(ref,...)12485 QueryFont(ref,...)
12486 Image::Magick ref=NO_INIT
12487 ALIAS:
12488 queryfont = 1
12489 PPCODE:
12490 {
12491 char
12492 *name,
12493 message[MagickPathExtent];
12494
12495 ExceptionInfo
12496 *exception;
12497
12498 register ssize_t
12499 i;
12500
12501 SV
12502 *perl_exception;
12503
12504 volatile const TypeInfo
12505 *type_info;
12506
12507 PERL_UNUSED_VAR(ref);
12508 PERL_UNUSED_VAR(ix);
12509 exception=AcquireExceptionInfo();
12510 perl_exception=newSVpv("",0);
12511 if (items == 1)
12512 {
12513 const TypeInfo
12514 **typelist;
12515
12516 size_t
12517 types;
12518
12519 typelist=GetTypeInfoList("*",&types,exception);
12520 EXTEND(sp,types);
12521 for (i=0; i < (ssize_t) types; i++)
12522 {
12523 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12524 }
12525 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12526 typelist);
12527 goto PerlException;
12528 }
12529 EXTEND(sp,10*items);
12530 for (i=1; i < items; i++)
12531 {
12532 name=(char *) SvPV(ST(i),na);
12533 type_info=GetTypeInfo(name,exception);
12534 if (type_info == (TypeInfo *) NULL)
12535 {
12536 PUSHs(&sv_undef);
12537 continue;
12538 }
12539 if (type_info->name == (char *) NULL)
12540 PUSHs(&sv_undef);
12541 else
12542 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12543 if (type_info->description == (char *) NULL)
12544 PUSHs(&sv_undef);
12545 else
12546 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12547 if (type_info->family == (char *) NULL)
12548 PUSHs(&sv_undef);
12549 else
12550 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12551 if (type_info->style == UndefinedStyle)
12552 PUSHs(&sv_undef);
12553 else
12554 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12555 type_info->style),0)));
12556 if (type_info->stretch == UndefinedStretch)
12557 PUSHs(&sv_undef);
12558 else
12559 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12560 type_info->stretch),0)));
12561 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
12562 type_info->weight);
12563 PUSHs(sv_2mortal(newSVpv(message,0)));
12564 if (type_info->encoding == (char *) NULL)
12565 PUSHs(&sv_undef);
12566 else
12567 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12568 if (type_info->foundry == (char *) NULL)
12569 PUSHs(&sv_undef);
12570 else
12571 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12572 if (type_info->format == (char *) NULL)
12573 PUSHs(&sv_undef);
12574 else
12575 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12576 if (type_info->metrics == (char *) NULL)
12577 PUSHs(&sv_undef);
12578 else
12579 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12580 if (type_info->glyphs == (char *) NULL)
12581 PUSHs(&sv_undef);
12582 else
12583 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12584 }
12585
12586 PerlException:
12587 InheritPerlException(exception,perl_exception);
12588 exception=DestroyExceptionInfo(exception);
12589 SvREFCNT_dec(perl_exception);
12590 }
12591
12592 #
12593 ###############################################################################
12594 # #
12595 # #
12596 # #
12597 # Q u e r y F o n t M e t r i c s #
12598 # #
12599 # #
12600 # #
12601 ###############################################################################
12602 #
12603 #
12604 void
QueryFontMetrics(ref,...)12605 QueryFontMetrics(ref,...)
12606 Image::Magick ref=NO_INIT
12607 ALIAS:
12608 queryfontmetrics = 1
12609 PPCODE:
12610 {
12611 AffineMatrix
12612 affine,
12613 current;
12614
12615 AV
12616 *av;
12617
12618 char
12619 *attribute;
12620
12621 double
12622 x,
12623 y;
12624
12625 DrawInfo
12626 *draw_info;
12627
12628 ExceptionInfo
12629 *exception;
12630
12631 GeometryInfo
12632 geometry_info;
12633
12634 Image
12635 *image;
12636
12637 MagickBooleanType
12638 status;
12639
12640 MagickStatusType
12641 flags;
12642
12643 register ssize_t
12644 i;
12645
12646 ssize_t
12647 type;
12648
12649 struct PackageInfo
12650 *info,
12651 *package_info;
12652
12653 SV
12654 *perl_exception,
12655 *reference; /* reference is the SV* of ref=SvIV(reference) */
12656
12657 TypeMetric
12658 metrics;
12659
12660 PERL_UNUSED_VAR(ref);
12661 PERL_UNUSED_VAR(ix);
12662 exception=AcquireExceptionInfo();
12663 package_info=(struct PackageInfo *) NULL;
12664 perl_exception=newSVpv("",0);
12665 reference=SvRV(ST(0));
12666 av=(AV *) reference;
12667 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12668 exception);
12669 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12670 if (image == (Image *) NULL)
12671 {
12672 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12673 PackageName);
12674 goto PerlException;
12675 }
12676 package_info=ClonePackageInfo(info,exception);
12677 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12678 CloneString(&draw_info->text,"");
12679 current=draw_info->affine;
12680 GetAffineMatrix(&affine);
12681 x=0.0;
12682 y=0.0;
12683 EXTEND(sp,7*items);
12684 for (i=2; i < items; i+=2)
12685 {
12686 attribute=(char *) SvPV(ST(i-1),na);
12687 switch (*attribute)
12688 {
12689 case 'A':
12690 case 'a':
12691 {
12692 if (LocaleCompare(attribute,"antialias") == 0)
12693 {
12694 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12695 SvPV(ST(i),na));
12696 if (type < 0)
12697 {
12698 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12699 SvPV(ST(i),na));
12700 break;
12701 }
12702 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12703 break;
12704 }
12705 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12706 attribute);
12707 break;
12708 }
12709 case 'd':
12710 case 'D':
12711 {
12712 if (LocaleCompare(attribute,"density") == 0)
12713 {
12714 CloneString(&draw_info->density,SvPV(ST(i),na));
12715 break;
12716 }
12717 if (LocaleCompare(attribute,"direction") == 0)
12718 {
12719 draw_info->direction=(DirectionType) ParseCommandOption(
12720 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12721 break;
12722 }
12723 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12724 attribute);
12725 break;
12726 }
12727 case 'e':
12728 case 'E':
12729 {
12730 if (LocaleCompare(attribute,"encoding") == 0)
12731 {
12732 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12733 break;
12734 }
12735 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12736 attribute);
12737 break;
12738 }
12739 case 'f':
12740 case 'F':
12741 {
12742 if (LocaleCompare(attribute,"family") == 0)
12743 {
12744 CloneString(&draw_info->family,SvPV(ST(i),na));
12745 break;
12746 }
12747 if (LocaleCompare(attribute,"fill") == 0)
12748 {
12749 if (info)
12750 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12751 &draw_info->fill,exception);
12752 break;
12753 }
12754 if (LocaleCompare(attribute,"font") == 0)
12755 {
12756 CloneString(&draw_info->font,SvPV(ST(i),na));
12757 break;
12758 }
12759 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12760 attribute);
12761 break;
12762 }
12763 case 'g':
12764 case 'G':
12765 {
12766 if (LocaleCompare(attribute,"geometry") == 0)
12767 {
12768 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12769 break;
12770 }
12771 if (LocaleCompare(attribute,"gravity") == 0)
12772 {
12773 draw_info->gravity=(GravityType) ParseCommandOption(
12774 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12775 break;
12776 }
12777 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12778 attribute);
12779 break;
12780 }
12781 case 'i':
12782 case 'I':
12783 {
12784 if (LocaleCompare(attribute,"interline-spacing") == 0)
12785 {
12786 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12787 draw_info->interline_spacing=geometry_info.rho;
12788 break;
12789 }
12790 if (LocaleCompare(attribute,"interword-spacing") == 0)
12791 {
12792 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12793 draw_info->interword_spacing=geometry_info.rho;
12794 break;
12795 }
12796 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12797 attribute);
12798 break;
12799 }
12800 case 'k':
12801 case 'K':
12802 {
12803 if (LocaleCompare(attribute,"kerning") == 0)
12804 {
12805 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12806 draw_info->kerning=geometry_info.rho;
12807 break;
12808 }
12809 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12810 attribute);
12811 break;
12812 }
12813 case 'p':
12814 case 'P':
12815 {
12816 if (LocaleCompare(attribute,"pointsize") == 0)
12817 {
12818 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12819 draw_info->pointsize=geometry_info.rho;
12820 break;
12821 }
12822 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12823 attribute);
12824 break;
12825 }
12826 case 'r':
12827 case 'R':
12828 {
12829 if (LocaleCompare(attribute,"rotate") == 0)
12830 {
12831 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12832 affine.rx=geometry_info.rho;
12833 affine.ry=geometry_info.sigma;
12834 if ((flags & SigmaValue) == 0)
12835 affine.ry=affine.rx;
12836 break;
12837 }
12838 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12839 attribute);
12840 break;
12841 }
12842 case 's':
12843 case 'S':
12844 {
12845 if (LocaleCompare(attribute,"scale") == 0)
12846 {
12847 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12848 affine.sx=geometry_info.rho;
12849 affine.sy=geometry_info.sigma;
12850 if ((flags & SigmaValue) == 0)
12851 affine.sy=affine.sx;
12852 break;
12853 }
12854 if (LocaleCompare(attribute,"skew") == 0)
12855 {
12856 double
12857 x_angle,
12858 y_angle;
12859
12860 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12861 x_angle=geometry_info.rho;
12862 y_angle=geometry_info.sigma;
12863 if ((flags & SigmaValue) == 0)
12864 y_angle=x_angle;
12865 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12866 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12867 break;
12868 }
12869 if (LocaleCompare(attribute,"stroke") == 0)
12870 {
12871 if (info)
12872 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12873 &draw_info->stroke,exception);
12874 break;
12875 }
12876 if (LocaleCompare(attribute,"style") == 0)
12877 {
12878 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12879 SvPV(ST(i),na));
12880 if (type < 0)
12881 {
12882 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12883 SvPV(ST(i),na));
12884 break;
12885 }
12886 draw_info->style=(StyleType) type;
12887 break;
12888 }
12889 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12890 attribute);
12891 break;
12892 }
12893 case 't':
12894 case 'T':
12895 {
12896 if (LocaleCompare(attribute,"text") == 0)
12897 {
12898 CloneString(&draw_info->text,SvPV(ST(i),na));
12899 break;
12900 }
12901 if (LocaleCompare(attribute,"translate") == 0)
12902 {
12903 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12904 affine.tx=geometry_info.rho;
12905 affine.ty=geometry_info.sigma;
12906 if ((flags & SigmaValue) == 0)
12907 affine.ty=affine.tx;
12908 break;
12909 }
12910 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12911 attribute);
12912 break;
12913 }
12914 case 'w':
12915 case 'W':
12916 {
12917 if (LocaleCompare(attribute,"weight") == 0)
12918 {
12919 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12920 draw_info->weight=(size_t) geometry_info.rho;
12921 break;
12922 }
12923 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12924 attribute);
12925 break;
12926 }
12927 case 'x':
12928 case 'X':
12929 {
12930 if (LocaleCompare(attribute,"x") == 0)
12931 {
12932 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12933 x=geometry_info.rho;
12934 break;
12935 }
12936 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12937 attribute);
12938 break;
12939 }
12940 case 'y':
12941 case 'Y':
12942 {
12943 if (LocaleCompare(attribute,"y") == 0)
12944 {
12945 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12946 y=geometry_info.rho;
12947 break;
12948 }
12949 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12950 attribute);
12951 break;
12952 }
12953 default:
12954 {
12955 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12956 attribute);
12957 break;
12958 }
12959 }
12960 }
12961 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12962 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12963 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12964 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12965 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12966 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12967 if (draw_info->geometry == (char *) NULL)
12968 {
12969 draw_info->geometry=AcquireString((char *) NULL);
12970 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
12971 "%.15g,%.15g",x,y);
12972 }
12973 status=GetTypeMetrics(image,draw_info,&metrics,exception);
12974 (void) CatchImageException(image);
12975 if (status == MagickFalse)
12976 PUSHs(&sv_undef);
12977 else
12978 {
12979 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12980 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12981 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12982 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12983 PUSHs(sv_2mortal(newSVnv(metrics.width)));
12984 PUSHs(sv_2mortal(newSVnv(metrics.height)));
12985 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12986 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12987 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12988 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12989 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12990 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12991 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12992 }
12993 draw_info=DestroyDrawInfo(draw_info);
12994
12995 PerlException:
12996 if (package_info != (struct PackageInfo *) NULL)
12997 DestroyPackageInfo(package_info);
12998 InheritPerlException(exception,perl_exception);
12999 exception=DestroyExceptionInfo(exception);
13000 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13001 }
13002
13003 #
13004 ###############################################################################
13005 # #
13006 # #
13007 # #
13008 # 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 #
13009 # #
13010 # #
13011 # #
13012 ###############################################################################
13013 #
13014 #
13015 void
QueryMultilineFontMetrics(ref,...)13016 QueryMultilineFontMetrics(ref,...)
13017 Image::Magick ref=NO_INIT
13018 ALIAS:
13019 querymultilinefontmetrics = 1
13020 PPCODE:
13021 {
13022 AffineMatrix
13023 affine,
13024 current;
13025
13026 AV
13027 *av;
13028
13029 char
13030 *attribute;
13031
13032 double
13033 x,
13034 y;
13035
13036 DrawInfo
13037 *draw_info;
13038
13039 ExceptionInfo
13040 *exception;
13041
13042 GeometryInfo
13043 geometry_info;
13044
13045 Image
13046 *image;
13047
13048 MagickBooleanType
13049 status;
13050
13051 MagickStatusType
13052 flags;
13053
13054 register ssize_t
13055 i;
13056
13057 ssize_t
13058 type;
13059
13060 struct PackageInfo
13061 *info,
13062 *package_info;
13063
13064 SV
13065 *perl_exception,
13066 *reference; /* reference is the SV* of ref=SvIV(reference) */
13067
13068 TypeMetric
13069 metrics;
13070
13071 PERL_UNUSED_VAR(ref);
13072 PERL_UNUSED_VAR(ix);
13073 exception=AcquireExceptionInfo();
13074 package_info=(struct PackageInfo *) NULL;
13075 perl_exception=newSVpv("",0);
13076 reference=SvRV(ST(0));
13077 av=(AV *) reference;
13078 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13079 exception);
13080 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13081 if (image == (Image *) NULL)
13082 {
13083 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13084 PackageName);
13085 goto PerlException;
13086 }
13087 package_info=ClonePackageInfo(info,exception);
13088 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13089 CloneString(&draw_info->text,"");
13090 current=draw_info->affine;
13091 GetAffineMatrix(&affine);
13092 x=0.0;
13093 y=0.0;
13094 EXTEND(sp,7*items);
13095 for (i=2; i < items; i+=2)
13096 {
13097 attribute=(char *) SvPV(ST(i-1),na);
13098 switch (*attribute)
13099 {
13100 case 'A':
13101 case 'a':
13102 {
13103 if (LocaleCompare(attribute,"antialias") == 0)
13104 {
13105 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13106 SvPV(ST(i),na));
13107 if (type < 0)
13108 {
13109 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13110 SvPV(ST(i),na));
13111 break;
13112 }
13113 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13114 break;
13115 }
13116 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13117 attribute);
13118 break;
13119 }
13120 case 'd':
13121 case 'D':
13122 {
13123 if (LocaleCompare(attribute,"density") == 0)
13124 {
13125 CloneString(&draw_info->density,SvPV(ST(i),na));
13126 break;
13127 }
13128 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13129 attribute);
13130 break;
13131 }
13132 case 'e':
13133 case 'E':
13134 {
13135 if (LocaleCompare(attribute,"encoding") == 0)
13136 {
13137 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13138 break;
13139 }
13140 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13141 attribute);
13142 break;
13143 }
13144 case 'f':
13145 case 'F':
13146 {
13147 if (LocaleCompare(attribute,"family") == 0)
13148 {
13149 CloneString(&draw_info->family,SvPV(ST(i),na));
13150 break;
13151 }
13152 if (LocaleCompare(attribute,"fill") == 0)
13153 {
13154 if (info)
13155 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13156 &draw_info->fill,exception);
13157 break;
13158 }
13159 if (LocaleCompare(attribute,"font") == 0)
13160 {
13161 CloneString(&draw_info->font,SvPV(ST(i),na));
13162 break;
13163 }
13164 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13165 attribute);
13166 break;
13167 }
13168 case 'g':
13169 case 'G':
13170 {
13171 if (LocaleCompare(attribute,"geometry") == 0)
13172 {
13173 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13174 break;
13175 }
13176 if (LocaleCompare(attribute,"gravity") == 0)
13177 {
13178 draw_info->gravity=(GravityType) ParseCommandOption(
13179 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13180 break;
13181 }
13182 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13183 attribute);
13184 break;
13185 }
13186 case 'p':
13187 case 'P':
13188 {
13189 if (LocaleCompare(attribute,"pointsize") == 0)
13190 {
13191 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13192 draw_info->pointsize=geometry_info.rho;
13193 break;
13194 }
13195 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13196 attribute);
13197 break;
13198 }
13199 case 'r':
13200 case 'R':
13201 {
13202 if (LocaleCompare(attribute,"rotate") == 0)
13203 {
13204 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13205 affine.rx=geometry_info.rho;
13206 affine.ry=geometry_info.sigma;
13207 if ((flags & SigmaValue) == 0)
13208 affine.ry=affine.rx;
13209 break;
13210 }
13211 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13212 attribute);
13213 break;
13214 }
13215 case 's':
13216 case 'S':
13217 {
13218 if (LocaleCompare(attribute,"scale") == 0)
13219 {
13220 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13221 affine.sx=geometry_info.rho;
13222 affine.sy=geometry_info.sigma;
13223 if ((flags & SigmaValue) == 0)
13224 affine.sy=affine.sx;
13225 break;
13226 }
13227 if (LocaleCompare(attribute,"skew") == 0)
13228 {
13229 double
13230 x_angle,
13231 y_angle;
13232
13233 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13234 x_angle=geometry_info.rho;
13235 y_angle=geometry_info.sigma;
13236 if ((flags & SigmaValue) == 0)
13237 y_angle=x_angle;
13238 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13239 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13240 break;
13241 }
13242 if (LocaleCompare(attribute,"stroke") == 0)
13243 {
13244 if (info)
13245 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13246 &draw_info->stroke,exception);
13247 break;
13248 }
13249 if (LocaleCompare(attribute,"style") == 0)
13250 {
13251 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13252 SvPV(ST(i),na));
13253 if (type < 0)
13254 {
13255 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13256 SvPV(ST(i),na));
13257 break;
13258 }
13259 draw_info->style=(StyleType) type;
13260 break;
13261 }
13262 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13263 attribute);
13264 break;
13265 }
13266 case 't':
13267 case 'T':
13268 {
13269 if (LocaleCompare(attribute,"text") == 0)
13270 {
13271 CloneString(&draw_info->text,SvPV(ST(i),na));
13272 break;
13273 }
13274 if (LocaleCompare(attribute,"translate") == 0)
13275 {
13276 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13277 affine.tx=geometry_info.rho;
13278 affine.ty=geometry_info.sigma;
13279 if ((flags & SigmaValue) == 0)
13280 affine.ty=affine.tx;
13281 break;
13282 }
13283 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13284 attribute);
13285 break;
13286 }
13287 case 'w':
13288 case 'W':
13289 {
13290 if (LocaleCompare(attribute,"weight") == 0)
13291 {
13292 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13293 draw_info->weight=(size_t) geometry_info.rho;
13294 break;
13295 }
13296 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13297 attribute);
13298 break;
13299 }
13300 case 'x':
13301 case 'X':
13302 {
13303 if (LocaleCompare(attribute,"x") == 0)
13304 {
13305 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13306 x=geometry_info.rho;
13307 break;
13308 }
13309 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13310 attribute);
13311 break;
13312 }
13313 case 'y':
13314 case 'Y':
13315 {
13316 if (LocaleCompare(attribute,"y") == 0)
13317 {
13318 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13319 y=geometry_info.rho;
13320 break;
13321 }
13322 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13323 attribute);
13324 break;
13325 }
13326 default:
13327 {
13328 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13329 attribute);
13330 break;
13331 }
13332 }
13333 }
13334 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13335 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13336 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13337 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13338 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13339 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13340 if (draw_info->geometry == (char *) NULL)
13341 {
13342 draw_info->geometry=AcquireString((char *) NULL);
13343 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
13344 "%.15g,%.15g",x,y);
13345 }
13346 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13347 (void) CatchException(exception);
13348 if (status == MagickFalse)
13349 PUSHs(&sv_undef);
13350 else
13351 {
13352 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13353 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13354 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13355 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13356 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13357 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13358 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13359 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13360 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13361 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13362 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13363 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13364 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13365 }
13366 draw_info=DestroyDrawInfo(draw_info);
13367
13368 PerlException:
13369 if (package_info != (struct PackageInfo *) NULL)
13370 DestroyPackageInfo(package_info);
13371 InheritPerlException(exception,perl_exception);
13372 exception=DestroyExceptionInfo(exception);
13373 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13374 }
13375
13376 #
13377 ###############################################################################
13378 # #
13379 # #
13380 # #
13381 # Q u e r y F o r m a t #
13382 # #
13383 # #
13384 # #
13385 ###############################################################################
13386 #
13387 #
13388 void
QueryFormat(ref,...)13389 QueryFormat(ref,...)
13390 Image::Magick ref=NO_INIT
13391 ALIAS:
13392 queryformat = 1
13393 PPCODE:
13394 {
13395 char
13396 *name;
13397
13398 ExceptionInfo
13399 *exception;
13400
13401 register ssize_t
13402 i;
13403
13404 SV
13405 *perl_exception;
13406
13407 volatile const MagickInfo
13408 *magick_info;
13409
13410 PERL_UNUSED_VAR(ref);
13411 PERL_UNUSED_VAR(ix);
13412 exception=AcquireExceptionInfo();
13413 perl_exception=newSVpv("",0);
13414 if (items == 1)
13415 {
13416 char
13417 format[MagickPathExtent];
13418
13419 const MagickInfo
13420 **format_list;
13421
13422 size_t
13423 types;
13424
13425 format_list=GetMagickInfoList("*",&types,exception);
13426 EXTEND(sp,types);
13427 for (i=0; i < (ssize_t) types; i++)
13428 {
13429 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
13430 LocaleLower(format);
13431 PUSHs(sv_2mortal(newSVpv(format,0)));
13432 }
13433 format_list=(const MagickInfo **)
13434 RelinquishMagickMemory((MagickInfo *) format_list);
13435 goto PerlException;
13436 }
13437 EXTEND(sp,8*items);
13438 for (i=1; i < items; i++)
13439 {
13440 name=(char *) SvPV(ST(i),na);
13441 magick_info=GetMagickInfo(name,exception);
13442 if (magick_info == (const MagickInfo *) NULL)
13443 {
13444 PUSHs(&sv_undef);
13445 continue;
13446 }
13447 if (magick_info->description == (char *) NULL)
13448 PUSHs(&sv_undef);
13449 else
13450 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13451 if (magick_info->module == (char *) NULL)
13452 PUSHs(&sv_undef);
13453 else
13454 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13455 }
13456
13457 PerlException:
13458 InheritPerlException(exception,perl_exception);
13459 exception=DestroyExceptionInfo(exception);
13460 SvREFCNT_dec(perl_exception);
13461 }
13462
13463 #
13464 ###############################################################################
13465 # #
13466 # #
13467 # #
13468 # Q u e r y O p t i o n #
13469 # #
13470 # #
13471 # #
13472 ###############################################################################
13473 #
13474 #
13475 void
QueryOption(ref,...)13476 QueryOption(ref,...)
13477 Image::Magick ref=NO_INIT
13478 ALIAS:
13479 queryoption = 1
13480 PPCODE:
13481 {
13482 char
13483 **options;
13484
13485 ExceptionInfo
13486 *exception;
13487
13488 register ssize_t
13489 i;
13490
13491 ssize_t
13492 j,
13493 option;
13494
13495 SV
13496 *perl_exception;
13497
13498 PERL_UNUSED_VAR(ref);
13499 PERL_UNUSED_VAR(ix);
13500 exception=AcquireExceptionInfo();
13501 perl_exception=newSVpv("",0);
13502 EXTEND(sp,8*items);
13503 for (i=1; i < items; i++)
13504 {
13505 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13506 SvPV(ST(i),na));
13507 options=GetCommandOptions((CommandOption) option);
13508 if (options == (char **) NULL)
13509 PUSHs(&sv_undef);
13510 else
13511 {
13512 for (j=0; options[j] != (char *) NULL; j++)
13513 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13514 options=DestroyStringList(options);
13515 }
13516 }
13517
13518 InheritPerlException(exception,perl_exception);
13519 exception=DestroyExceptionInfo(exception);
13520 SvREFCNT_dec(perl_exception);
13521 }
13522
13523 #
13524 ###############################################################################
13525 # #
13526 # #
13527 # #
13528 # R e a d #
13529 # #
13530 # #
13531 # #
13532 ###############################################################################
13533 #
13534 #
13535 void
Read(ref,...)13536 Read(ref,...)
13537 Image::Magick ref=NO_INIT
13538 ALIAS:
13539 ReadImage = 1
13540 read = 2
13541 readimage = 3
13542 PPCODE:
13543 {
13544 AV
13545 *av;
13546
13547 char
13548 **keep,
13549 **list;
13550
13551 ExceptionInfo
13552 *exception;
13553
13554 HV
13555 *hv;
13556
13557 Image
13558 *image;
13559
13560 int
13561 n;
13562
13563 MagickBooleanType
13564 status;
13565
13566 register char
13567 **p;
13568
13569 register ssize_t
13570 i;
13571
13572 ssize_t
13573 ac,
13574 number_images;
13575
13576 STRLEN
13577 *length;
13578
13579 struct PackageInfo
13580 *info,
13581 *package_info;
13582
13583 SV
13584 *perl_exception, /* Perl variable for storing messages */
13585 *reference,
13586 *rv,
13587 *sv;
13588
13589 PERL_UNUSED_VAR(ref);
13590 PERL_UNUSED_VAR(ix);
13591 exception=AcquireExceptionInfo();
13592 perl_exception=newSVpv("",0);
13593 sv=NULL;
13594 package_info=(struct PackageInfo *) NULL;
13595 number_images=0;
13596 ac=(items < 2) ? 1 : items-1;
13597 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13598 keep=list;
13599 length=(STRLEN *) NULL;
13600 if (list == (char **) NULL)
13601 {
13602 ThrowPerlException(exception,ResourceLimitError,
13603 "MemoryAllocationFailed",PackageName);
13604 goto PerlException;
13605 }
13606 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13607 if (length == (STRLEN *) NULL)
13608 {
13609 ThrowPerlException(exception,ResourceLimitError,
13610 "MemoryAllocationFailed",PackageName);
13611 goto PerlException;
13612 }
13613 if (sv_isobject(ST(0)) == 0)
13614 {
13615 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13616 PackageName);
13617 goto PerlException;
13618 }
13619 reference=SvRV(ST(0));
13620 hv=SvSTASH(reference);
13621 if (SvTYPE(reference) != SVt_PVAV)
13622 {
13623 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13624 PackageName);
13625 goto PerlException;
13626 }
13627 av=(AV *) reference;
13628 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13629 exception);
13630 package_info=ClonePackageInfo(info,exception);
13631 n=1;
13632 if (items <= 1)
13633 *list=(char *) (*package_info->image_info->filename ?
13634 package_info->image_info->filename : "XC:black");
13635 else
13636 for (n=0, i=0; i < ac; i++)
13637 {
13638 list[n]=(char *) SvPV(ST(i+1),length[n]);
13639 if ((items >= 3) && strEQcase(list[n],"blob"))
13640 {
13641 void
13642 *blob;
13643
13644 i++;
13645 blob=(void *) (SvPV(ST(i+1),length[n]));
13646 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13647 }
13648 if ((items >= 3) && strEQcase(list[n],"filename"))
13649 continue;
13650 if ((items >= 3) && strEQcase(list[n],"file"))
13651 {
13652 FILE
13653 *file;
13654
13655 PerlIO
13656 *io_info;
13657
13658 i++;
13659 io_info=IoIFP(sv_2io(ST(i+1)));
13660 if (io_info == (PerlIO *) NULL)
13661 {
13662 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13663 PackageName);
13664 continue;
13665 }
13666 file=PerlIO_findFILE(io_info);
13667 if (file == (FILE *) NULL)
13668 {
13669 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13670 PackageName);
13671 continue;
13672 }
13673 SetImageInfoFile(package_info->image_info,file);
13674 }
13675 if ((items >= 3) && strEQcase(list[n],"magick"))
13676 continue;
13677 n++;
13678 }
13679 list[n]=(char *) NULL;
13680 keep=list;
13681 status=ExpandFilenames(&n,&list);
13682 if (status == MagickFalse)
13683 {
13684 ThrowPerlException(exception,ResourceLimitError,
13685 "MemoryAllocationFailed",PackageName);
13686 goto PerlException;
13687 }
13688 number_images=0;
13689 for (i=0; i < n; i++)
13690 {
13691 if ((package_info->image_info->file == (FILE *) NULL) &&
13692 (package_info->image_info->blob == (void *) NULL))
13693 image=ReadImages(package_info->image_info,list[i],exception);
13694 else
13695 {
13696 image=ReadImages(package_info->image_info,
13697 package_info->image_info->filename,exception);
13698 if (image != (Image *) NULL)
13699 DisassociateImageStream(image);
13700 }
13701 if (image == (Image *) NULL)
13702 break;
13703 for ( ; image; image=image->next)
13704 {
13705 AddImageToRegistry(sv,image);
13706 rv=newRV(sv);
13707 av_push(av,sv_bless(rv,hv));
13708 SvREFCNT_dec(sv);
13709 number_images++;
13710 }
13711 }
13712 /*
13713 Free resources.
13714 */
13715 for (i=0; i < n; i++)
13716 if (list[i] != (char *) NULL)
13717 for (p=keep; list[i] != *p++; )
13718 if (*p == (char *) NULL)
13719 {
13720 list[i]=(char *) RelinquishMagickMemory(list[i]);
13721 break;
13722 }
13723
13724 PerlException:
13725 if (package_info != (struct PackageInfo *) NULL)
13726 DestroyPackageInfo(package_info);
13727 if (list && (list != keep))
13728 list=(char **) RelinquishMagickMemory(list);
13729 if (keep)
13730 keep=(char **) RelinquishMagickMemory(keep);
13731 if (length)
13732 length=(STRLEN *) RelinquishMagickMemory(length);
13733 InheritPerlException(exception,perl_exception);
13734 exception=DestroyExceptionInfo(exception);
13735 sv_setiv(perl_exception,(IV) number_images);
13736 SvPOK_on(perl_exception);
13737 ST(0)=sv_2mortal(perl_exception);
13738 XSRETURN(1);
13739 }
13740
13741 #
13742 ###############################################################################
13743 # #
13744 # #
13745 # #
13746 # R e m o t e #
13747 # #
13748 # #
13749 # #
13750 ###############################################################################
13751 #
13752 #
13753 void
Remote(ref,...)13754 Remote(ref,...)
13755 Image::Magick ref=NO_INIT
13756 ALIAS:
13757 RemoteCommand = 1
13758 remote = 2
13759 remoteCommand = 3
13760 PPCODE:
13761 {
13762 AV
13763 *av;
13764
13765 ExceptionInfo
13766 *exception;
13767
13768 register ssize_t
13769 i;
13770
13771 SV
13772 *perl_exception,
13773 *reference;
13774
13775 struct PackageInfo
13776 *info;
13777
13778 PERL_UNUSED_VAR(ref);
13779 PERL_UNUSED_VAR(ix);
13780 exception=AcquireExceptionInfo();
13781 perl_exception=newSVpv("",0);
13782 reference=SvRV(ST(0));
13783 av=(AV *) reference;
13784 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13785 exception);
13786 for (i=1; i < items; i++)
13787 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13788 SvPV(ST(i),na),exception);
13789 InheritPerlException(exception,perl_exception);
13790 exception=DestroyExceptionInfo(exception);
13791 SvREFCNT_dec(perl_exception); /* throw away all errors */
13792 }
13793
13794 #
13795 ###############################################################################
13796 # #
13797 # #
13798 # #
13799 # S e t #
13800 # #
13801 # #
13802 # #
13803 ###############################################################################
13804 #
13805 #
13806 void
Set(ref,...)13807 Set(ref,...)
13808 Image::Magick ref=NO_INIT
13809 ALIAS:
13810 SetAttributes = 1
13811 SetAttribute = 2
13812 set = 3
13813 setattributes = 4
13814 setattribute = 5
13815 PPCODE:
13816 {
13817 ExceptionInfo
13818 *exception;
13819
13820 Image
13821 *image;
13822
13823 register ssize_t
13824 i;
13825
13826 struct PackageInfo
13827 *info;
13828
13829 SV
13830 *perl_exception,
13831 *reference; /* reference is the SV* of ref=SvIV(reference) */
13832
13833 PERL_UNUSED_VAR(ref);
13834 PERL_UNUSED_VAR(ix);
13835 exception=AcquireExceptionInfo();
13836 perl_exception=newSVpv("",0);
13837 if (sv_isobject(ST(0)) == 0)
13838 {
13839 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13840 PackageName);
13841 goto PerlException;
13842 }
13843 reference=SvRV(ST(0));
13844 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13845 if (items == 2)
13846 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13847 else
13848 for (i=2; i < items; i+=2)
13849 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13850
13851 PerlException:
13852 InheritPerlException(exception,perl_exception);
13853 exception=DestroyExceptionInfo(exception);
13854 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13855 SvPOK_on(perl_exception);
13856 ST(0)=sv_2mortal(perl_exception);
13857 XSRETURN(1);
13858 }
13859
13860 #
13861 ###############################################################################
13862 # #
13863 # #
13864 # #
13865 # S e t P i x e l #
13866 # #
13867 # #
13868 # #
13869 ###############################################################################
13870 #
13871 #
13872 void
SetPixel(ref,...)13873 SetPixel(ref,...)
13874 Image::Magick ref=NO_INIT
13875 ALIAS:
13876 setpixel = 1
13877 setPixel = 2
13878 PPCODE:
13879 {
13880 AV
13881 *av;
13882
13883 char
13884 *attribute;
13885
13886 ChannelType
13887 channel,
13888 channel_mask;
13889
13890 ExceptionInfo
13891 *exception;
13892
13893 Image
13894 *image;
13895
13896 MagickBooleanType
13897 normalize;
13898
13899 RectangleInfo
13900 region;
13901
13902 register ssize_t
13903 i;
13904
13905 register Quantum
13906 *q;
13907
13908 ssize_t
13909 option;
13910
13911 struct PackageInfo
13912 *info;
13913
13914 SV
13915 *perl_exception,
13916 *reference; /* reference is the SV* of ref=SvIV(reference) */
13917
13918 PERL_UNUSED_VAR(ref);
13919 PERL_UNUSED_VAR(ix);
13920 exception=AcquireExceptionInfo();
13921 perl_exception=newSVpv("",0);
13922 reference=SvRV(ST(0));
13923 av=(AV *) reference;
13924 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13925 exception);
13926 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13927 if (image == (Image *) NULL)
13928 {
13929 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13930 PackageName);
13931 goto PerlException;
13932 }
13933 av=(AV *) NULL;
13934 normalize=MagickTrue;
13935 region.x=0;
13936 region.y=0;
13937 region.width=image->columns;
13938 region.height=1;
13939 if (items == 1)
13940 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion);
13941 channel=DefaultChannels;
13942 for (i=2; i < items; i+=2)
13943 {
13944 attribute=(char *) SvPV(ST(i-1),na);
13945 switch (*attribute)
13946 {
13947 case 'C':
13948 case 'c':
13949 {
13950 if (LocaleCompare(attribute,"channel") == 0)
13951 {
13952 ssize_t
13953 option;
13954
13955 option=ParseChannelOption(SvPV(ST(i),na));
13956 if (option < 0)
13957 {
13958 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13959 SvPV(ST(i),na));
13960 return;
13961 }
13962 channel=(ChannelType) option;
13963 break;
13964 }
13965 if (LocaleCompare(attribute,"color") == 0)
13966 {
13967 if (SvTYPE(ST(i)) != SVt_RV)
13968 {
13969 char
13970 message[MagickPathExtent];
13971
13972 (void) FormatLocaleString(message,MagickPathExtent,
13973 "invalid %.60s value",attribute);
13974 ThrowPerlException(exception,OptionError,message,
13975 SvPV(ST(i),na));
13976 }
13977 av=(AV *) SvRV(ST(i));
13978 break;
13979 }
13980 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13981 attribute);
13982 break;
13983 }
13984 case 'g':
13985 case 'G':
13986 {
13987 if (LocaleCompare(attribute,"geometry") == 0)
13988 {
13989 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion);
13990 break;
13991 }
13992 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13993 attribute);
13994 break;
13995 }
13996 case 'N':
13997 case 'n':
13998 {
13999 if (LocaleCompare(attribute,"normalize") == 0)
14000 {
14001 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14002 SvPV(ST(i),na));
14003 if (option < 0)
14004 {
14005 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14006 SvPV(ST(i),na));
14007 break;
14008 }
14009 normalize=option != 0 ? MagickTrue : MagickFalse;
14010 break;
14011 }
14012 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14013 attribute);
14014 break;
14015 }
14016 case 'x':
14017 case 'X':
14018 {
14019 if (LocaleCompare(attribute,"x") == 0)
14020 {
14021 region.x=SvIV(ST(i));
14022 break;
14023 }
14024 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14025 attribute);
14026 break;
14027 }
14028 case 'y':
14029 case 'Y':
14030 {
14031 if (LocaleCompare(attribute,"y") == 0)
14032 {
14033 region.y=SvIV(ST(i));
14034 break;
14035 }
14036 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14037 attribute);
14038 break;
14039 }
14040 default:
14041 {
14042 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14043 attribute);
14044 break;
14045 }
14046 }
14047 }
14048 (void) SetImageStorageClass(image,DirectClass,exception);
14049 channel_mask=SetImageChannelMask(image,channel);
14050 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14051 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14052 (SvTYPE(av) != SVt_PVAV))
14053 PUSHs(&sv_undef);
14054 else
14055 {
14056 double
14057 scale;
14058
14059 register ssize_t
14060 i;
14061
14062 i=0;
14063 scale=1.0;
14064 if (normalize != MagickFalse)
14065 scale=QuantumRange;
14066 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14067 (i <= av_len(av)))
14068 {
14069 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14070 av_fetch(av,i,0)))),q);
14071 i++;
14072 }
14073 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14074 (i <= av_len(av)))
14075 {
14076 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14077 av_fetch(av,i,0)))),q);
14078 i++;
14079 }
14080 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14081 (i <= av_len(av)))
14082 {
14083 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14084 av_fetch(av,i,0)))),q);
14085 i++;
14086 }
14087 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14088 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14089 {
14090 SetPixelBlack(image,ClampToQuantum(scale*
14091 SvNV(*(av_fetch(av,i,0)))),q);
14092 i++;
14093 }
14094 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14095 (i <= av_len(av)))
14096 {
14097 SetPixelAlpha(image,ClampToQuantum(scale*
14098 SvNV(*(av_fetch(av,i,0)))),q);
14099 i++;
14100 }
14101 (void) SyncAuthenticPixels(image,exception);
14102 }
14103 (void) SetImageChannelMask(image,channel_mask);
14104
14105 PerlException:
14106 InheritPerlException(exception,perl_exception);
14107 exception=DestroyExceptionInfo(exception);
14108 SvREFCNT_dec(perl_exception);
14109 }
14110
14111 #
14112 ###############################################################################
14113 # #
14114 # #
14115 # #
14116 # S m u s h #
14117 # #
14118 # #
14119 # #
14120 ###############################################################################
14121 #
14122 #
14123 void
Smush(ref,...)14124 Smush(ref,...)
14125 Image::Magick ref=NO_INIT
14126 ALIAS:
14127 SmushImage = 1
14128 smush = 2
14129 smushimage = 3
14130 PPCODE:
14131 {
14132 AV
14133 *av;
14134
14135 char
14136 *attribute;
14137
14138 ExceptionInfo
14139 *exception;
14140
14141 HV
14142 *hv;
14143
14144 Image
14145 *image;
14146
14147 register ssize_t
14148 i;
14149
14150 ssize_t
14151 offset,
14152 stack;
14153
14154 struct PackageInfo
14155 *info;
14156
14157 SV
14158 *av_reference,
14159 *perl_exception,
14160 *reference,
14161 *rv,
14162 *sv;
14163
14164 PERL_UNUSED_VAR(ref);
14165 PERL_UNUSED_VAR(ix);
14166 exception=AcquireExceptionInfo();
14167 perl_exception=newSVpv("",0);
14168 sv=NULL;
14169 attribute=NULL;
14170 av=NULL;
14171 if (sv_isobject(ST(0)) == 0)
14172 {
14173 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14174 PackageName);
14175 goto PerlException;
14176 }
14177 reference=SvRV(ST(0));
14178 hv=SvSTASH(reference);
14179 av=newAV();
14180 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14181 SvREFCNT_dec(av);
14182 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14183 if (image == (Image *) NULL)
14184 {
14185 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14186 PackageName);
14187 goto PerlException;
14188 }
14189 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14190 /*
14191 Get options.
14192 */
14193 offset=0;
14194 stack=MagickTrue;
14195 for (i=2; i < items; i+=2)
14196 {
14197 attribute=(char *) SvPV(ST(i-1),na);
14198 switch (*attribute)
14199 {
14200 case 'O':
14201 case 'o':
14202 {
14203 if (LocaleCompare(attribute,"offset") == 0)
14204 {
14205 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14206 break;
14207 }
14208 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14209 attribute);
14210 break;
14211 }
14212 case 'S':
14213 case 's':
14214 {
14215 if (LocaleCompare(attribute,"stack") == 0)
14216 {
14217 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14218 SvPV(ST(i),na));
14219 if (stack < 0)
14220 {
14221 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14222 SvPV(ST(i),na));
14223 return;
14224 }
14225 break;
14226 }
14227 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14228 attribute);
14229 break;
14230 }
14231 default:
14232 {
14233 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14234 attribute);
14235 break;
14236 }
14237 }
14238 }
14239 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14240 exception);
14241 if (image == (Image *) NULL)
14242 goto PerlException;
14243 for ( ; image; image=image->next)
14244 {
14245 AddImageToRegistry(sv,image);
14246 rv=newRV(sv);
14247 av_push(av,sv_bless(rv,hv));
14248 SvREFCNT_dec(sv);
14249 }
14250 exception=DestroyExceptionInfo(exception);
14251 ST(0)=av_reference;
14252 SvREFCNT_dec(perl_exception);
14253 XSRETURN(1);
14254
14255 PerlException:
14256 InheritPerlException(exception,perl_exception);
14257 exception=DestroyExceptionInfo(exception);
14258 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14259 SvPOK_on(perl_exception);
14260 ST(0)=sv_2mortal(perl_exception);
14261 XSRETURN(1);
14262 }
14263
14264 #
14265 ###############################################################################
14266 # #
14267 # #
14268 # #
14269 # S t a t i s t i c s #
14270 # #
14271 # #
14272 # #
14273 ###############################################################################
14274 #
14275 #
14276 void
Statistics(ref,...)14277 Statistics(ref,...)
14278 Image::Magick ref=NO_INIT
14279 ALIAS:
14280 StatisticsImage = 1
14281 statistics = 2
14282 statisticsimage = 3
14283 PPCODE:
14284 {
14285 #define ChannelStatistics(channel) \
14286 { \
14287 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14288 (double) channel_statistics[channel].depth); \
14289 PUSHs(sv_2mortal(newSVpv(message,0))); \
14290 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14291 channel_statistics[channel].minima/scale); \
14292 PUSHs(sv_2mortal(newSVpv(message,0))); \
14293 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14294 channel_statistics[channel].maxima/scale); \
14295 PUSHs(sv_2mortal(newSVpv(message,0))); \
14296 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14297 channel_statistics[channel].mean/scale); \
14298 PUSHs(sv_2mortal(newSVpv(message,0))); \
14299 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14300 channel_statistics[channel].standard_deviation/scale); \
14301 PUSHs(sv_2mortal(newSVpv(message,0))); \
14302 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14303 channel_statistics[channel].kurtosis); \
14304 PUSHs(sv_2mortal(newSVpv(message,0))); \
14305 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14306 channel_statistics[channel].skewness); \
14307 PUSHs(sv_2mortal(newSVpv(message,0))); \
14308 (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14309 channel_statistics[channel].entropy); \
14310 PUSHs(sv_2mortal(newSVpv(message,0))); \
14311 }
14312
14313 AV
14314 *av;
14315
14316 char
14317 message[MagickPathExtent];
14318
14319 ChannelStatistics
14320 *channel_statistics;
14321
14322 double
14323 scale;
14324
14325 ExceptionInfo
14326 *exception;
14327
14328 Image
14329 *image;
14330
14331 ssize_t
14332 count;
14333
14334 struct PackageInfo
14335 *info;
14336
14337 SV
14338 *perl_exception,
14339 *reference;
14340
14341 PERL_UNUSED_VAR(ref);
14342 PERL_UNUSED_VAR(ix);
14343 exception=AcquireExceptionInfo();
14344 perl_exception=newSVpv("",0);
14345 av=NULL;
14346 if (sv_isobject(ST(0)) == 0)
14347 {
14348 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14349 PackageName);
14350 goto PerlException;
14351 }
14352 reference=SvRV(ST(0));
14353 av=newAV();
14354 SvREFCNT_dec(av);
14355 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14356 if (image == (Image *) NULL)
14357 {
14358 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14359 PackageName);
14360 goto PerlException;
14361 }
14362 count=0;
14363 for ( ; image; image=image->next)
14364 {
14365 channel_statistics=GetImageStatistics(image,exception);
14366 if (channel_statistics == (ChannelStatistics *) NULL)
14367 continue;
14368 count++;
14369 EXTEND(sp,35*count);
14370 scale=(double) QuantumRange;
14371 ChannelStatistics(RedChannel);
14372 ChannelStatistics(GreenChannel);
14373 ChannelStatistics(BlueChannel);
14374 if (image->colorspace == CMYKColorspace)
14375 ChannelStatistics(BlackChannel);
14376 if (image->alpha_trait != UndefinedPixelTrait)
14377 ChannelStatistics(AlphaChannel);
14378 channel_statistics=(ChannelStatistics *)
14379 RelinquishMagickMemory(channel_statistics);
14380 }
14381
14382 PerlException:
14383 InheritPerlException(exception,perl_exception);
14384 exception=DestroyExceptionInfo(exception);
14385 SvREFCNT_dec(perl_exception);
14386 }
14387
14388 #
14389 ###############################################################################
14390 # #
14391 # #
14392 # #
14393 # S y n c A u t h e n t i c P i x e l s #
14394 # #
14395 # #
14396 # #
14397 ###############################################################################
14398 #
14399 #
14400 void
SyncAuthenticPixels(ref,...)14401 SyncAuthenticPixels(ref,...)
14402 Image::Magick ref = NO_INIT
14403 ALIAS:
14404 Syncauthenticpixels = 1
14405 SyncImagePixels = 2
14406 syncimagepixels = 3
14407 CODE:
14408 {
14409 ExceptionInfo
14410 *exception;
14411
14412 Image
14413 *image;
14414
14415 MagickBooleanType
14416 status;
14417
14418 struct PackageInfo
14419 *info;
14420
14421 SV
14422 *perl_exception,
14423 *reference;
14424
14425 PERL_UNUSED_VAR(ref);
14426 PERL_UNUSED_VAR(ix);
14427 exception=AcquireExceptionInfo();
14428 perl_exception=newSVpv("",0);
14429 if (sv_isobject(ST(0)) == 0)
14430 {
14431 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14432 PackageName);
14433 goto PerlException;
14434 }
14435
14436 reference=SvRV(ST(0));
14437 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14438 if (image == (Image *) NULL)
14439 {
14440 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14441 PackageName);
14442 goto PerlException;
14443 }
14444
14445 status=SyncAuthenticPixels(image,exception);
14446 if (status != MagickFalse)
14447 return;
14448
14449 PerlException:
14450 InheritPerlException(exception,perl_exception);
14451 exception=DestroyExceptionInfo(exception);
14452 SvREFCNT_dec(perl_exception); /* throw away all errors */
14453 }
14454
14455 #
14456 ###############################################################################
14457 # #
14458 # #
14459 # #
14460 # W r i t e #
14461 # #
14462 # #
14463 # #
14464 ###############################################################################
14465 #
14466 #
14467 void
Write(ref,...)14468 Write(ref,...)
14469 Image::Magick ref=NO_INIT
14470 ALIAS:
14471 WriteImage = 1
14472 write = 2
14473 writeimage = 3
14474 PPCODE:
14475 {
14476 char
14477 filename[MagickPathExtent];
14478
14479 ExceptionInfo
14480 *exception;
14481
14482 Image
14483 *image,
14484 *next;
14485
14486 register ssize_t
14487 i;
14488
14489 ssize_t
14490 number_images,
14491 scene;
14492
14493 struct PackageInfo
14494 *info,
14495 *package_info;
14496
14497 SV
14498 *perl_exception,
14499 *reference;
14500
14501 PERL_UNUSED_VAR(ref);
14502 PERL_UNUSED_VAR(ix);
14503 exception=AcquireExceptionInfo();
14504 perl_exception=newSVpv("",0);
14505 number_images=0;
14506 package_info=(struct PackageInfo *) NULL;
14507 if (sv_isobject(ST(0)) == 0)
14508 {
14509 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14510 PackageName);
14511 goto PerlException;
14512 }
14513 reference=SvRV(ST(0));
14514 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14515 if (image == (Image *) NULL)
14516 {
14517 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14518 PackageName);
14519 goto PerlException;
14520 }
14521 package_info=ClonePackageInfo(info,exception);
14522 if (items == 2)
14523 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14524 else
14525 if (items > 2)
14526 for (i=2; i < items; i+=2)
14527 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14528 exception);
14529 (void) CopyMagickString(filename,package_info->image_info->filename,
14530 MagickPathExtent);
14531 scene=0;
14532 for (next=image; next; next=next->next)
14533 {
14534 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
14535 next->scene=scene++;
14536 }
14537 *package_info->image_info->magick='\0';
14538 SetImageInfo(package_info->image_info,(unsigned int)
14539 GetImageListLength(image),exception);
14540 for (next=image; next; next=next->next)
14541 {
14542 (void) WriteImage(package_info->image_info,next,exception);
14543 number_images++;
14544 if (package_info->image_info->adjoin)
14545 break;
14546 }
14547
14548 PerlException:
14549 if (package_info != (struct PackageInfo *) NULL)
14550 DestroyPackageInfo(package_info);
14551 InheritPerlException(exception,perl_exception);
14552 exception=DestroyExceptionInfo(exception);
14553 sv_setiv(perl_exception,(IV) number_images);
14554 SvPOK_on(perl_exception);
14555 ST(0)=sv_2mortal(perl_exception);
14556 XSRETURN(1);
14557 }
14558