ext/RMagick/rmimage.c in rmagick-2.1.0 vs ext/RMagick/rmimage.c in rmagick-2.2.0
- old
+ new
@@ -1,6 +1,6 @@
-/* $Id: rmimage.c,v 1.277 2008/01/08 23:47:33 rmagick Exp $ */
+/* $Id: rmimage.c,v 1.279 2008/01/28 22:31:50 rmagick Exp $ */
/*============================================================================\
| Copyright (C) 2008 by Timothy P. Hunter
| Name: rmimage.c
| Author: Tim Hunter
| Purpose: Image class method definitions for RMagick
@@ -5453,11 +5453,59 @@
rm_not_implemented();
return(VALUE)0;
#endif
}
+
/*
+ Method: Image#liquid_rescale(columns, rows, delta_x=0.0, rigidity=0.0)
+ Purpose: Call the LiquidRescaleImage API
+*/
+VALUE
+Image_liquid_rescale(int argc, VALUE *argv, VALUE self)
+{
+#if defined(HAVE_LIQUIDRESCALEIMAGE)
+ Image *image, *new_image;
+ unsigned long cols, rows;
+ double delta_x = 0.0;
+ double rigidity = 0.0;
+ ExceptionInfo exception;
+
+ image = rm_check_destroyed(self);
+
+ switch (argc)
+ {
+ case 4:
+ rigidity = NUM2DBL(argv[3]);
+ case 3:
+ delta_x = NUM2DBL(argv[2]);
+ case 2:
+ rows = NUM2ULONG(argv[1]);
+ cols = NUM2ULONG(argv[0]);
+ break;
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 to 4)", argc);
+ break;
+ }
+
+ GetExceptionInfo(&exception);
+ new_image = LiquidRescaleImage(image, cols, rows, delta_x, rigidity, &exception);
+ rm_check_exception(&exception, new_image, DestroyOnError);
+ DestroyExceptionInfo(&exception);
+ rm_ensure_result(new_image);
+
+ return rm_image_new(new_image);
+#else
+ argc = argc; // defeat "unused parameter" messages
+ argv = argv;
+ self = self;
+ rm_not_implemented();
+ return(VALUE)0;
+#endif
+}
+
+/*
Method: Image._load
Purpose: implement marshalling
Notes: calls BlobToImage - see Image#_dump
*/
VALUE
@@ -6371,25 +6419,113 @@
Image_opaque(VALUE self, VALUE target, VALUE fill)
{
Image *image, *new_image;
MagickPixelPacket target_pp;
MagickPixelPacket fill_pp;
+ MagickBooleanType okay;
image = rm_check_destroyed(self);
new_image = rm_clone_image(image);
// Allow color name or Pixel
Color_to_MagickPixelPacket(image, &target_pp, target);
Color_to_MagickPixelPacket(image, &fill_pp, fill);
- (void) PaintOpaqueImage(new_image, &target_pp, &fill_pp);
+#if defined(HAVE_OPAQUEPAINTIMAGECHANNEL)
+ okay = OpaquePaintImageChannel(new_image, DefaultChannels, &target_pp, &fill_pp, MagickFalse);
+#else
+ okay = PaintOpaqueImageChannel(new_image, DefaultChannels, &target_pp, &fill_pp);
+#endif
rm_check_image_exception(new_image, DestroyOnError);
+ if (!okay)
+ {
+ // Force exception
+ DestroyImage(new_image);
+ rm_ensure_result(NULL);
+ }
+
return rm_image_new(new_image);
}
+
/*
+ Method: Image#opaque_channel
+ Purpose: Improved Image#opaque available in 6.3.7-10
+ Notes: opaque_channel(target, fill, invert=false, fuzz=img.fuzz [, channel...])
+*/
+VALUE
+Image_opaque_channel(int argc, VALUE *argv, VALUE self)
+{
+#if defined(HAVE_OPAQUEPAINTIMAGECHANNEL)
+ Image *image, *new_image;
+ MagickPixelPacket target_pp, fill_pp;
+ ChannelType channels;
+ double keep, fuzz;
+ MagickBooleanType okay, invert = MagickFalse;
+
+ image = rm_check_destroyed(self);
+ channels = extract_channels(&argc, argv);
+ if (argc > 4)
+ {
+ raise_ChannelType_error(argv[argc-1]);
+ }
+
+ // Default fuzz value is image's fuzz attribute.
+ fuzz = image->fuzz;
+
+ switch (argc)
+ {
+ case 4:
+ fuzz = NUM2DBL(argv[3]);
+ if (fuzz < 0.0)
+ {
+ rb_raise(rb_eArgError, "fuzz must be >= 0.0", fuzz);
+ }
+ case 3:
+ invert = RTEST(argv[2]);
+ case 2:
+ // Allow color name or Pixel
+ Color_to_MagickPixelPacket(image, &fill_pp, argv[1]);
+ Color_to_MagickPixelPacket(image, &target_pp, argv[0]);
+ break;
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (got %d, expected 2 or more)", argc);
+ break;
+ }
+
+ new_image = rm_clone_image(image);
+ keep = new_image->fuzz;
+ new_image->fuzz = fuzz;
+
+ okay = OpaquePaintImageChannel(new_image, channels, &target_pp, &fill_pp, invert);
+
+ // Restore saved fuzz value
+ new_image->fuzz = keep;
+ rm_check_image_exception(new_image, DestroyOnError);
+
+ if (!okay)
+ {
+ // Force exception
+ DestroyImage(new_image);
+ rm_ensure_result(NULL);
+ }
+
+ return rm_image_new(new_image);
+
+#else
+ argc = argc; // defeat "unused parameter" messages
+ argv = argv;
+ self = self;
+ rm_not_implemented();
+ return (VALUE)0;
+#endif
+}
+
+
+
+/*
Method: Image#opaque?
Purpose: return true if any of the pixels in the image have an opacity
value other than opaque ( 0 )
*/
VALUE
@@ -6507,11 +6643,76 @@
Image *image = rm_check_frozen(self);
Rectangle_to_RectangleInfo(&image->page, rect);
return self;
}
+
/*
+ Method: Image#paint_transparent(target, opacity=TransparentOpacity, invert=false, fuzz=img.fuzz)
+ Purpose: Improved version of Image#transparent available in 6.3.7-10
+*/
+VALUE
+Image_paint_transparent(int argc, VALUE *argv, VALUE self)
+{
+#if defined(HAVE_TRANSPARENTPAINTIMAGE)
+ Image *image, *new_image;
+ MagickPixelPacket color;
+ Quantum opacity = TransparentOpacity;
+ double keep, fuzz;
+ MagickBooleanType okay, invert = MagickFalse;
+
+ image = rm_check_destroyed(self);
+
+ // Default fuzz value is image's fuzz attribute.
+ fuzz = image->fuzz;
+
+ switch (argc)
+ {
+ case 4:
+ fuzz = NUM2DBL(argv[3]);
+ case 3:
+ invert = RTEST(argv[2]);
+ case 2:
+ opacity = APP2QUANTUM(argv[1]);
+ case 1:
+ Color_to_MagickPixelPacket(image, &color, argv[0]);
+ break;
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 4)", argc);
+ break;
+ }
+
+ new_image = rm_clone_image(image);
+
+ // Use fuzz value from caller
+ keep = new_image->fuzz;
+ new_image->fuzz = fuzz;
+
+ okay = TransparentPaintImage(new_image, &color, opacity, invert);
+ new_image->fuzz = keep;
+
+ // Is it possible for TransparentPaintImage to silently fail?
+ rm_check_image_exception(new_image, DestroyOnError);
+ if (!okay)
+ {
+ // Force exception
+ DestroyImage(new_image);
+ rm_ensure_result(NULL);
+ }
+
+ return rm_image_new(new_image);
+#else
+ argc = argc; // defeat "unused parameter" messages
+ argv = argv;
+ self = self;
+ rm_not_implemented();
+ return (VALUE)0;
+#endif
+}
+
+
+/*
Method: Image#palette?
Purpose: return true if the image is PseudoClass and has 256 unique
colors or less.
*/
VALUE
@@ -9093,10 +9294,11 @@
Image_transparent(int argc, VALUE *argv, VALUE self)
{
Image *image, *new_image;
MagickPixelPacket color;
Quantum opacity = TransparentOpacity;
+ MagickBooleanType okay;
image = rm_check_destroyed(self);
switch (argc)
{
@@ -9110,12 +9312,22 @@
break;
}
new_image = rm_clone_image(image);
- (void) PaintTransparentImage(new_image, &color, opacity);
+#if defined(HAVE_TRANSPARENTPAINTIMAGE)
+ okay = TransparentPaintImage(new_image, &color, opacity, MagickFalse);
+#else
+ okay = PaintTransparentImage(new_image, &color, opacity);
+#endif
rm_check_image_exception(new_image, DestroyOnError);
+ if (!okay)
+ {
+ // Force exception
+ DestroyImage(new_image);
+ rm_ensure_result(NULL);
+ }
return rm_image_new(new_image);
}
@@ -10184,10 +10396,10 @@
is unexpectedly encountered
*/
void
raise_ChannelType_error(VALUE arg)
{
- rb_raise(rb_eTypeError, "argument needs to be a ChannelType (%s given)"
+ rb_raise(rb_eTypeError, "argument must be a ChannelType value (%s given)"
, rb_class2name(CLASS_OF(arg)));
}