ext/RMagick/rmimage.c in rmagick-1.9.3 vs ext/RMagick/rmimage.c in rmagick-1.10.0

- old
+ new

@@ -1,8 +1,8 @@ -/* $Id: rmimage.c,v 1.123 2005/09/26 23:37:04 rmagick Exp $ */ +/* $Id: rmimage.c,v 1.139 2006/01/18 00:22:33 rmagick Exp $ */ /*============================================================================\ -| Copyright (C) 2005 by Timothy P. Hunter +| Copyright (C) 2006 by Timothy P. Hunter | Name: rmimage.c | Author: Tim Hunter | Purpose: Image class method definitions for RMagick \============================================================================*/ @@ -24,11 +24,11 @@ typedef unsigned int (thresholder_t)(Image *, const char *); typedef Image *(xformer_t)(const Image *, const RectangleInfo *, ExceptionInfo *); static VALUE effect_image(VALUE, int, VALUE *, effector_t *); static VALUE rd_image(VALUE, VALUE, reader_t); -static VALUE scale_image(int, int, VALUE *, VALUE, scaler_t *); +static VALUE scale(int, int, VALUE *, VALUE, scaler_t *); static VALUE cropper(int, int, VALUE *, VALUE); static VALUE xform_image(int, VALUE, VALUE, VALUE, VALUE, VALUE, xformer_t); static VALUE threshold_image(int, VALUE *, VALUE, thresholder_t); static VALUE array_from_images(Image *); static ChannelType extract_channels(int *, VALUE *); @@ -45,11 +45,10 @@ Returns: a new image */ VALUE Image_adaptive_threshold(int argc, VALUE *argv, VALUE self) { -#ifdef HAVE_ADAPTIVETHRESHOLDIMAGE Image *image, *new_image; unsigned long width = 3, height = 3, offset = 0; ExceptionInfo exception; switch (argc) @@ -70,14 +69,10 @@ GetExceptionInfo(&exception); new_image = AdaptiveThresholdImage(image, width, height, offset, &exception); HANDLE_ERROR return rm_image_new(new_image); -#else - rm_not_implemented(); - return (VALUE)0; -#endif } /* Method: Image#add_noise(noise_type) Purpose: add random noise to a copy of the image @@ -85,23 +80,65 @@ */ VALUE Image_add_noise(VALUE self, VALUE noise) { Image *image, *new_image; - NoiseType nt; + NoiseType noise_type; ExceptionInfo exception; Data_Get_Struct(self, Image, image); + GetExceptionInfo(&exception); + VALUE_TO_ENUM(noise, noise_type, NoiseType); - VALUE_TO_ENUM(noise, nt, NoiseType); - new_image = AddNoiseImage(image, nt, &exception); + new_image = AddNoiseImage(image, noise_type, &exception); HANDLE_ERROR return rm_image_new(new_image); } /* + Method: Image#add_noise_channel(noise_type[,channel...]) + Purpose: add random noise to a copy of the image + Returns: a new image +*/ +VALUE +Image_add_noise_channel(int argc, VALUE *argv, VALUE self) +{ +#if defined(HAVE_ADDNOISEIMAGECHANNEL) + Image *image, *new_image; + NoiseType noise_type; + ExceptionInfo exception; + ChannelType channels; + + channels = extract_channels(&argc, argv); + + // There must be 1 remaining argument. + if (argc == 0) + { + rb_raise(rb_eArgError, "missing noise type argument"); + } + else if (argc > 1) + { + raise_ChannelType_error(argv[argc-1]); + } + + Data_Get_Struct(self, Image, image); + GetExceptionInfo(&exception); + VALUE_TO_ENUM(argv[0], noise_type, NoiseType); + channels &= ~OpacityChannel; + + new_image = AddNoiseImageChannel(image, channels, noise_type, &exception); + HANDLE_ERROR + return rm_image_new(new_image); + +#else + rm_not_implemented(); + return (VALUE)0; +#endif +} + +/* Method: Image#affine_transform(affine_matrix) Purpose: transforms an image as dictated by the affine matrix argument Returns: a new image */ VALUE @@ -632,11 +669,11 @@ rb_ary_store(ary, 1, ULONG2NUM(rect.height)); rb_ary_store(ary, 2, self); return rb_yield(ary); -#elif defined(HAVE_GETMAGICKGEOMETRY) +#else Image *image; char *geometry; unsigned int flags; long x, y; unsigned long width, height; @@ -661,13 +698,10 @@ rb_ary_store(ary, 1, ULONG2NUM(height)); rb_ary_store(ary, 2, self); return rb_yield(ary); -#else - rm_not_implemented(); - return (VALUE)0; #endif } /* @@ -1244,21 +1278,21 @@ profile = rb_str_new2(str); DestroyString(str); } #else /* !defined(HAVE_ACQUIRESTRINGINFO) */ - const char *str; + const unsigned char *str; size_t length; Data_Get_Struct(self, Image, image); profile = Qnil; /* Assume no profile defined */ length = 0; str = GetImageProfile(image, "icc", &length); if (str) { - profile = rb_str_new(str, length); + profile = rb_str_new((char *)str, length); } #endif #else @@ -1353,11 +1387,11 @@ { (void) SetImageProfile(image, "icc", NULL, 0); } else { - prof = STRING_PTR_LEN(profile, prof_l); + prof = (unsigned char *)STRING_PTR_LEN(profile, prof_l); (void) SetImageProfile(image, "icc", prof, (size_t)prof_l); } #endif /* defined(HAVE_SETIMAGEPROFILE) */ #else @@ -2111,11 +2145,15 @@ { rb_raise(rb_eNoMemError, "not enough memory to continue."); } image->columns = width; image->rows = height; +#if defined(HAVE_SETIMAGEBACKGROUNDCOLOR) + SetImageBackgroundColor(image); +#else SetImage(image, OpaqueOpacity); +#endif okay = ImportImagePixels(image, 0, 0, width, height, map, stg_type, (void *)pixels.v); if (!okay) { // Save exception info, delete the image, then raise the exception. exception = image->exception; @@ -2975,54 +3013,69 @@ { Image *image; rm_check_frozen(self); Data_Get_Struct(self, Image, image); + +#if defined(HAVE_SETIMAGEBACKGROUNDCOLOR) + SetImageBackgroundColor(image); +#else SetImage(image, OpaqueOpacity); +#endif return self; } /* - Method: Image#export_pixels + Method: Image#export_pixels(x=0, y=0, cols=self.columns, rows=self.rows, map="RGB") Purpose: extract image pixels in the form of an array */ VALUE -Image_export_pixels( - VALUE self, - VALUE x_arg, - VALUE y_arg, - VALUE cols_arg, - VALUE rows_arg, - VALUE map_arg) +Image_export_pixels(int argc, VALUE *argv, VALUE self) { #if defined(HAVE_EXPORTIMAGEPIXELS) Image *image; - long x_off, y_off; + long x_off = 0L, y_off = 0L; unsigned long cols, rows; unsigned long n, npixels; unsigned int okay; - char *map; + char *map = "RGB"; volatile unsigned int *pixels; volatile VALUE ary; ExceptionInfo exception; Data_Get_Struct(self, Image, image); - x_off = NUM2LONG(x_arg); - y_off = NUM2LONG(y_arg); - cols = NUM2ULONG(cols_arg); - rows = NUM2ULONG(rows_arg); + cols = image->columns; + rows = image->rows; + switch (argc) + { + case 5: + map = STRING_PTR(argv[4]); + case 4: + rows = NUM2ULONG(argv[3]); + case 3: + cols = NUM2ULONG(argv[2]); + case 2: + y_off = NUM2LONG(argv[1]); + case 1: + x_off = NUM2LONG(argv[0]); + case 0: + break; + default: + rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 5)", argc); + break; + } + if ( x_off < 0 || x_off > image->columns || y_off < 0 || y_off > image->rows || cols == 0 || rows == 0) { rb_raise(rb_eArgError, "invalid extract geometry"); } - map = STRING_PTR(map_arg); npixels = cols * rows * strlen(map); pixels = ALLOC_N(unsigned int, npixels); if (!pixels) // app recovered from exception { @@ -3056,10 +3109,122 @@ return (VALUE)0; #endif } /* + Method: Image#export_pixels_to_str(x=0, y=0, cols=self.columns, + rows=self.rows, map="RGB", type=Magick::CharPixel) + Purpose: extract image pixels to a Ruby string +*/ +VALUE +Image_export_pixels_to_str(int argc, VALUE *argv, VALUE self) +{ +#if defined(HAVE_EXPORTIMAGEPIXELS) + Image *image; + long x_off = 0L, y_off = 0L; + unsigned long cols, rows; + unsigned long npixels; + size_t sz; + unsigned int okay; + char *map = "RGB"; + StorageType type = CharPixel; + volatile VALUE string; + char *str; + ExceptionInfo exception; + + Data_Get_Struct(self, Image, image); + cols = image->columns; + rows = image->rows; + + switch (argc) + { + case 6: + VALUE_TO_ENUM(argv[5], type, StorageType); + case 5: + map = STRING_PTR(argv[4]); + case 4: + rows = NUM2ULONG(argv[3]); + case 3: + cols = NUM2ULONG(argv[2]); + case 2: + y_off = NUM2LONG(argv[1]); + case 1: + x_off = NUM2LONG(argv[0]); + case 0: + break; + default: + rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 6)", argc); + break; + } + + if ( x_off < 0 || x_off > image->columns + || y_off < 0 || y_off > image->rows + || cols == 0 || rows == 0) + { + rb_raise(rb_eArgError, "invalid extract geometry"); + } + + + npixels = cols * rows * strlen(map); + switch (type) + { + case CharPixel: + sz = sizeof(unsigned char); + break; + case ShortPixel: + sz = sizeof(unsigned short); + break; + case DoublePixel: + sz = sizeof(double); + break; + case FloatPixel: + sz = sizeof(float); + break; + case IntegerPixel: + sz = sizeof(unsigned int); + break; + case LongPixel: + sz = sizeof(unsigned long); + break; +#if defined(HAVE_QUANTUMPIXEL) + case QuantumPixel: + sz = sizeof(Quantum); + break; +#endif + case UndefinedPixel: + default: + rb_raise(rb_eArgError, "undefined storage type"); + break; + } + + // Allocate a string long enough to hold the exported pixel data. + // Get a pointer to the buffer. + string = rb_str_new2(""); + rb_str_resize(string, (long)(sz * npixels)); + str = STRING_PTR(string); + + GetExceptionInfo(&exception); + + okay = ExportImagePixels(image, x_off, y_off, cols, rows, map, type, (void *)str, &exception); + if (!okay) + { + // Let GC have the string buffer. + rb_str_resize(string, 0); + HANDLE_ERROR + // Should never get here... + rb_raise(rb_eStandardError, "ExportImagePixels failed with no explanation."); + } + + return string; + +#else + rm_not_implemented(); + return (VALUE)0; +#endif +} + +/* Method: Image#extract_info, extract_info= Purpose: the extract_info attribute accessors */ VALUE Image_extract_info(VALUE self) @@ -3758,11 +3923,11 @@ */ VALUE Image_import_pixels(int argc, VALUE *argv, VALUE self) { #if defined(HAVE_IMPORTIMAGEPIXELS) - Image *image, *clone_image; + Image *image; long x_off, y_off; unsigned long cols, rows; unsigned long npixels; long n, buffer_l; char *map; @@ -3770,11 +3935,10 @@ StorageType stg_type = CharPixel; size_t type_sz, map_l; volatile int *pixels = NULL; volatile void *buffer; unsigned int okay; - ExceptionInfo exception; rm_check_frozen(self); switch (argc) { @@ -3881,35 +4045,25 @@ buffer = (void *) pixels; stg_type = IntegerPixel; } - // Import into a clone - ImportImagePixels destroys the input image if an error occurs. - GetExceptionInfo(&exception); - clone_image = CloneImage(image, 0, 0, True, &exception); - HANDLE_ERROR + okay = ImportImagePixels(image, x_off, y_off, cols, rows, map, stg_type, (const void *)buffer); - okay = ImportImagePixels(clone_image, x_off, y_off, cols, rows, map, stg_type, (const void *)buffer); - - // Free pixel array before checking for errors. If an error occurred, ImportImagePixels - // destroyed the clone image, so we don't have to. + // Free pixel array before checking for errors. if (pixels) { xfree((void *)pixels); } if (!okay) { - HANDLE_ERROR_IMG(clone_image) + HANDLE_ERROR_IMG(image) // Shouldn't get here... rb_raise(rb_eStandardError, "ImportImagePixels failed with no explanation."); } - // Everything worked. Replace the image with the clone and destroy the original. - DATA_PTR(self) = clone_image; - DestroyImage(image); - return self; #else rm_not_implemented(); return (VALUE)0; @@ -3940,15 +4094,11 @@ x += sprintf(buffer+x, "%s=>", image->magick_filename); } // Print current filename. x += sprintf(buffer+x, "%s", image->filename); // Print scene number. -#if defined(HAVE_GETNEXTIMAGEINLIST) if ((GetPreviousImageInList(image) != NULL) && (GetNextImageInList(image) != NULL) && image->scene > 0) -#else - if ((image->previous || image->next) && image->scene > 0) -#endif { x += sprintf(buffer+x, "[%lu]", image->scene); } // Print format x += sprintf(buffer+x, " %s ", image->magick); @@ -4121,11 +4271,11 @@ profile = Qnil; /* Assume no profile defined */ prof = GetImageProfile(image, "iptc", &length); if (prof) { - profile = rb_str_new(prof, (long) length); + profile = rb_str_new((char *)prof, (long) length); } #endif #else @@ -4218,11 +4368,11 @@ { (void) SetImageProfile(image, "iptc", NULL, 0); } else { - prof = STRING_PTR_LEN(profile, prof_l); + prof = (unsigned char *)STRING_PTR_LEN(profile, prof_l); (void) SetImageProfile(image, "iptc", prof, (size_t)prof_l); } #endif #else @@ -4309,11 +4459,10 @@ Notes: black and white are 0-MaxRGB, mid is 0-10. */ VALUE Image_level_channel(int argc, VALUE *argv, VALUE self) { -#ifdef HAVE_LEVELIMAGECHANNEL Image *image, *new_image; double black_point = 0.0, mid_point = 1.0, white_point = (double)MaxRGB; ChannelType channel; ExceptionInfo exception; @@ -4351,14 +4500,10 @@ , black_point , mid_point , white_point); HANDLE_ERROR_IMG(new_image) return rm_image_new(new_image); -#else - rm_not_implemented(); - return (VALUE)0; -#endif } /* Method: Image._load Purpose: implement marshalling @@ -4983,11 +5128,15 @@ // If the caller did not supply a fill argument, call SetImage to fill the // image using the background color. The background color can be set by // specifying it when creating the Info parm block. if (!fill) { +#if defined(HAVE_SETIMAGEBACKGROUNDCOLOR) + SetImageBackgroundColor(image); +#else SetImage(image, OpaqueOpacity); +#endif } // fillobj.fill(self) else { (void) rb_funcall(fill, ID_fill, 1, self); @@ -5252,27 +5401,58 @@ HANDLE_ERROR return r ? Qtrue : Qfalse; } /* - Method: Image#ordered_dither - Purpose: call OrderedDitherImage + Method: Image#ordered_dither(order=2) + Purpose: perform ordered dither on image + Notes: order must be 2, 3, or 4 + I don't call OrderedDitherImages anymore. Sometime after + IM 6.0.0 it quit working. IM and GM use the routines I use + below to implement the "ordered-dither" option. */ VALUE -Image_ordered_dither(VALUE self) +Image_ordered_dither(int argc, VALUE *argv, VALUE self) { Image *image, *new_image; + int order; + const char *thresholds = "2x2"; ExceptionInfo exception; + if (argc > 1) + { + rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc); + } + if (argc == 1) + { + order = NUM2INT(argv[0]); + if (order == 3) + { + thresholds = "3x3"; + } + else if (order == 4) + { + thresholds = "4x4"; + } + else if (order != 2) + { + rb_raise(rb_eArgError, "order must be 2, 3, or 4 (%d given)", order); + } + } + + Data_Get_Struct(self, Image, image); GetExceptionInfo(&exception); new_image = CloneImage(image, 0, 0, True, &exception); HANDLE_ERROR - - (void) OrderedDitherImage(new_image); - HANDLE_ERROR_IMG(new_image) +#if defined(HAVE_RANDOMTHRESHOLDIMAGECHANNEL) + (void) RandomThresholdImageChannel(new_image, AllChannels, thresholds, &exception); +#else + (void) RandomChannelThresholdImage(new_image, "all", thresholds, &exception); +#endif + HANDLE_ERROR return rm_image_new(new_image); } /* Method: Image#orientation @@ -6172,22 +6352,15 @@ Image *image, *next; // Orphan the image, create an Image object, add it to the array. image_ary = rb_ary_new(); - #ifdef HAVE_REMOVEFIRSTIMAGEFROMLIST + next = NULL; next = next; // defeat "never referenced" message from icc while (images) { image = RemoveFirstImageFromList(&images); - - #else - for (image = images; image; image = next) - { - next = images->next; - image->next = image->previous = NULL; - #endif image_obj = rm_image_new(image); rb_ary_push(image_ary, image_obj); } return image_ary; @@ -6256,11 +6429,11 @@ { Image *image, *new_image; double scale; FilterTypes filter; unsigned long rows, columns; - double blur; + double blur, drows, dcols; ExceptionInfo exception; Data_Get_Struct(self, Image, image); // Set up defaults @@ -6276,15 +6449,29 @@ case 3: VALUE_TO_ENUM(argv[2], filter, FilterTypes); case 2: rows = NUM2ULONG(argv[1]); columns = NUM2ULONG(argv[0]); + if (columns == 0 || rows == 0) + { + rb_raise(rb_eArgError, "invalid result dimension (%lu, %lu given)", columns, rows); + } break; case 1: scale = NUM2DBL(argv[0]); - rows = scale * image->rows; - columns = scale * image->columns; + if (scale < 0.0) + { + rb_raise(rb_eArgError, "invalid scale value (%g given)", scale); + } + drows = scale * image->rows + 0.5; + dcols = scale * image->columns + 0.5; + if (drows > ULONG_MAX || dcols > ULONG_MAX) + { + rb_raise(rb_eRangeError, "resulting image too big"); + } + rows = (unsigned long) drows; + columns = (unsigned long) dcols; break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 4)", argc); break; } @@ -6384,18 +6571,18 @@ sample!: self, sampled */ VALUE Image_sample(int argc, VALUE *argv, VALUE self) { - return scale_image(False, argc, argv, self, SampleImage); + return scale(False, argc, argv, self, SampleImage); } VALUE Image_sample_bang(int argc, VALUE *argv, VALUE self) { rm_check_frozen(self); - return scale_image(True, argc, argv, self, SampleImage); + return scale(True, argc, argv, self, SampleImage); } /* Method: Image#scale(scale) or (cols, rows) Image#scale! @@ -6404,54 +6591,60 @@ scale!: self, scaled */ VALUE Image_scale(int argc, VALUE *argv, VALUE self) { - return scale_image(False, argc, argv, self, ScaleImage); + return scale(False, argc, argv, self, ScaleImage); } VALUE Image_scale_bang(int argc, VALUE *argv, VALUE self) { rm_check_frozen(self); - return scale_image(True, argc, argv, self, ScaleImage); + return scale(True, argc, argv, self, ScaleImage); } /* - Static: scale_image + Static: scale Purpose: Call ScaleImage or SampleImage Arguments: if 1 argument > 0, multiply current size by this much if 2 arguments, (cols, rows) */ static VALUE -scale_image(int bang, int argc, VALUE *argv, VALUE self, scaler_t *scaler) +scale(int bang, int argc, VALUE *argv, VALUE self, scaler_t *scaler) { Image *image, *new_image; unsigned long columns, rows; - double scale; + double scale, drows, dcols; ExceptionInfo exception; Data_Get_Struct(self, Image, image); switch (argc) { case 2: columns = NUM2ULONG(argv[0]); rows = NUM2ULONG(argv[1]); - if (columns <= 0 || rows <= 0) + if (columns == 0 || rows == 0) { - rb_raise(rb_eArgError, "invalid scale given (%dl, %dl given)", columns, rows); + rb_raise(rb_eArgError, "invalid result dimension (%lu, %lu given)", columns, rows); } break; case 1: scale = NUM2DBL(argv[0]); if (scale <= 0) { rb_raise(rb_eArgError, "invalid scale value (%g given)", scale); } - rows = image->rows * scale; - columns = image->columns * scale; + drows = scale * image->rows + 0.5; + dcols = scale * image->columns + 0.5; + if (drows > ULONG_MAX || dcols > ULONG_MAX) + { + rb_raise(rb_eRangeError, "resulting image too big"); + } + rows = (unsigned long) drows; + columns = (unsigned long) dcols; break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc); break; } @@ -7551,28 +7744,41 @@ Notes: Uses BoxFilter, blur attribute of input image */ static VALUE thumbnail(int bang, int argc, VALUE *argv, VALUE self) { -#ifdef HAVE_THUMBNAILIMAGE Image *image, *new_image; unsigned long columns, rows; - double scale; + double scale, drows, dcols; ExceptionInfo exception; Data_Get_Struct(self, Image, image); switch (argc) { case 2: columns = NUM2ULONG(argv[0]); rows = NUM2ULONG(argv[1]); + if (columns == 0 || rows == 0) + { + rb_raise(rb_eArgError, "invalid result dimension (%lu, %lu given)", columns, rows); + } break; case 1: scale = NUM2DBL(argv[0]); - rows = scale * image->rows; - columns = scale * image->columns; + if (scale < 0.0) + { + rb_raise(rb_eArgError, "invalid scale value (%g given)", scale); + } + drows = scale * image->rows + 0.5; + dcols = scale * image->columns + 0.5; + if (drows > ULONG_MAX || dcols > ULONG_MAX) + { + rb_raise(rb_eRangeError, "resulting image too big"); + } + rows = (unsigned long) drows; + columns = (unsigned long) dcols; break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc); break; } @@ -7587,14 +7793,10 @@ DestroyImage(image); return self; } return rm_image_new(new_image); -#else - rm_not_implemented(); - return (VALUE)0; -#endif } VALUE Image_thumbnail(int argc, VALUE *argv, VALUE self) { @@ -7770,10 +7972,11 @@ VALUE Image_to_blob(VALUE self) { Image *image; Info *info; + const MagickInfo *magick_info; volatile VALUE info_obj; volatile VALUE blob_str; void *blob = NULL; size_t length = 2048; // Do what Magick++ does ExceptionInfo exception; @@ -7805,10 +8008,24 @@ return Qnil; } strncpy(image->magick, info->magick, sizeof(info->magick)-1); } + // Fix #2844 - libjpeg exits when image is 0x0 + magick_info = GetMagickInfo(image->magick, &exception); + HANDLE_ERROR + if (magick_info) + { + if ( (!rm_strcasecmp(magick_info->name, "JPEG") + || !rm_strcasecmp(magick_info->name, "JPG")) + && (image->rows == 0 || image->columns == 0)) + { + rb_raise(rb_eRuntimeError, "Can't convert %lux%lu %.4s image to a blob" + , image->columns, image->rows, magick_info->name); + } + } + blob = ImageToBlob(info, image, &length, &exception); HANDLE_ERROR if (length == 0 || !blob) { return Qnil; @@ -8133,10 +8350,64 @@ #endif } /* + Method: Image#vignette(horz_radius, vert_radius, radius, sigma); + Purpose: soften the edges of an image + Notes: The outer edges of the image are replaced by the background color. +*/ +VALUE +Image_vignette(int argc, VALUE *argv, VALUE self) +{ +#if defined(HAVE_VIGNETTEIMAGE) + Image *image, *new_image; + long horz_radius, vert_radius; + double radius = 0.0, sigma = 10.0; + ExceptionInfo exception; + + Data_Get_Struct(self, Image, image); + + horz_radius = image->columns * 0.10 + 0.5; + vert_radius = image->rows * 0.10 + 0.5; + + switch (argc) + { + case 4: + sigma = NUM2DBL(argv[3]); + case 3: + radius = NUM2DBL(argv[2]); + case 2: + vert_radius = NUM2INT(argv[1]); + case 1: + horz_radius = NUM2INT(argv[0]); + case 0: + break; + default: + rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 4)", argc); + break; + } + + GetExceptionInfo(&exception); + + new_image = VignetteImage(image, radius, sigma, horz_radius, vert_radius, &exception); + HANDLE_ERROR + if (!new_image) + { + rb_raise(rb_eRuntimeError, "VignetteImage failed"); + } + + return rm_image_new(new_image); + +#else + rm_not_implemented(); + return (VALUE)0; +#endif +} + + +/* Method: Image#virtual_pixel_method Purpose: get the VirtualPixelMethod for the image */ VALUE Image_virtual_pixel_method(VALUE self) @@ -8530,15 +8801,17 @@ VALUE_TO_ENUM(arg, ch_arg, ChannelType); channels |= ch_arg; *argc -= 1; } -#if defined(HAVE_ALLCHANNELS) if (channels == 0) { +#if defined(HAVE_ALLCHANNELS) channels = AllChannels; - } +#else + channels = 0xff; #endif + } return channels; }