ext/RMagick/rmimage.c in rmagick-2.2.2 vs ext/RMagick/rmimage.c in rmagick-2.3.0

- old
+ new

@@ -1,6 +1,6 @@ -/* $Id: rmimage.c,v 1.279 2008/01/28 22:31:50 rmagick Exp $ */ +/* $Id: rmimage.c,v 1.288 2008/03/23 15:15:46 rmagick Exp $ */ /*============================================================================\ | Copyright (C) 2008 by Timothy P. Hunter | Name: rmimage.c | Author: Tim Hunter | Purpose: Image class method definitions for RMagick @@ -394,33 +394,49 @@ return self; } + /* - Method: Image#alpha=(alpha) - Purpose: Equivalent to -alpha option - Notes: see mogrify.c + Method: Image#alpha(type) + Purpose: Calls SetImageAlphaChannel + Notes: Replaces matte=, alpha= + Originally there was an alpha attribute getter and setter. + These are replaced with alpha? and alpha(type). We + still define (but don't document) alpha=. For backward + compatibility, if this method is called without an argument, + make it act like the old alpha getter and return true if the + matte channel is active, false otherwise. */ VALUE -Image_alpha_eq(VALUE self, VALUE type) +Image_alpha(int argc, VALUE *argv, VALUE self) { #if defined(HAVE_TYPE_ALPHACHANNELTYPE) Image *image; AlphaChannelType alpha; - image = rm_check_frozen(self); - VALUE_TO_ENUM(type, alpha, AlphaChannelType); + // For backward compatibility, make alpha() act like alpha? + if (argc == 0) + { + return Image_alpha_q(self); + } + else if (argc > 1) + { + rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc); + } + + image = rm_check_frozen(self); + VALUE_TO_ENUM(argv[0], alpha, AlphaChannelType); + #if defined(HAVE_SETIMAGEALPHACHANNEL) // Added in 6.3.6-9 (void) SetImageAlphaChannel(image, alpha); rm_check_image_exception(image, RetainOnError); - #else - switch (alpha) { case ActivateAlphaChannel: image->matte = MagickTrue; break; @@ -441,14 +457,59 @@ (void) CompositeImage(image, CopyOpacityCompositeOp, image, 0, 0); rm_check_image_exception(image, RetainOnError); break; default: + rb_raise(rb_eArgError, "unknown AlphaChannelType value"); break; } #endif + return argv[0]; + +#else // HAVE_ALPHACHANNELTYPE + argc = argc; + argv =argv; + self = self; + rm_not_implemented(); + return(VALUE)0; +#endif +} + + + +/* + Method: Image#alpha? + Returns: true if the image's alpha channel is activated + Notes: Replaces Image#matte +*/ +VALUE +Image_alpha_q(VALUE self) +{ + Image *image = rm_check_destroyed(self); +#if defined(HAVE_GETIMAGEALPHACHANNEL) + return GetImageAlphaChannel(image) ? Qtrue : Qfalse; +#else + return image->matte ? Qtrue : Qfalse; +#endif +} + + +/* + Method: Image#alpha=(alpha) + Purpose: Equivalent to -alpha option + Returns: alpha + Notes: see mogrify.c + Notes: Deprecated. See Image_alpha. +*/ +VALUE +Image_alpha_eq(VALUE self, VALUE type) +{ +#if defined(HAVE_TYPE_ALPHACHANNELTYPE) + VALUE argv[1]; + argv[0] = type; + Image_alpha(1, argv, self); return type; #else self = self; type = type; rm_not_implemented(); @@ -3176,10 +3237,49 @@ return INT2FIX(depth); } +/* + Method: Image#decipher(passphrase) + Purpose: call DecipherImage +*/ +VALUE +Image_decipher(VALUE self, VALUE passphrase) +{ +#if defined(HAVE_ENCIPHERIMAGE) + Image *image, *new_image; + char *pf; + ExceptionInfo exception; + MagickBooleanType okay; + + image = rm_check_destroyed(self); + pf = StringValuePtr(passphrase); // ensure passphrase is a string + GetExceptionInfo(&exception); + + new_image = rm_clone_image(image); + + okay = DecipherImage(new_image, pf, &exception); + rm_check_exception(&exception, new_image, DestroyOnError); + if (!okay) + { + new_image = DestroyImage(new_image); + rb_raise(rb_eRuntimeError, "DecipherImage failed for unknown reason."); + } + + DestroyExceptionInfo(&exception); + + return rm_image_new(new_image); +#else + self = self; + passphrase = passphrase; + rm_not_implemented(); + return (VALUE)0; +#endif +} + + DEF_ATTR_ACCESSOR(Image, delay, ulong) /* Method: Image#delete_profile(name) @@ -3836,11 +3936,50 @@ { return effect_image(self, argc, argv, EmbossImage); } +/* + Method: Image#encipher(passphrase) + Purpose: call EncipherImage +*/ +VALUE +Image_encipher(VALUE self, VALUE passphrase) +{ +#if defined(HAVE_ENCIPHERIMAGE) + Image *image, *new_image; + char *pf; + ExceptionInfo exception; + MagickBooleanType okay; + image = rm_check_destroyed(self); + pf = StringValuePtr(passphrase); // ensure passphrase is a string + GetExceptionInfo(&exception); + + new_image = rm_clone_image(image); + + okay = EncipherImage(new_image, pf, &exception); + rm_check_exception(&exception, new_image, DestroyOnError); + if (!okay) + { + new_image = DestroyImage(new_image); + rb_raise(rb_eRuntimeError, "EncipherImage failed for unknown reason."); + } + + DestroyExceptionInfo(&exception); + + return rm_image_new(new_image); +#else + self = self; + passphrase = passphrase; + rm_not_implemented(); + return (VALUE)0; +#endif +} + + + /* Method: Image#endian Purpose: Return endian option for images that support it. */ VALUE @@ -5662,22 +5801,21 @@ return rm_image_new(new_image); } /* - Method: Image#mask + Static: get_image_mask Purpose: Return the image's clip mask, or nil if it doesn't have a clip mask. Notes: Distinguish from Image#clip_mask */ -VALUE -Image_mask(VALUE self) +static VALUE +get_image_mask(Image *image) { - Image *image, *mask; + Image *mask; ExceptionInfo exception; - image = rm_check_destroyed(self); GetExceptionInfo(&exception); // The returned clip mask is a clone, ours to keep. mask = GetImageClipMask(image, &exception); rm_check_exception(&exception, mask, DestroyOnError); @@ -5688,27 +5826,54 @@ } /* Method: Image#mask=(mask-image) + Notes: Deprecated in favor of Image#mask(mask-image). See below. +*/ +VALUE +Image_mask_eq(VALUE self, VALUE mask) +{ + VALUE v[1]; + v[0] = mask; + return Image_mask(1, v, self); +} + + +/* + Method: Image#mask([mask-image]) Purpose: associates a clip mask with the image + Returns: Copy of the current clip-mask + Notes: Omit the argument to get a copy of the current clip mask. Notes: pass "nil" for the mask-image to remove the current clip mask. If the clip mask is not the same size as the target image, resizes the clip mask to match the target. Notes: Distinguish from Image#clip_mask= */ VALUE -Image_mask_eq(VALUE self, VALUE mask) +Image_mask(int argc, VALUE *argv, VALUE self) { + volatile VALUE mask; Image *image, *mask_image, *resized_image; Image *clip_mask; long x, y; PixelPacket *q; ExceptionInfo exception; - image = rm_check_frozen(self); + image = rm_check_destroyed(self); + if (argc == 0) + { + return get_image_mask(image); + } + if (argc > 1) + { + rb_raise(rb_eArgError, "wrong number of arguments (expected 0 or 1, got %d)", argc); + } + rb_check_frozen(self); + mask = argv[0]; + if (mask != Qnil) { mask = ImageList_cur_image(mask); mask_image = rm_check_destroyed(mask); clip_mask = rm_clone_image(mask_image); @@ -5769,18 +5934,19 @@ else { (void) SetImageClipMask(image, NULL); } - return self; + // Always return a copy of the mask! + return get_image_mask(image); } /* Method: Image#matte Purpose: Get matte attribute - Notes: Deprecated as of ImageMagick 6.3.6 + Notes: Deprecated as of ImageMagick 6.3.6. See Image#alpha */ VALUE Image_matte(VALUE self) { Image *image; @@ -5791,11 +5957,11 @@ /* Method: Image#matte= Purpose: Set matte attribute - Notes: Deprecated as of ImageMagick 6.3.6. Calls Image_matte_eq. + Notes: Deprecated as of ImageMagick 6.3.6. See Image#alpha */ VALUE Image_matte_eq(VALUE self, VALUE matte) { #if defined(HAVE_TYPE_ALPHACHANNELTYPE) || defined(HAVE_SETIMAGEALPHACHANNEL) @@ -6477,10 +6643,10 @@ { case 4: fuzz = NUM2DBL(argv[3]); if (fuzz < 0.0) { - rb_raise(rb_eArgError, "fuzz must be >= 0.0", fuzz); + rb_raise(rb_eArgError, "fuzz must be >= 0.0 (%g given)", fuzz); } case 3: invert = RTEST(argv[2]); case 2: // Allow color name or Pixel