ext/RMagick/rmimage.c in rmagick-2.3.0 vs ext/RMagick/rmimage.c in rmagick-2.4.0
- old
+ new
@@ -1,6 +1,6 @@
-/* $Id: rmimage.c,v 1.288 2008/03/23 15:15:46 rmagick Exp $ */
+/* $Id: rmimage.c,v 1.295 2008/06/02 22:47:37 rmagick Exp $ */
/*============================================================================\
| Copyright (C) 2008 by Timothy P. Hunter
| Name: rmimage.c
| Author: Tim Hunter
| Purpose: Image class method definitions for RMagick
@@ -24,11 +24,11 @@
static VALUE rotate(int, int, VALUE *, VALUE);
static VALUE scale(int, int, VALUE *, VALUE, scaler_t);
static VALUE threshold_image(int, VALUE *, VALUE, thresholder_t);
static VALUE xform_image(int, VALUE, VALUE, VALUE, VALUE, VALUE, xformer_t);
static VALUE array_from_images(Image *);
-static void call_trace_proc(Image *, char *);
+static void call_trace_proc(Image *, const char *);
static const char *BlackPointCompensationKey = "PROFILE:black-point-compensation";
@@ -144,20 +144,20 @@
return adaptive_channel_method(argc, argv, self, AdaptiveBlurImageChannel);
}
/*
- Method: Image#adaptive_resize(scale)
+ Method: Image#adaptive_resize(scale_val)
Image#adaptive_resize(cols, rows)
Purpose: Call AdaptiveResizeImage
*/
VALUE
Image_adaptive_resize(int argc, VALUE *argv, VALUE self)
{
Image *image, *new_image;
unsigned long rows, columns;
- double scale, drows, dcols;
+ double scale_val, drows, dcols;
ExceptionInfo exception;
image = rm_check_destroyed(self);
switch (argc)
@@ -165,17 +165,17 @@
case 2:
rows = NUM2ULONG(argv[1]);
columns = NUM2ULONG(argv[0]);
break;
case 1:
- scale = NUM2DBL(argv[0]);
- if (scale < 0.0)
+ scale_val = NUM2DBL(argv[0]);
+ if (scale_val < 0.0)
{
- rb_raise(rb_eArgError, "invalid scale value (%g given)", scale);
+ rb_raise(rb_eArgError, "invalid scale_val value (%g given)", scale_val);
}
- drows = scale * image->rows + 0.5;
- dcols = scale * image->columns + 0.5;
+ drows = scale_val * image->rows + 0.5;
+ dcols = scale_val * image->columns + 0.5;
if (drows > (double)ULONG_MAX || dcols > (double)ULONG_MAX)
{
rb_raise(rb_eRangeError, "resized image too big");
}
rows = (unsigned long) drows;
@@ -358,12 +358,19 @@
info = CloneImageInfo(NULL);
if (!info)
{
rb_raise(rb_eNoMemError, "not enough memory to continue");
}
- info->client_data= (void *)GetImageProfile(image,"8bim");
-
+#if defined(HAVE_ST_PROFILE)
+ profile = GetImageProfile(image, "iptc");
+ if (profile)
+ {
+ info->profile = (void *)CloneStringInfo(profile);
+ }
+#else
+ info->client_data = GetImageProfile(image, "8bim");
+#endif
strncpy(info->filename, profile_filename, min((size_t)profile_filename_l, sizeof(info->filename)));
info->filename[MaxTextExtent-1] = '\0';
GetExceptionInfo(&exception);
profile_image = ReadImage(info, &exception);
@@ -377,11 +384,12 @@
while (profile_name)
{
profile = GetImageProfile(profile_image, profile_name);
if (profile)
{
- (void)ProfileImage(image, profile_name, profile->datum, (unsigned long)profile->length, MagickFalse);
+ (void)ProfileImage(image, profile_name, GetStringInfoDatum(profile)
+ , GetStringInfoLength(profile), MagickFalse);
if (image->exception.severity >= ErrorException)
{
break;
}
}
@@ -600,17 +608,17 @@
Image#[:key] = attr
Purpose: Update or add image attribute "key"
Returns: self
Notes: Specify attr=nil to remove the key from the list.
- SetImageAttribute normally APPENDS the new value
+ SetImageProperty normally APPENDS the new value
to any existing value. Since this usage is tremendously
counter-intuitive, this function always deletes the
existing value before setting the new value.
There's no use checking the return value since
- SetImageAttribute returns "False" for many reasons,
+ SetImageProperty returns "False" for many reasons,
some legitimate.
*/
VALUE
Image_aset(VALUE self, VALUE key_arg, VALUE attr_arg)
{
@@ -640,20 +648,20 @@
}
break;
}
- // Delete existing value. SetImageAttribute returns False if
+ // Delete existing value. SetImageProperty returns False if
// the attribute doesn't exist - we don't care.
(void) rm_set_property(image, key, NULL);
// Set new value
if (attr)
{
okay = rm_set_property(image, key, attr);
if (!okay)
{
- rb_warning("SetImageAttribute failed (probably out of memory)");
+ rb_warning("SetImageProperty failed (probably out of memory)");
}
}
return self;
}
@@ -922,11 +930,11 @@
*/
VALUE
Image_black_point_compensation_eq(VALUE self, VALUE arg)
{
Image *image;
- char *value;
+ const char *value;
image = rm_check_frozen(self);
(void) rm_set_property(image, BlackPointCompensationKey, NULL);
value = RTEST(arg) ? "true" : "false";
(void) rm_set_property(image, BlackPointCompensationKey, value);
@@ -958,11 +966,11 @@
Image *image,
Image *mark,
long *x_offset,
long *y_offset)
{
- MagickEnum *magick_enum;
+ MagickEnum *m_enum;
GravityType gravity;
VALUE_TO_ENUM(grav, gravity, GravityType);
switch (gravity)
@@ -997,12 +1005,12 @@
case NorthEastGravity:
case NorthGravity:
// Don't let these run into the default case
break;
default:
- Data_Get_Struct(grav, MagickEnum, magick_enum);
- rb_warning("gravity type `%s' has no effect", rb_id2name(magick_enum->id));
+ Data_Get_Struct(grav, MagickEnum, m_enum);
+ rb_warning("gravity type `%s' has no effect", rb_id2name(m_enum->id));
break;
}
}
@@ -2065,11 +2073,36 @@
}
draw_info->fill = fill;
new_image = rm_clone_image(image);
+#if defined(HAVE_FLOODFILLPAINTIMAGE)
+ {
+ MagickPixelPacket target_mpp;
+ MagickBooleanType invert;
+
+ GetMagickPixelPacket(new_image, &target_mpp);
+ if (fill_method == FillToBorderMethod)
+ {
+ invert = MagickTrue;
+ target_mpp.red = (MagickRealType) image->border_color.red;
+ target_mpp.green = (MagickRealType) image->border_color.green;
+ target_mpp.blue = (MagickRealType) image->border_color.blue;
+ }
+ else
+ {
+ invert = MagickFalse;
+ target_mpp.red = (MagickRealType) target.red;
+ target_mpp.green = (MagickRealType) target.green;
+ target_mpp.blue = (MagickRealType) target.blue;
+ }
+
+ (void) FloodfillPaintImage(new_image, DefaultChannels, draw_info, &target_mpp, x, y, invert);
+ }
+#else
(void) ColorFloodfillImage(new_image, draw_info, target, x, y, (PaintMethod)fill_method);
+#endif
// No need to check for error
(void) DestroyDrawInfo(draw_info);
return rm_image_new(new_image);
}
@@ -2139,23 +2172,23 @@
*/
VALUE
Image_colormap(int argc, VALUE *argv, VALUE self)
{
Image *image;
- unsigned long index;
+ unsigned long idx;
PixelPacket color, new_color;
image = rm_check_destroyed(self);
// We can handle either 1 or 2 arguments. Nothing else.
if (argc == 0 || argc > 2)
{
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
}
- index = NUM2ULONG(argv[0]);
- if (index > QuantumRange)
+ idx = NUM2ULONG(argv[0]);
+ if (idx > QuantumRange)
{
rb_raise(rb_eIndexError, "index out of range");
}
// If this is a simple "get" operation, ensure the image has a colormap.
@@ -2165,15 +2198,15 @@
{
rb_raise(rb_eIndexError, "image does not contain a colormap");
}
// Validate the index
- if (index > image->colors-1)
+ if (idx > image->colors-1)
{
rb_raise(rb_eIndexError, "index out of range");
}
- return PixelPacket_to_Color_Name(image, &image->colormap[index]);
+ return PixelPacket_to_Color_Name(image, &image->colormap[idx]);
}
// This is a "set" operation. Things are different.
rb_check_frozen(self);
@@ -2181,37 +2214,37 @@
// Replace with new color? The arg can be either a color name or
// a Magick::Pixel.
Color_to_PixelPacket(&new_color, argv[1]);
// Handle no colormap or current colormap too small.
- if (!image->colormap || index > image->colors-1)
+ if (!image->colormap || idx > image->colors-1)
{
PixelPacket black;
unsigned long i;
memset(&black, 0, sizeof(black));
if (!image->colormap)
{
- image->colormap = (PixelPacket *)magick_safe_malloc((index+1), sizeof(PixelPacket));
+ image->colormap = (PixelPacket *)magick_safe_malloc((idx+1), sizeof(PixelPacket));
image->colors = 0;
}
else
{
- image->colormap = (PixelPacket *)magick_safe_realloc(image->colormap, (index+1), sizeof(PixelPacket));
+ image->colormap = (PixelPacket *)magick_safe_realloc(image->colormap, (idx+1), sizeof(PixelPacket));
}
- for (i = image->colors; i < index; i++)
+ for (i = image->colors; i < idx; i++)
{
image->colormap[i] = black;
}
- image->colors = index+1;
+ image->colors = idx+1;
}
// Save the current color so we can return it. Set the new color.
- color = image->colormap[index];
- image->colormap[index] = new_color;
+ color = image->colormap[idx];
+ image->colormap[idx] = new_color;
return PixelPacket_to_Color_Name(image, &color);
}
DEF_ATTR_READER(Image, colors, ulong)
@@ -2437,11 +2470,11 @@
{
Image *image, *new_image;
Image *comp_image;
CompositeOperator operator = UndefinedCompositeOp;
GravityType gravity;
- MagickEnum *magick_enum;
+ MagickEnum *m_enum;
volatile VALUE comp;
signed long x_offset = 0;
signed long y_offset = 0;
image = rm_check_destroyed(self);
@@ -2555,12 +2588,12 @@
case NorthEastGravity:
case NorthGravity:
// Don't let these run into the default case
break;
default:
- Data_Get_Struct(argv[1], MagickEnum, magick_enum);
- rb_warning("gravity type `%s' has no effect", rb_id2name(magick_enum->id));
+ Data_Get_Struct(argv[1], MagickEnum, m_enum);
+ rb_warning("gravity type `%s' has no effect", rb_id2name(m_enum->id));
break;
}
break;
}
@@ -2611,19 +2644,19 @@
Image_composite_affine(
VALUE self,
VALUE source,
VALUE affine_matrix)
{
- Image *image, *composite, *new_image;
+ Image *image, *composite_image, *new_image;
AffineMatrix affine;
image = rm_check_destroyed(self);
- composite = rm_check_destroyed(source);
+ composite_image = rm_check_destroyed(source);
new_image = rm_clone_image(image);
AffineMatrix_to_AffineMatrix(&affine, affine_matrix);
- (void) DrawAffineImage(new_image, composite, &affine);
+ (void) DrawAffineImage(new_image, composite_image, &affine);
rm_check_image_exception(new_image, DestroyOnError);
return rm_image_new(new_image);
}
@@ -2728,15 +2761,15 @@
volatile VALUE pixel, pixel0;
unsigned long width, height;
long x, npixels;
char *map;
long map_l;
- union
+ volatile union
{
- volatile double *f;
- volatile Quantum *i;
- volatile void *v;
+ double *f;
+ Quantum *i;
+ void *v;
} pixels;
volatile VALUE pixel_class;
StorageType stg_type;
class = class; // Suppress "never referenced" message from icc
@@ -2765,17 +2798,17 @@
// Inspect the first element in the pixels array to determine the expected
// type of all the elements. Allocate the pixel buffer.
pixel0 = rb_ary_entry(pixels_arg, 0);
if (rb_obj_is_kind_of(pixel0, rb_cFloat) == Qtrue)
{
- pixels.f = ALLOC_N(volatile double, npixels);
+ pixels.f = ALLOC_N(double, npixels);
stg_type = DoublePixel;
pixel_class = rb_cFloat;
}
else if (rb_obj_is_kind_of(pixel0, rb_cInteger) == Qtrue)
{
- pixels.i = ALLOC_N(volatile Quantum, npixels);
+ pixels.i = ALLOC_N(Quantum, npixels);
stg_type = QuantumPixel;
pixel_class = rb_cInteger;
}
else
{
@@ -2822,12 +2855,12 @@
rm_check_image_exception(image, DestroyOnError);
(void) SetImageBackgroundColor(image);
rm_check_image_exception(image, DestroyOnError);
- (void) ImportImagePixels(image, 0, 0, width, height, map, stg_type, (void *)pixels.v);
- xfree((void *)pixels.v);
+ (void) ImportImagePixels(image, 0, 0, width, height, map, stg_type, (const void *)pixels.v);
+ xfree(pixels.v);
rm_check_image_exception(image, DestroyOnError);
(void) DestroyExceptionInfo(&exception);
DestroyConstitute();
@@ -2967,11 +3000,11 @@
VALUE self,
VALUE order_arg,
VALUE kernel_arg)
{
Image *image, *new_image;
- volatile double *kernel;
+ double *kernel;
unsigned int x, order;
ExceptionInfo exception;
image = rm_check_destroyed(self);
@@ -2980,20 +3013,20 @@
kernel_arg = rb_Array(kernel_arg);
rm_check_ary_len(kernel_arg, (long)(order*order));
// Convert the kernel array argument to an array of doubles
- kernel = (volatile double *)ALLOC_N(double, order*order);
+ kernel = (double *)ALLOC_N(double, order*order);
for (x = 0; x < order*order; x++)
{
kernel[x] = NUM2DBL(rb_ary_entry(kernel_arg, (long)x));
}
GetExceptionInfo(&exception);
- new_image = ConvolveImage(image, order, (double *)kernel, &exception);
- xfree((double *)kernel);
+ new_image = ConvolveImage((const Image *)image, order, (double *)kernel, &exception);
+ xfree((void *)kernel);
rm_check_exception(&exception, new_image, DestroyOnError);
(void) DestroyExceptionInfo(&exception);
rm_ensure_result(new_image);
@@ -3011,11 +3044,11 @@
int argc,
VALUE *argv,
VALUE self)
{
Image *image, *new_image;
- volatile double *kernel;
+ double *kernel;
volatile VALUE ary;
unsigned int x, order;
ChannelType channels;
ExceptionInfo exception;
@@ -3046,12 +3079,12 @@
kernel[x] = NUM2DBL(rb_ary_entry(ary, (long)x));
}
GetExceptionInfo(&exception);
- new_image = ConvolveImageChannel(image, channels, order, (double *)kernel, &exception);
- xfree((double *)kernel);
+ new_image = ConvolveImageChannel(image, channels, order, kernel, &exception);
+ xfree((void *)kernel);
rm_check_exception(&exception, new_image, DestroyOnError);
(void) DestroyExceptionInfo(&exception);
rm_ensure_result(new_image);
@@ -3457,15 +3490,15 @@
StorageType stg_type = QuantumPixel;
char *map;
long mapL;
MagickBooleanType okay;
ExceptionInfo exception;
- union
+ volatile union
{
- volatile Quantum *i;
- volatile double *f;
- volatile void *v;
+ Quantum *i;
+ double *f;
+ void *v;
} pixels;
(void) rm_check_destroyed(self);
if (argc < 5 || argc > 6)
@@ -3577,22 +3610,22 @@
/*
Method: Image#dissolve(overlay, src_percent, dst_percent, x_offset=0, y_offset=0)
Image#dissolve(overlay, src_percent, dst_percent, gravity, x_offset=0, y_offset=0)
- Purpose: Corresponds to the composite -dissolve operation
+ Purpose: Corresponds to the composite_image -dissolve operation
Notes: `percent' can be a number or a string in the form "NN%"
The "default" value of dst_percent is -1.0, which tells
blend_geometry to leave it out of the geometry string.
*/
VALUE
Image_dissolve(int argc, VALUE *argv, VALUE self)
{
Image *image, *overlay;
double src_percent, dst_percent = -1.0;
long x_offset = 0L, y_offset = 0L;
- volatile VALUE composite, ovly;
+ volatile VALUE composite_image, ovly;
image = rm_check_destroyed(self);
if (argc < 1)
{
@@ -3619,14 +3652,14 @@
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 to 6)", argc);
break;
}
- composite = special_composite(image, overlay, src_percent, dst_percent
- , x_offset, y_offset, DissolveCompositeOp);
+ composite_image = special_composite(image, overlay, src_percent, dst_percent
+ , x_offset, y_offset, DissolveCompositeOp);
- return composite;
+ return composite_image;
}
/*
* Method: Image#distort(type, points, bestfit=false)
@@ -4172,12 +4205,12 @@
Image *image;
long x_off = 0L, y_off = 0L;
unsigned long cols, rows;
long n, npixels;
unsigned int okay;
- char *map = "RGB";
- volatile Quantum *pixels;
+ const char *map = "RGB";
+ Quantum *pixels;
volatile VALUE ary;
ExceptionInfo exception;
image = rm_check_destroyed(self);
@@ -4221,11 +4254,11 @@
GetExceptionInfo(&exception);
okay = ExportImagePixels(image, x_off, y_off, cols, rows, map, QuantumPixel, (void *)pixels, &exception);
if (!okay)
{
- xfree((unsigned int *)pixels);
+ xfree((void *)pixels);
CHECK_EXCEPTION()
// Should never get here...
rm_magick_error("ExportImagePixels failed with no explanation.", NULL);
}
@@ -4236,11 +4269,11 @@
for (n = 0; n < npixels; n++)
{
(void) rb_ary_push(ary, QUANTUM2NUM(pixels[n]));
}
- xfree((unsigned int *)pixels);
+ xfree((void *)pixels);
return ary;
}
@@ -4322,11 +4355,11 @@
long x_off = 0L, y_off = 0L;
unsigned long cols, rows;
unsigned long npixels;
size_t sz;
unsigned int okay;
- char *map = "RGB";
+ const char *map = "RGB";
StorageType type = CharPixel;
volatile VALUE string;
char *str;
ExceptionInfo exception;
@@ -4825,11 +4858,11 @@
VALUE
Image_gamma_correct(int argc, VALUE *argv, VALUE self)
{
Image *image, *new_image;
double red_gamma, green_gamma, blue_gamma;
- char gamma[50];
+ char gamma_arg[50];
image = rm_check_destroyed(self);
switch (argc)
{
case 1:
@@ -4857,15 +4890,15 @@
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 3)", argc);
break;
}
- sprintf(gamma, "%f,%f,%f", red_gamma, green_gamma, blue_gamma);
+ sprintf(gamma_arg, "%f,%f,%f", red_gamma, green_gamma, blue_gamma);
new_image = rm_clone_image(image);
- (void) GammaImage(new_image, gamma);
+ (void) GammaImage(new_image, gamma_arg);
rm_check_image_exception(new_image, DestroyOnError);
return rm_image_new(new_image);
}
@@ -4974,11 +5007,11 @@
VALUE y_arg,
VALUE cols_arg,
VALUE rows_arg)
{
Image *image;
- PixelPacket *pixels;
+ const PixelPacket *pixels;
ExceptionInfo exception;
long x, y;
unsigned long columns, rows;
long size, n;
VALUE pixel_ary;
@@ -4996,11 +5029,11 @@
}
// Cast AcquireImagePixels to get rid of the const qualifier. We're not going
// to change the pixels but I don't want to make "pixels" const.
GetExceptionInfo(&exception);
- pixels = (PixelPacket *)AcquireImagePixels(image, x, y, columns, rows, &exception);
+ pixels = AcquireImagePixels(image, x, y, columns, rows, &exception);
CHECK_EXCEPTION()
(void) DestroyExceptionInfo(&exception);
// If the function failed, return a 0-length array.
@@ -5118,13 +5151,13 @@
long buffer_l;
char *map;
volatile VALUE pixel_arg, pixel_ary;
StorageType stg_type = CharPixel;
size_t type_sz, map_l;
- volatile Quantum *pixels = NULL;
- volatile double *fpixels = NULL;
- volatile void *buffer;
+ Quantum *pixels = NULL;
+ double *fpixels = NULL;
+ void *buffer;
unsigned int okay;
image = rm_check_frozen(self);
switch (argc)
@@ -5243,11 +5276,11 @@
stg_type = QuantumPixel;
}
}
- okay = ImportImagePixels(image, x_off, y_off, cols, rows, map, stg_type, (const void *)buffer);
+ okay = ImportImagePixels(image, x_off, y_off, cols, rows, map, stg_type, buffer);
// Free pixel array before checking for errors.
if (pixels)
{
xfree((void *)pixels);
@@ -5270,11 +5303,11 @@
/*
Method: Image#inspect
Purpose: Overrides Object#inspect - returns a string description of the
image.
Returns: the string
- Notes: this is essentially the DescribeImage except the description is
+ Notes: this is essentially the IdentifyImage except the description is
built in a char buffer instead of being written to a file.
*/
static void build_inspect_string(Image *image, char *buffer, size_t len)
{
unsigned long quantum_depth;
@@ -5361,23 +5394,23 @@
// Print bit depth
quantum_depth = GetImageQuantumDepth(image, MagickTrue);
x += sprintf(buffer+x, "%lu-bit", quantum_depth);
// Print blob info if appropriate.
- if (SizeBlob(image) != 0)
+ if (GetBlobSize(image) != 0)
{
- if (SizeBlob(image) >= (1 << 24))
+ if (GetBlobSize(image) >= (1 << 24))
{
- x += sprintf(buffer+x, " %lumb", (unsigned long) (SizeBlob(image)/1024/1024));
+ x += sprintf(buffer+x, " %lumb", (unsigned long) (GetBlobSize(image)/1024/1024));
}
- else if (SizeBlob(image) >= 1024)
+ else if (GetBlobSize(image) >= 1024)
{
- x += sprintf(buffer+x, " %lukb", (unsigned long) (SizeBlob(image)/1024));
+ x += sprintf(buffer+x, " %lukb", (unsigned long) (GetBlobSize(image)/1024));
}
else
{
- x += sprintf(buffer+x, " %lub", (unsigned long) SizeBlob(image));
+ x += sprintf(buffer+x, " %lub", (unsigned long) GetBlobSize(image));
}
}
assert(x < (int)(len-1));
buffer[x] = '\0';
@@ -5482,11 +5515,11 @@
*/
VALUE
Image_level2(int argc, VALUE *argv, VALUE self)
{
Image *image, *new_image;
- double black_point = 0.0, gamma = 1.0, white_point = (double)QuantumRange;
+ double black_point = 0.0, gamma_val = 1.0, white_point = (double)QuantumRange;
char level[50];
image = rm_check_destroyed(self);
switch (argc)
{
@@ -5501,20 +5534,20 @@
white_point = NUM2DBL(argv[1]);
break;
case 3:
black_point = NUM2DBL(argv[0]);
white_point = NUM2DBL(argv[1]);
- gamma = NUM2DBL(argv[2]);
+ gamma_val = NUM2DBL(argv[2]);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 3)", argc);
break;
}
new_image = rm_clone_image(image);
- sprintf(level, "%gx%g+%g", black_point, white_point, gamma);
+ sprintf(level, "%gx%g+%g", black_point, white_point, gamma_val);
(void) LevelImage(new_image, level);
rm_check_image_exception(new_image, DestroyOnError);
return rm_image_new(new_image);
}
@@ -5526,11 +5559,11 @@
*/
VALUE
Image_level_channel(int argc, VALUE *argv, VALUE self)
{
Image *image, *new_image;
- double black_point = 0.0, gamma = 1.0, white_point = (double)QuantumRange;
+ double black_point = 0.0, gamma_val = 1.0, white_point = (double)QuantumRange;
ChannelType channel;
image = rm_check_destroyed(self);
switch (argc)
{
@@ -5545,22 +5578,22 @@
white_point = NUM2DBL(argv[2]);
break;
case 4:
black_point = NUM2DBL(argv[1]);
white_point = NUM2DBL(argv[2]);
- gamma = NUM2DBL(argv[3]);
+ gamma_val = NUM2DBL(argv[3]);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 4)", argc);
break;
}
VALUE_TO_ENUM(argv[0], channel, ChannelType);
new_image = rm_clone_image(image);
- (void) LevelImageChannel(new_image, channel, black_point, white_point, gamma);
+ (void) LevelImageChannel(new_image, channel, black_point, white_point, gamma_val);
rm_check_image_exception(new_image, DestroyOnError);
return rm_image_new(new_image);
}
@@ -6007,38 +6040,38 @@
Color_to_PixelPacket(&image->matte_color, color);
return self;
}
/*
- Method: Image#matte_flood_fill(color, opacity, x, y, method)
+ Method: Image#matte_flood_fill(color, opacity, x, y, method_obj)
Purpose: Call MatteFloodFillImage
*/
VALUE
Image_matte_flood_fill(
VALUE self,
VALUE color,
VALUE opacity,
VALUE x_obj,
VALUE y_obj,
- VALUE method)
+ VALUE method_obj)
{
Image *image, *new_image;
PixelPacket target;
Quantum op;
long x, y;
- PaintMethod pm;
+ PaintMethod method;
image = rm_check_destroyed(self);
Color_to_PixelPacket(&target, color);
op = APP2QUANTUM(opacity);
- VALUE_TO_ENUM(method, pm, PaintMethod);
- if (!(pm == FloodfillMethod || pm == FillToBorderMethod))
+ VALUE_TO_ENUM(method_obj, method, PaintMethod);
+ if (!(method == FloodfillMethod || method == FillToBorderMethod))
{
- rb_raise(rb_eArgError, "paint method must be FloodfillMethod or "
- "FillToBorderMethod (%d given)", pm);
+ rb_raise(rb_eArgError, "paint method_obj must be FloodfillMethod or "
+ "FillToBorderMethod (%d given)", method);
}
x = NUM2LONG(x_obj);
y = NUM2LONG(y_obj);
if ((unsigned long)x > image->columns || (unsigned long)y > image->rows)
{
@@ -6047,11 +6080,44 @@
}
new_image = rm_clone_image(image);
- (void) MatteFloodfillImage(new_image, target, op, x, y, pm);
+#if defined(HAVE_FLOODFILLPAINTIMAGE)
+ {
+ DrawInfo *draw_info;
+ MagickPixelPacket target_mpp;
+ MagickBooleanType invert;
+
+ // FloodfillPaintImage looks for the opacity in the DrawInfo.fill field.
+ draw_info = CloneDrawInfo(NULL, NULL);
+ if (!draw_info)
+ {
+ rb_raise(rb_eNoMemError, "not enough memory to continue");
+ }
+ draw_info->fill.opacity = op;
+
+ if (method == FillToBorderMethod)
+ {
+ invert = MagickTrue;
+ target_mpp.red = (MagickRealType) image->border_color.red;
+ target_mpp.green = (MagickRealType) image->border_color.green;
+ target_mpp.blue = (MagickRealType) image->border_color.blue;
+ }
+ else
+ {
+ invert = MagickFalse;
+ target_mpp.red = (MagickRealType) target.red;
+ target_mpp.green = (MagickRealType) target.green;
+ target_mpp.blue = (MagickRealType) target.blue;
+ }
+
+ (void) FloodfillPaintImage(new_image, OpacityChannel, draw_info, &target_mpp, x, y, invert);
+ }
+#else
+ (void) MatteFloodfillImage(new_image, target, op, x, y, method);
+#endif
rm_check_image_exception(new_image, DestroyOnError);
return rm_image_new(new_image);
}
@@ -6427,13 +6493,13 @@
// NOW store a real image in the image object.
UPDATE_DATA_PTR(self, image);
SetImageExtent(image, cols, rows);
- // 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 the caller did not supply a fill argument, call SetImageBackgroundColor
+ // 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)
{
(void) SetImageBackgroundColor(image);
}
// fillobj.fill(self)
@@ -6851,11 +6917,11 @@
// Use fuzz value from caller
keep = new_image->fuzz;
new_image->fuzz = fuzz;
- okay = TransparentPaintImage(new_image, &color, opacity, invert);
+ okay = TransparentPaintImage(new_image, (const MagickPixelPacket *)&color, opacity, invert);
new_image->fuzz = keep;
// Is it possible for TransparentPaintImage to silently fail?
rm_check_image_exception(new_image, DestroyOnError);
if (!okay)
@@ -7757,11 +7823,11 @@
*/
static VALUE
resize(int bang, int argc, VALUE *argv, VALUE self)
{
Image *image, *new_image;
- double scale;
+ double scale_arg;
FilterTypes filter;
unsigned long rows, columns;
double blur, drows, dcols;
ExceptionInfo exception;
@@ -7786,17 +7852,17 @@
{
rb_raise(rb_eArgError, "invalid result dimension (%lu, %lu given)", columns, rows);
}
break;
case 1:
- scale = NUM2DBL(argv[0]);
- if (scale < 0.0)
+ scale_arg = NUM2DBL(argv[0]);
+ if (scale_arg < 0.0)
{
- rb_raise(rb_eArgError, "invalid scale value (%g given)", scale);
+ rb_raise(rb_eArgError, "invalid scale_arg value (%g given)", scale_arg);
}
- drows = scale * image->rows + 0.5;
- dcols = scale * image->columns + 0.5;
+ drows = scale_arg * image->rows + 0.5;
+ dcols = scale_arg * image->columns + 0.5;
if (drows > (double)ULONG_MAX || dcols > (double)ULONG_MAX)
{
rb_raise(rb_eRangeError, "resized image too big");
}
rows = (unsigned long) drows;
@@ -7991,11 +8057,11 @@
static VALUE
scale(int bang, int argc, VALUE *argv, VALUE self, scaler_t scaler)
{
Image *image, *new_image;
unsigned long columns, rows;
- double scale, drows, dcols;
+ double scale_arg, drows, dcols;
ExceptionInfo exception;
Data_Get_Struct(self, Image, image);
switch (argc)
@@ -8007,17 +8073,17 @@
{
rb_raise(rb_eArgError, "invalid result dimension (%lu, %lu given)", columns, rows);
}
break;
case 1:
- scale = NUM2DBL(argv[0]);
- if (scale <= 0)
+ scale_arg = NUM2DBL(argv[0]);
+ if (scale_arg <= 0)
{
- rb_raise(rb_eArgError, "invalid scale value (%g given)", scale);
+ rb_raise(rb_eArgError, "invalid scale value (%g given)", scale_arg);
}
- drows = scale * image->rows + 0.5;
- dcols = scale * image->columns + 0.5;
+ drows = scale_arg * image->rows + 0.5;
+ dcols = scale_arg * image->columns + 0.5;
if (drows > (double)ULONG_MAX || dcols > (double)ULONG_MAX)
{
rb_raise(rb_eRangeError, "resized image too big");
}
rows = (unsigned long) drows;
@@ -8721,18 +8787,18 @@
*/
VALUE
Image_spread(int argc, VALUE *argv, VALUE self)
{
Image *image, *new_image;
- unsigned int radius = 3;
+ double radius = 3.0;
ExceptionInfo exception;
image = rm_check_destroyed(self);
switch (argc)
{
case 1:
- radius = NUM2UINT(argv[0]);
+ radius = NUM2DBL(argv[0]);
case 0:
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
break;
@@ -9057,20 +9123,38 @@
}
draw_info->fill_pattern = rm_clone_image(texture_image);
new_image = rm_clone_image(image);
- // Hack: By-pass bug in ColorFloodfillImage that tests
- // the fill color even though the fill color isn't used.
+
+#if defined(HAVE_FLOODFILLPAINTIMAGE)
+ {
+ MagickPixelPacket color_mpp;
+ MagickBooleanType invert;
+
+ GetMagickPixelPacket(new_image, &color_mpp);
if (method == FillToBorderMethod)
{
- draw_info->fill.red = ROUND_TO_QUANTUM(color.red + new_image->fuzz + 1);
- draw_info->fill.green = color.green;
- draw_info->fill.blue = color.blue;
+ invert = MagickTrue;
+ color_mpp.red = (MagickRealType) image->border_color.red;
+ color_mpp.green = (MagickRealType) image->border_color.green;
+ color_mpp.blue = (MagickRealType) image->border_color.blue;
}
+ else
+ {
+ invert = MagickFalse;
+ color_mpp.red = (MagickRealType) color.red;
+ color_mpp.green = (MagickRealType) color.green;
+ color_mpp.blue = (MagickRealType) color.blue;
+ }
+ (void) FloodfillPaintImage(new_image, DefaultChannels, draw_info, &color_mpp, x, y, invert);
+ }
+
+#else
(void) ColorFloodfillImage(new_image, draw_info, color, x, y, method);
+#endif
(void) DestroyDrawInfo(draw_info);
rm_check_image_exception(new_image, DestroyOnError);
@@ -9162,11 +9246,11 @@
static VALUE
thumbnail(int bang, int argc, VALUE *argv, VALUE self)
{
Image *image, *new_image;
unsigned long columns, rows;
- double scale, drows, dcols;
+ double scale_arg, drows, dcols;
ExceptionInfo exception;
Data_Get_Struct(self, Image, image);
switch (argc)
@@ -9178,17 +9262,17 @@
{
rb_raise(rb_eArgError, "invalid result dimension (%lu, %lu given)", columns, rows);
}
break;
case 1:
- scale = NUM2DBL(argv[0]);
- if (scale < 0.0)
+ scale_arg = NUM2DBL(argv[0]);
+ if (scale_arg < 0.0)
{
- rb_raise(rb_eArgError, "invalid scale value (%g given)", scale);
+ rb_raise(rb_eArgError, "invalid scale value (%g given)", scale_arg);
}
- drows = scale * image->rows + 0.5;
- dcols = scale * image->columns + 0.5;
+ drows = scale_arg * image->rows + 0.5;
+ dcols = scale_arg * image->columns + 0.5;
if (drows > (double)ULONG_MAX || dcols > (double)ULONG_MAX)
{
rb_raise(rb_eRangeError, "resized image too big");
}
rows = (unsigned long) drows;
@@ -9448,11 +9532,11 @@
}
/*
Method: Image#transparent(color-name<, opacity>)
Image#transparent(pixel<, opacity>)
- Purpose: Call TransparentImage
+ Purpose: Call TransparentPaintImage
Notes: Can use Magick::OpaqueOpacity or Magick::TransparentOpacity,
or any value >= 0 && <= QuantumRange. The default is
Magick::TransparentOpacity.
Use Image#fuzz= to define the tolerance level.
*/
@@ -9571,11 +9655,10 @@
static VALUE
trimmer(int bang, int argc, VALUE *argv, VALUE self)
{
Image *image, *new_image;
- RectangleInfo geometry;
ExceptionInfo exception;
int reset_page = 0;
switch (argc)
{
@@ -9589,15 +9672,11 @@
}
Data_Get_Struct(self, Image, image);
GetExceptionInfo(&exception);
-
- geometry = GetImageBoundingBox(image, &exception);
- CHECK_EXCEPTION()
-
- new_image = CropImage(image, &geometry, &exception);
+ new_image = TrimImage(image, &exception);
rm_check_exception(&exception, new_image, DestroyOnError);
(void) DestroyExceptionInfo(&exception);
rm_ensure_result(new_image);
@@ -9656,12 +9735,12 @@
return gravity;
}
/*
- Method: Image#image_type
- Purpose: Call GetImageType to get the image type
+ Method: Image#image_type, image_type=
+ Purpose: Call GetImageType/SetImageType to get/set the image type
*/
VALUE Image_image_type(VALUE self)
{
Image *image;
ImageType type;
@@ -9676,10 +9755,22 @@
return ImageType_new(type);
}
+VALUE Image_image_type_eq(VALUE self, VALUE image_type)
+{
+ Image *image;
+ ImageType type;
+
+ image = rm_check_frozen(self);
+ VALUE_TO_ENUM(image_type, type, ImageType);
+ SetImageType(image, type);
+ return image_type;
+}
+
+
/*
Method: Image#unique_colors
Purpose: Call UniqueImageColors
*/
VALUE
@@ -10070,17 +10161,18 @@
*/
VALUE
Image_wet_floor(int argc, VALUE *argv, VALUE self)
{
Image *image, *reflection, *flip_image;
- PixelPacket *p, *q;
+ const PixelPacket *p;
+ PixelPacket *q;
RectangleInfo geometry;
long x, y, max_rows;
double initial = 0.5;
double rate = 1.0;
double opacity, step;
- char *func;
+ const char *func;
MagickBooleanType okay;
ExceptionInfo exception;
image = rm_check_destroyed(self);
switch (argc)
@@ -10149,11 +10241,11 @@
if (opacity > TransparentOpacity)
{
opacity = TransparentOpacity;
}
- p = (PixelPacket *)AcquireImagePixels(reflection, 0, y, image->columns, 1, &exception);
+ p = AcquireImagePixels(reflection, 0, y, image->columns, 1, &exception);
rm_check_exception(&exception, reflection, RetainOnError);
q = SetImagePixels(reflection, 0, y, image->columns, 1);
rm_check_image_exception(reflection, DestroyOnError);
if (!q)
@@ -10294,11 +10386,11 @@
volatile VALUE x, y, width, height;
unsigned long nx = 0, ny = 0;
unsigned long columns, rows;
int reset_page = 0;
GravityType gravity;
- MagickEnum *magick_enum;
+ MagickEnum *m_enum;
Image *image;
VALUE cropped;
// Check for a "reset page" trailing argument.
if (argc >= 1)
@@ -10365,12 +10457,12 @@
case NorthEastGravity:
case NorthGravity:
// Don't let these run into the default case
break;
default:
- Data_Get_Struct(argv[0], MagickEnum, magick_enum);
- rb_warning("gravity type `%s' has no effect", rb_id2name(magick_enum->id));
+ Data_Get_Struct(argv[0], MagickEnum, m_enum);
+ rb_warning("gravity type `%s' has no effect", rb_id2name(m_enum->id));
break;
}
x = ULONG2NUM(nx);
y = ULONG2NUM(ny);
@@ -10573,13 +10665,13 @@
/*
Static: call_trace_proc
Purpose: If Magick.trace_proc is not nil, build an argument
list and call the proc.
*/
-static void call_trace_proc(Image *image, char *which)
+static void call_trace_proc(Image *image, const char *which)
{
volatile VALUE trace;
- volatile VALUE trace_args[4];
+ VALUE trace_args[4];
if (rb_ivar_defined(Module_Magick, rm_ID_trace_proc) == Qtrue)
{
trace = rb_ivar_get(Module_Magick, rm_ID_trace_proc);
if (!NIL_P(trace))