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