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))); }