ext/RMagick/rmutil.c in rmagick-1.15.17 vs ext/RMagick/rmutil.c in rmagick-2.0.0

- old
+ new

@@ -1,8 +1,8 @@ -/* $Id: rmutil.c,v 1.90.2.3.2.7 2008/09/10 23:22:46 rmagick Exp $ */ +/* $Id: rmutil.c,v 1.138 2007/12/26 21:43:52 rmagick Exp $ */ /*============================================================================\ -| Copyright (C) 2008 by Timothy P. Hunter +| Copyright (C) 2007 by Timothy P. Hunter | Name: rmutil.c | Author: Tim Hunter | Purpose: Utility functions for RMagick \============================================================================*/ @@ -14,62 +14,50 @@ static const char *StretchType_name(StretchType); static void Color_Name_to_PixelPacket(PixelPacket *, VALUE); static VALUE Enum_type_values(VALUE); static VALUE Enum_type_inspect(VALUE); static void handle_exception(ExceptionInfo *, Image *, ErrorRetention); -#if defined(HAVE_NEW_COLORINFO) static VALUE Pixel_from_MagickPixelPacket(MagickPixelPacket *); -#endif -#if !defined(HAVE_ACQUIREMAGICKMEMORY) + /* - Dummy versions of ImageMagick memory routines for use with GraphicsMagick. + Extern: magick_safe_malloc, magick_malloc, magick_free, magick_realloc + Purpose: ImageMagick versions of standard memory routines. + Notes: use when managing memory that ImageMagick may have + allocated or may free. + + If malloc fails, it raises an exception. + + magick_safe_malloc and magick_safe_realloc prevent exceptions + caused by integer overflow. Added in 6.3.5-9 but backwards + compatible with prior releases. */ -static void *AcquireMagickMemory(const size_t size) +void *magick_safe_malloc(const size_t count, const size_t quantum) { - assert(size > 0); - return malloc(size); -} +#if defined(HAVE_ACQUIREQUANTUMMEMORY) + void *ptr; -static void *RelinquishMagickMemory(void *memory) -{ - if (memory) + ptr = AcquireQuantumMemory(count, quantum); + if (!ptr) { - free(memory); + rb_raise(rb_eNoMemError, "not enough memory to continue"); } - return NULL; -} + return ptr; +#else -static void *ResizeMagickMemory(void *memory, const size_t size) -{ - void *new; + // Provide an implementation of AcquireQuantumMemory in releases prior to 6.3.5-9. + size_t size = count * quantum; - if (!memory) + if (count == 0 || quantum != (size/count)) { - return malloc(size); + rb_raise(rb_eRuntimeError, "integer overflow detected in memory size computation. " + "Probable image corruption."); } - if (size == 0) - { - free(memory); - return NULL; - } - new = realloc(memory, size); - if (!new) - { - free(memory); - } - return new; -} + return magick_malloc(size); #endif +} -/* - Extern: magick_malloc, magick_free, magick_realloc - Purpose: ****Magick versions of standard memory routines. - Notes: use when managing memory that ****Magick may have - allocated or may free. - If malloc fails, it raises an exception -*/ void *magick_malloc(const size_t size) { void *ptr; ptr = AcquireMagickMemory(size); if (!ptr) @@ -83,10 +71,32 @@ void magick_free(void *ptr) { (void) RelinquishMagickMemory(ptr); } +void *magick_safe_realloc(void *memory, const size_t count, const size_t quantum) +{ +#if defined(HAVE_RESIZEQUANTUMMEMORY) + void *v; + v = ResizeQuantumMemory(memory, count, quantum); + if (!v) + { + rb_raise(rb_eNoMemError, "not enough memory to continue"); + } + return v; +#else + // Provide an implementation of ResizeQuantumMemory in releases prior to 6.3.5-9. + size_t size = count * quantum; + if (count == 0 || quantum != (size/count)) + { + rb_raise(rb_eRuntimeError, "integer overflow detected in memory size computation. " + "Probable image corruption."); + } + return magick_realloc(memory, size); +#endif +} + void *magick_realloc(void *ptr, const size_t size) { void *v; v = ResizeMagickMemory(ptr, size); if (!v) @@ -108,62 +118,11 @@ { (void) CloneString(new_str, str); } - /* - Extern: rm_string_value_ptr(VALUE*) - Purpose: emulate Ruby 1.8's rb_string_value_ptr - Notes: This is essentially 1.8's rb_string_value_ptr - with a few minor changes to make it work in 1.6. - Always called via STRING_PTR -*/ -#if !defined StringValuePtr -char * -rm_string_value_ptr(volatile VALUE *ptr) -{ - volatile VALUE s = *ptr; - - // If VALUE is not a string, call to_str on it - if (TYPE(s) != T_STRING) - { - s = rb_str_to_str(s); - *ptr = s; - } - // If ptr == NULL, allocate a 1 char array - if (!RSTRING(s)->ptr) - { - RSTRING(s)->ptr = ALLOC_N(char, 1); - (RSTRING(s)->ptr)[0] = 0; - RSTRING(s)->orig = 0; - } - return RSTRING(s)->ptr; -} -#endif - -/* - Extern: rm_string_value_ptr_len - Purpose: safe replacement for rb_str2cstr - Returns: stores string length in 2nd arg, returns ptr to C string - Notes: Uses rb/rm_string_value_ptr to ensure correct String - argument. - Always called via STRING_PTR_LEN -*/ -char *rm_string_value_ptr_len(volatile VALUE *ptr, long *len) -{ - volatile VALUE v = *ptr; - char *str; - - str = STRING_PTR(v); - *ptr = v; - *len = RSTRING(v)->len; - return str; -} - - -/* * Extern: rm_strcasecmp(s1, s2) * Purpose: compare s1 and s2 ignoring case * Returns: same as strcmp(3) */ int @@ -180,10 +139,12 @@ } return (int)(*s1 - *s2); } + + /* * Extern: rm_strncasecmp(s1, s2, n) * Purpose: compare s1 and s2 ignoring case * Returns: same as strcmp(3) */ @@ -206,41 +167,58 @@ return (int)(*s1 - *s2); } - - /* * Extern: rm_check_ary_len(ary, len) * Purpose: raise exception if array too short */ void rm_check_ary_len(VALUE ary, long len) { if (RARRAY(ary)->len < len) { rb_raise(rb_eIndexError, "not enough elements in array - expecting %ld, got %ld", - len, RARRAY(ary)->len); + len, (long)RARRAY(ary)->len); } } + /* - Extern: rm_check_frozen - Purpose: backport rb_check_frozen for 1.6.x releases + Extern: rm_check_destroyed + Purpose: raise an error if the image has been destroyed */ -void -rm_check_frozen(VALUE obj) +Image * +rm_check_destroyed(VALUE obj) { - if (OBJ_FROZEN(obj)) + Image *image; + + Data_Get_Struct(obj, Image, image); + if (!image) { - rb_error_frozen(rb_class2name(CLASS_OF(obj))); + rb_raise(Class_DestroyedImageError, "destroyed image"); } + + return image; } /* + Extern: rm_check_frozen_image + Purpose: raise an error if the image has been destroyed or is frozen +*/ +Image * +rm_check_frozen_image(VALUE obj) +{ + Image *image = rm_check_destroyed(obj); + rb_check_frozen(obj); + return image; +} + + +/* Extern: rm_no_freeze(obj) Purpose: overrides freeze in classes that can't be frozen. */ VALUE rm_no_freeze(VALUE obj) @@ -294,11 +272,11 @@ (void) rb_protect(arg_is_number, arg, &not_num); if (not_num) { arg = rb_rescue(rb_str_to_str, arg, rescue_not_str, arg); - pct_str = STRING_PTR(arg); + pct_str = StringValuePtr(arg); errno = 0; pct_long = strtol(pct_str, &end, 10); if (errno == ERANGE) { rb_raise(rb_eRangeError, "`%s' out of range", pct_str); @@ -351,11 +329,11 @@ Purpose: called if rb_num2dbl raises an exception */ static VALUE rescue_not_dbl(VALUE ignored) { - ignored = ignored; // defeat gcc message + ignored = ignored; // defeat gcc message return INT2FIX(0); } /* @@ -377,11 +355,11 @@ { long pct; char *pct_str, *end; str = rb_rescue(rb_str_to_str, str, rescue_not_str, str); - pct_str = STRING_PTR(str); + pct_str = StringValuePtr(str); errno = 0; pct = strtol(pct_str, &end, 10); if (errno == ERANGE) { @@ -402,11 +380,11 @@ /* * Extern: rm_fuzz_to_dbl(obj) * Purpose: If the argument is a number, convert it to a double. * Otherwise it's supposed to be a string in the form 'NN%'. - * Return a percentage of MaxRGB. + * Return a percentage of QuantumRange. * Notes: Called from Image#fuzz= and Info#fuzz= */ double rm_fuzz_to_dbl(VALUE fuzz_arg) { @@ -419,11 +397,11 @@ if (not_num) { // Convert to string, issue error message if failure. fuzz_arg = rb_rescue(rb_str_to_str, fuzz_arg, rescue_not_str, fuzz_arg); - fuzz_str = STRING_PTR(fuzz_arg); + fuzz_str = StringValuePtr(fuzz_arg); errno = 0; fuzz = strtod(fuzz_str, &end); if (errno == ERANGE) { rb_raise(rb_eRangeError, "`%s' out of range", fuzz_str); @@ -432,11 +410,11 @@ { if (fuzz < 0.0) { rb_raise(rb_eArgError, "percentages may not be negative (got `%s')", fuzz_str); } - fuzz = (fuzz * MaxRGB) / 100.0; + fuzz = (fuzz * QuantumRange) / 100.0; } else if(*end != '\0') { rb_raise(rb_eArgError, "expected percentage, got `%s'", fuzz_str); } @@ -453,10 +431,33 @@ return fuzz; } /* + Extern: rm_app2quantum + Purpose: Convert a application-supplied number to a Quantum. If the object + is a Float, truncate it before converting. + Notes: Ruby says that 2147483647.5 doesn't fit into an unsigned long. + If you truncate it, it works. + Should use this only when the input value is possibly subject + to this problem. +*/ +Quantum +rm_app2quantum(VALUE obj) +{ + volatile VALUE v = obj; + + if (TYPE(obj) == T_FLOAT) + { + v = rb_funcall(obj, rm_ID_to_i, 0); + } + + return NUM2QUANTUM(v); +} + + +/* Extern: ImageList_cur_image Purpose: Sends the "cur_image" method to the object. If 'img' is an ImageList, then cur_image is self[@scene]. If 'img' is an image, then cur_image is simply 'self'. @@ -514,12 +515,12 @@ { Pixel *pixel; char buff[100]; Data_Get_Struct(self, Pixel, pixel); - sprintf(buff, "red=%d, green=%d, blue=%d, opacity=%d" - , (int)pixel->red, (int)pixel->green, (int)pixel->blue, (int)pixel->opacity); + sprintf(buff, "red=" QuantumFormat ", green=" QuantumFormat ", blue=" QuantumFormat ", opacity=" QuantumFormat + , pixel->red, pixel->green, pixel->blue, pixel->opacity); return rb_str_new2(buff); } /* Method: Magick::Pixel.from_color(string) @@ -538,17 +539,17 @@ MagickBooleanType okay; class = class; // defeat "never referenced" message from icc GetExceptionInfo(&exception); - okay = QueryColorDatabase(STRING_PTR(name), &pp, &exception); + okay = QueryColorDatabase(StringValuePtr(name), &pp, &exception); CHECK_EXCEPTION() (void) DestroyExceptionInfo(&exception); if (!okay) { - rb_raise(rb_eArgError, "invalid color name: %s", STRING_PTR(name)); + rb_raise(rb_eArgError, "invalid color name: %s", StringValuePtr(name)); } return Pixel_from_PixelPacket(&pp); } @@ -630,11 +631,10 @@ Pixel *pixel; double hue, saturation, luminosity; volatile VALUE hsl; Data_Get_Struct(self, Pixel, pixel); - #if defined(HAVE_CONVERTRGBTOHSL) ConvertRGBToHSL(pixel->red, pixel->green, pixel->blue, &hue, &saturation, &luminosity); #else TransformHSL(pixel->red, pixel->green, pixel->blue, &hue, &saturation, &luminosity); #endif @@ -651,14 +651,15 @@ [hue, saturation, luminosity]. */ VALUE Pixel_from_HSL(VALUE class, VALUE hsl) { - PixelPacket rgb = {0}; + PixelPacket rgb; double hue, saturation, luminosity; class = class; // defeat "never referenced" message from icc + memset(&rgb, 0, sizeof(rgb)); hsl = rb_Array(hsl); // Ensure array if (RARRAY(hsl)->len < 3) { rb_raise(rb_eArgError, "array argument must have at least 3 elements"); @@ -673,11 +674,10 @@ &rgb.red, &rgb.green, &rgb.blue); #else HSLTransform(hue, saturation, luminosity, &rgb.red, &rgb.green, &rgb.blue); #endif - return Pixel_from_PixelPacket(&rgb); } /* Method: Pixel#eql? @@ -694,14 +694,12 @@ Purpose: Compare pixel values for equality */ VALUE Pixel_fcmp(int argc, VALUE *argv, VALUE self) { -#if defined(HAVE_FUZZYCOLORCOMPARE) Image *image; Info *info; -#endif Pixel *this, *that; ColorspaceType colorspace = RGBColorspace; double fuzz = 0.0; unsigned int equal; @@ -721,41 +719,35 @@ } Data_Get_Struct(self, Pixel, this); Data_Get_Struct(argv[0], Pixel, that); -#if defined(HAVE_FUZZYCOLORCOMPARE) || defined(HAVE_ISCOLORSIMILAR) - // The FuzzyColorCompare function expects to get the + // The IsColorSimilar function expects to get the // colorspace and fuzz parameters from an Image structure. info = CloneImageInfo(NULL); if (!info) { rb_raise(rb_eNoMemError, "not enough memory to continue"); } image = AllocateImage(info); + + // Delete Info now in case we have to raise an exception + (void) DestroyImageInfo(info); + if (!image) { rb_raise(rb_eNoMemError, "not enough memory to continue"); } - (void) DestroyImageInfo(info); image->colorspace = colorspace; image->fuzz = fuzz; -#if defined(HAVE_ISCOLORSIMILAR) equal = IsColorSimilar(image, this, that); -#else - equal = FuzzyColorCompare(image, this, that); -#endif (void) DestroyImage(image); -#else - equal = FuzzyColorMatch(this, that, fuzz); -#endif - return equal ? Qtrue : Qfalse; } /* @@ -795,11 +787,11 @@ intensity = ROUND_TO_QUANTUM((0.299*pixel->red) + (0.587*pixel->green) + (0.114*pixel->blue)); - return ULONG2NUM((unsigned long) intensity); + return QUANTUM2NUM((unsigned long) intensity); } /* Methods: Pixel RGBA attribute accessors @@ -877,11 +869,10 @@ { xfree(pixel); } -#if defined(HAVE_RB_DEFINE_ALLOC_FUNC) /* Extern: Pixel_alloc Purpose: Allocate a Pixel object */ VALUE @@ -892,33 +883,12 @@ pixel = ALLOC(Pixel); memset(pixel, '\0', sizeof(Pixel)); return Data_Wrap_Struct(class, NULL, destroy_Pixel, pixel); } -#else /* - Method: Pixel.new - Purpose: Construct a new Pixel object -*/ -VALUE -Pixel_new(int argc, VALUE *argv, VALUE class) -{ - Pixel *pixel; - volatile VALUE pixel_obj; - - pixel = ALLOC(Pixel); - memset(pixel, '\0', sizeof(Pixel)); - pixel_obj = Data_Wrap_Struct(class, NULL, destroy_Pixel, pixel); - - rb_obj_call_init(pixel_obj, argc, argv); - return pixel_obj; -} -#endif - - -/* Method: Pixel#initialize(red=0,green=0,blue=0,opacity=0) Notes: For backward compatibility, arguments may be nil. */ VALUE Pixel_initialize(int argc, VALUE *argv, VALUE self) @@ -930,26 +900,26 @@ switch(argc) { case 4: if (argv[3] != Qnil) { - pixel->opacity = (Quantum) NUM2UINT(argv[3]); + pixel->opacity = APP2QUANTUM(argv[3]); } case 3: if (argv[2] != Qnil) { - pixel->blue = (Quantum) NUM2UINT(argv[2]); + pixel->blue = APP2QUANTUM(argv[2]); } case 2: if (argv[1] != Qnil) { - pixel->green = (Quantum) NUM2UINT(argv[1]); + pixel->green = APP2QUANTUM(argv[1]); } case 1: if (argv[0] != Qnil) { - pixel->red = (Quantum) NUM2UINT(argv[0]); + pixel->red = APP2QUANTUM(argv[0]); } case 0: break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 4)", argc); @@ -1009,11 +979,11 @@ volatile VALUE clone; clone = Pixel_dup(self); if (OBJ_FROZEN(self)) { - (void) rb_obj_freeze(clone); + OBJ_FREEZE(clone); } return clone; } @@ -1134,11 +1104,11 @@ MagickBooleanType okay; char *name; ExceptionInfo exception; GetExceptionInfo(&exception); - name = STRING_PTR(name_arg); + name = StringValuePtr(name_arg); okay = QueryColorDatabase(name, color, &exception); (void) DestroyExceptionInfo(&exception); if (!okay) { rb_raise(rb_eArgError, "invalid color name %s", name); @@ -1211,23 +1181,10 @@ VALUE ColorspaceType_new(ColorspaceType cs) { const char *name; -#if defined(HAVE_REC601YCBCRCOLORSPACE) - // GM 1.2 defines this symbol to be equal to YCbCrColorspace, so we - // can't use it as a case label. GM wants the string version of this - // enumerator to be Rec601YCbCrColorspace (see ColorspaceTypeToString - // in colorspace.c) so that's what we return for both versions of the - // enumerator. - if (cs == Rec601YCbCrColorspace) - { - return rm_enum_new(Class_ColorspaceType - , ID2SYM(rb_intern("Rec601YCbCrColorspace")), INT2FIX(cs)); - } -#endif - switch(cs) { default: case UndefinedColorspace: name = "UndefinedColorspace"; @@ -1272,45 +1229,31 @@ name = "HSLColorspace"; break; case HWBColorspace: name = "HWBColorspace"; break; -#if defined(HAVE_HSBCOLORSPACE) case HSBColorspace: name = "HSBColorspace"; break; -#endif -#if defined(HAVE_LABCOLORSPACE) case LABColorspace: name = "LABColorspace"; break; -#endif -#if defined(HAVE_CINEONLOGRGBCOLORSPACE) - case CineonLogRGBColorspace: - name = "CineonLogRGBColorspace"; + case Rec601YCbCrColorspace: + name = "Rec601YCbCrColorspace"; break; -#endif -#if defined(HAVE_REC601LUMACOLORSPACE) case Rec601LumaColorspace: name = "Rec601LumaColorspace"; break; -#endif -#if defined(HAVE_REC709LUMACOLORSPACE) case Rec709LumaColorspace: name = "Rec709LumaColorspace"; break; -#endif -#if defined(HAVE_REC709YCBCRCOLORSPACE) case Rec709YCbCrColorspace: name = "Rec709YCbCrColorspace"; break; -#endif -#if defined(HAVE_LOGCOLORSPACE) case LogColorspace: name = "LogColorspace"; break; -#endif } return rm_enum_new(Class_ColorspaceType, ID2SYM(rb_intern(name)), INT2FIX(cs)); } @@ -1338,25 +1281,25 @@ static const char * CompositeOperator_name(CompositeOperator op) { switch (op) { - default: ENUM_TO_NAME(UndefinedCompositeOp) ENUM_TO_NAME(NoCompositeOp) ENUM_TO_NAME(AddCompositeOp) ENUM_TO_NAME(AtopCompositeOp) ENUM_TO_NAME(BumpmapCompositeOp) +#if defined(HAVE_ENUM_CHANGEMASKCOMPOSITEOP) + ENUM_TO_NAME(ChangeMaskCompositeOp) +#endif ENUM_TO_NAME(ClearCompositeOp) -#if defined(HAVE_COLORDODGECOMPOSITEOP) ENUM_TO_NAME(ColorBurnCompositeOp) ENUM_TO_NAME(BlendCompositeOp) ENUM_TO_NAME(ColorDodgeCompositeOp) ENUM_TO_NAME(ExclusionCompositeOp) ENUM_TO_NAME(HardLightCompositeOp) ENUM_TO_NAME(SoftLightCompositeOp) -#endif ENUM_TO_NAME(ColorizeCompositeOp) ENUM_TO_NAME(CopyBlueCompositeOp) ENUM_TO_NAME(CopyCompositeOp) ENUM_TO_NAME(CopyCyanCompositeOp) ENUM_TO_NAME(CopyMagentaCompositeOp) @@ -1364,59 +1307,59 @@ ENUM_TO_NAME(CopyBlackCompositeOp) ENUM_TO_NAME(CopyGreenCompositeOp) ENUM_TO_NAME(CopyOpacityCompositeOp) ENUM_TO_NAME(CopyRedCompositeOp) ENUM_TO_NAME(DarkenCompositeOp) -#if defined(HAVE_DSTCOMPOSITEOP) +#if defined(HAVE_ENUM_DIVIDECOMPOSITEOP) + ENUM_TO_NAME(DivideCompositeOp) +#endif ENUM_TO_NAME(DstAtopCompositeOp) ENUM_TO_NAME(DstCompositeOp) ENUM_TO_NAME(DstInCompositeOp) ENUM_TO_NAME(DstOutCompositeOp) ENUM_TO_NAME(DstOverCompositeOp) -#endif ENUM_TO_NAME(DifferenceCompositeOp) ENUM_TO_NAME(DisplaceCompositeOp) ENUM_TO_NAME(DissolveCompositeOp) ENUM_TO_NAME(HueCompositeOp) ENUM_TO_NAME(InCompositeOp) ENUM_TO_NAME(LightenCompositeOp) +#if defined(HAVE_ENUM_LINEARLIGHTCOMPOSITEOP) + ENUM_TO_NAME(LinearLightCompositeOp) +#endif ENUM_TO_NAME(LuminizeCompositeOp) ENUM_TO_NAME(MinusCompositeOp) ENUM_TO_NAME(ModulateCompositeOp) ENUM_TO_NAME(MultiplyCompositeOp) ENUM_TO_NAME(OutCompositeOp) ENUM_TO_NAME(OverCompositeOp) ENUM_TO_NAME(OverlayCompositeOp) ENUM_TO_NAME(PlusCompositeOp) -#if defined(HAVE_REPLACECOMPOSITEOP) // Added 5.5.8 ENUM_TO_NAME(ReplaceCompositeOp) -#endif ENUM_TO_NAME(SaturateCompositeOp) ENUM_TO_NAME(ScreenCompositeOp) -#if defined(HAVE_DSTCOMPOSITEOP) ENUM_TO_NAME(SrcAtopCompositeOp) ENUM_TO_NAME(SrcCompositeOp) ENUM_TO_NAME(SrcInCompositeOp) ENUM_TO_NAME(SrcOutCompositeOp) ENUM_TO_NAME(SrcOverCompositeOp) -#endif ENUM_TO_NAME(SubtractCompositeOp) ENUM_TO_NAME(ThresholdCompositeOp) ENUM_TO_NAME(XorCompositeOp) } + + return "UndefinedCompositeOp"; } /* External: CompositeOperator_new Purpose: Construct a CompositeOperator enum object for the specified value */ VALUE CompositeOperator_new(CompositeOperator op) { - const char *name; - - name = CompositeOperator_name(op); + const char *name = CompositeOperator_name(op); return rm_enum_new(Class_CompositeOperator, ID2SYM(rb_intern(name)), INT2FIX(op)); } /* @@ -1426,35 +1369,35 @@ static const char * CompressionType_name(CompressionType ct) { switch (ct) { - default: ENUM_TO_NAME(UndefinedCompression) ENUM_TO_NAME(NoCompression) ENUM_TO_NAME(BZipCompression) ENUM_TO_NAME(FaxCompression) ENUM_TO_NAME(Group4Compression) ENUM_TO_NAME(JPEGCompression) + ENUM_TO_NAME(JPEG2000Compression) ENUM_TO_NAME(LosslessJPEGCompression) ENUM_TO_NAME(LZWCompression) ENUM_TO_NAME(RLECompression) ENUM_TO_NAME(ZipCompression) } + + return "UndefinedCompression"; } /* * External: CompressionType_new Purpose: Construct a CompressionType enum object for the specified value */ VALUE CompressionType_new(CompressionType ct) { - const char *name; - - name = CompressionType_name(ct); + const char *name = CompressionType_name(ct); return rm_enum_new(Class_CompressionType, ID2SYM(rb_intern(name)), INT2FIX(ct)); } /* @@ -1464,29 +1407,28 @@ static const char * DisposeType_name(DisposeType type) { switch(type) { - default: ENUM_TO_NAME(UndefinedDispose) ENUM_TO_NAME(BackgroundDispose) ENUM_TO_NAME(NoneDispose) ENUM_TO_NAME(PreviousDispose) } + + return "UndefinedDispose"; } /* External: DisposeType.new Purpose: Construct a DisposeType enum object for the specified value..new */ VALUE DisposeType_new(DisposeType type) { - const char *name; - - name = DisposeType_name(type); + const char *name = DisposeType_name(type); return rm_enum_new(Class_DisposeType, ID2SYM(rb_intern(name)), INT2FIX(type)); } /* @@ -1496,11 +1438,10 @@ static const char * FilterTypes_name(FilterTypes type) { switch(type) { - default: ENUM_TO_NAME(UndefinedFilter) ENUM_TO_NAME(PointFilter) ENUM_TO_NAME(BoxFilter) ENUM_TO_NAME(TriangleFilter) ENUM_TO_NAME(HermiteFilter) @@ -1513,24 +1454,45 @@ ENUM_TO_NAME(CatromFilter) ENUM_TO_NAME(MitchellFilter) ENUM_TO_NAME(LanczosFilter) ENUM_TO_NAME(BesselFilter) ENUM_TO_NAME(SincFilter) +#if defined(HAVE_ENUM_KAISERFILTER) + ENUM_TO_NAME(KaiserFilter) +#endif +#if defined(HAVE_ENUM_WELSHFILTER) + ENUM_TO_NAME(WelshFilter) +#endif +#if defined(HAVE_ENUM_PARZENFILTER) + ENUM_TO_NAME(ParzenFilter) +#endif +#if defined(HAVE_ENUM_LAGRANGEFILTER) + ENUM_TO_NAME(LagrangeFilter) +#endif +#if defined(HAVE_ENUM_BOHMANFILTER) + ENUM_TO_NAME(BohmanFilter) +#endif +#if defined(HAVE_ENUM_BARTLETTFILTER) + ENUM_TO_NAME(BartlettFilter) +#endif +#if defined(HAVE_ENUM_SENTINELFILTER) + ENUM_TO_NAME(SentinelFilter) +#endif } + + return "UndefinedFilter"; } /* External: FilterTypes.new Purpose: Construct an FilterTypes enum object for the specified value */ VALUE FilterTypes_new(FilterTypes type) { - const char *name; - - name = FilterTypes_name(type); + const char *name = FilterTypes_name(type); return rm_enum_new(Class_FilterTypes, ID2SYM(rb_intern(name)), INT2FIX(type)); } @@ -1541,41 +1503,78 @@ static const char * EndianType_name(EndianType type) { switch(type) { - default: ENUM_TO_NAME(UndefinedEndian) ENUM_TO_NAME(LSBEndian) ENUM_TO_NAME(MSBEndian) } + return "UndefinedEndian"; } /* External: EndianType.new Purpose: Construct an EndianType enum object */ VALUE EndianType_new(EndianType type) { - const char *name; - - name = EndianType_name(type); + const char *name = EndianType_name(type); return rm_enum_new(Class_EndianType, ID2SYM(rb_intern(name)), INT2FIX(type)); } +/* + Static: GravityType_name + Purpose: Return the name of a GravityType enum as a string +*/ +static const char * +GravityType_name(GravityType type) +{ + switch(type) + { + ENUM_TO_NAME(ForgetGravity) + ENUM_TO_NAME(NorthWestGravity) + ENUM_TO_NAME(NorthGravity) + ENUM_TO_NAME(NorthEastGravity) + ENUM_TO_NAME(WestGravity) + ENUM_TO_NAME(CenterGravity) + ENUM_TO_NAME(EastGravity) + ENUM_TO_NAME(SouthWestGravity) + ENUM_TO_NAME(SouthGravity) + ENUM_TO_NAME(SouthEastGravity) + ENUM_TO_NAME(StaticGravity) + } + // Defeat "duplicate case value" error. + return "UndefinedGravity"; +} + + /* + External: GravityType.new + Purpose: Construct an GravityType enum object for the specified value +*/ +VALUE +GravityType_new(GravityType type) +{ + const char *name = GravityType_name(type); + return rm_enum_new(Class_GravityType, ID2SYM(rb_intern(name)), INT2FIX(type)); +} + + + +/* Static: ImageType_name Purpose: Return the name of a ImageType enum as a string */ static char * ImageType_name(ImageType type) -{ switch(type) +{ + switch(type) { - default: ENUM_TO_NAME(UndefinedType) ENUM_TO_NAME(BilevelType) ENUM_TO_NAME(GrayscaleType) ENUM_TO_NAME(GrayscaleMatteType) ENUM_TO_NAME(PaletteType) @@ -1583,28 +1582,25 @@ ENUM_TO_NAME(TrueColorType) ENUM_TO_NAME(TrueColorMatteType) ENUM_TO_NAME(ColorSeparationType) ENUM_TO_NAME(ColorSeparationMatteType) ENUM_TO_NAME(OptimizeType) -#if defined(HAVE_PALETTEBILEVELMATTETYPE) ENUM_TO_NAME(PaletteBilevelMatteType) -#endif } + return "UndefinedType"; } /* External: ImageType.new Purpose: Construct an ImageType enum object for the specified value */ VALUE ImageType_new(ImageType type) { - const char *name; - - name = ImageType_name(type); + const char *name = ImageType_name(type); return rm_enum_new(Class_ImageType, ID2SYM(rb_intern(name)), INT2FIX(type)); } /* @@ -1614,105 +1610,133 @@ static const char * InterlaceType_name(InterlaceType interlace) { switch(interlace) { - default: ENUM_TO_NAME(UndefinedInterlace) +#if defined(HAVE_ENUM_GIFINTERLACE) + ENUM_TO_NAME(GIFInterlace) +#endif +#if defined(HAVE_ENUM_JPEGINTERLACE) + ENUM_TO_NAME(JPEGInterlace) +#endif +#if defined(HAVE_ENUM_PNGINTERLACE) + ENUM_TO_NAME(PNGInterlace) +#endif ENUM_TO_NAME(NoInterlace) ENUM_TO_NAME(LineInterlace) ENUM_TO_NAME(PlaneInterlace) ENUM_TO_NAME(PartitionInterlace) } + + return "UndefinedInterlace"; } /* External: InterlaceType_new Purpose: Construct an InterlaceType enum object for the specified value. */ VALUE InterlaceType_new(InterlaceType interlace) { - const char *name; - - name = InterlaceType_name(interlace); + const char *name = InterlaceType_name(interlace); return rm_enum_new(Class_InterlaceType, ID2SYM(rb_intern(name)), INT2FIX(interlace)); } /* Static: InterpolatePixelMethod_name Purpose: Return the name of a InterpolatePixelMethod enum as a string */ -#if defined(HAVE_INTERPOLATEPIXELCOLOR) static const char * InterpolatePixelMethod_name(InterpolatePixelMethod interpolate) { switch(interpolate) { - default: ENUM_TO_NAME(UndefinedInterpolatePixel) ENUM_TO_NAME(AverageInterpolatePixel) ENUM_TO_NAME(BicubicInterpolatePixel) ENUM_TO_NAME(BilinearInterpolatePixel) ENUM_TO_NAME(FilterInterpolatePixel) ENUM_TO_NAME(IntegerInterpolatePixel) ENUM_TO_NAME(MeshInterpolatePixel) ENUM_TO_NAME(NearestNeighborInterpolatePixel) +#if defined(HAVE_ENUM_SPLINEINTERPOLATEPIXEL) + ENUM_TO_NAME(SplineInterpolatePixel) +#endif } + + return "UndefinedInterpolatePixel"; } /* External: InterpolatePixelMethod_new Purpose: Construct an InterpolatePixelMethod enum object for the specified value. */ VALUE InterpolatePixelMethod_new(InterpolatePixelMethod interpolate) { - const char *name; - - name = InterpolatePixelMethod_name(interpolate); + const char *name = InterpolatePixelMethod_name(interpolate); return rm_enum_new(Class_InterpolatePixelMethod, ID2SYM(rb_intern(name)), INT2FIX(interpolate)); } -#endif /* External: MagickLayerMethod_new Purpose: Construct an MagickLayerMethod enum object for the specified value. */ -#if defined(HAVE_COMPAREIMAGELAYERS) static const char * -MagickLayerMethod_name(MagickLayerMethod method) +LAYERMETHODTYPE_NAME(LAYERMETHODTYPE method) { switch(method) { - default: ENUM_TO_NAME(UndefinedLayer) ENUM_TO_NAME(CompareAnyLayer) ENUM_TO_NAME(CompareClearLayer) ENUM_TO_NAME(CompareOverlayLayer) ENUM_TO_NAME(OptimizeLayer) ENUM_TO_NAME(OptimizePlusLayer) -#if defined(HAVE_COALESCELAYER) ENUM_TO_NAME(CoalesceLayer) ENUM_TO_NAME(DisposeLayer) +#if defined(HAVE_ENUM_OPTIMIZETRANSLAYER) + ENUM_TO_NAME(OptimizeTransLayer) #endif +#if defined(HAVE_ENUM_OPTIMIZEIMAGELAYER) + ENUM_TO_NAME(OptimizeImageLayer) +#endif +#if defined(HAVE_ENUM_REMOVEDUPSLAYER) + ENUM_TO_NAME(RemoveDupsLayer) +#endif +#if defined(HAVE_ENUM_REMOVEZEROLAYER) + ENUM_TO_NAME(RemoveZeroLayer) +#endif +#if defined(HAVE_ENUM_COMPOSITELAYER) + ENUM_TO_NAME(CompositeLayer) +#endif +#if defined(HAVE_ENUM_MERGELAYER) + ENUM_TO_NAME(MergeLayer) +#endif +#if defined(HAVE_ENUM_MOSAICLAYER) + ENUM_TO_NAME(MosaicLayer) +#endif +#if defined(HAVE_ENUM_FLATTENLAYER) + ENUM_TO_NAME(FlattenLayer) +#endif + } + + return "UndefinedLayer"; } VALUE -MagickLayerMethod_new(MagickLayerMethod method) +LAYERMETHODTYPE_NEW(LAYERMETHODTYPE method) { - const char *name; - - name = MagickLayerMethod_name(method); - return rm_enum_new(Class_MagickLayerMethod, ID2SYM(rb_intern(name)), INT2FIX(method)); + const char *name = LAYERMETHODTYPE_NAME(method); + return rm_enum_new(CLASS_LAYERMETHODTYPE, ID2SYM(rb_intern(name)), INT2FIX(method)); } -#endif /* Static: RenderingIntent_name Purpose: Return the name of a RenderingIntent enum as a string @@ -1720,18 +1744,18 @@ static const char * RenderingIntent_name(RenderingIntent intent) { switch(intent) { - default: ENUM_TO_NAME(UndefinedIntent) ENUM_TO_NAME(SaturationIntent) ENUM_TO_NAME(PerceptualIntent) ENUM_TO_NAME(AbsoluteIntent) ENUM_TO_NAME(RelativeIntent) } + return "UndefinedIntent"; } /* @@ -1739,13 +1763,11 @@ Purpose: Construct an RenderingIntent enum object for the specified value. */ VALUE RenderingIntent_new(RenderingIntent intent) { - const char *name; - - name = RenderingIntent_name(intent); + const char *name = RenderingIntent_name(intent); return rm_enum_new(Class_RenderingIntent, ID2SYM(rb_intern(name)), INT2FIX(intent)); } /* @@ -1755,71 +1777,66 @@ static const char * ResolutionType_name(ResolutionType type) { switch(type) { - default: ENUM_TO_NAME(UndefinedResolution) ENUM_TO_NAME(PixelsPerInchResolution) ENUM_TO_NAME(PixelsPerCentimeterResolution) } + return "UndefinedResolution"; } /* External: ResolutionType_new Purpose: Construct an ResolutionType enum object for the specified value. */ VALUE ResolutionType_new(ResolutionType type) { - const char *name; - - name = ResolutionType_name(type); + const char *name = ResolutionType_name(type); return rm_enum_new(Class_ResolutionType, ID2SYM(rb_intern(name)), INT2FIX(type)); } -#if defined(HAVE_IMAGE_ORIENTATION) /* Static: OrientationType_name Purpose: Return the name of a OrientationType enum as a string */ static const char * OrientationType_name(OrientationType type) { switch(type) { - default: ENUM_TO_NAME(UndefinedOrientation) ENUM_TO_NAME(TopLeftOrientation) ENUM_TO_NAME(TopRightOrientation) ENUM_TO_NAME(BottomRightOrientation) ENUM_TO_NAME(BottomLeftOrientation) ENUM_TO_NAME(LeftTopOrientation) ENUM_TO_NAME(RightTopOrientation) ENUM_TO_NAME(RightBottomOrientation) ENUM_TO_NAME(LeftBottomOrientation) } + + return "UndefinedOrientation"; } /* External: OrientationType_new Purpose: Construct an OrientationType enum object for the specified value. */ VALUE OrientationType_new(OrientationType type) { - const char *name; - - name = OrientationType_name(type); + const char *name = OrientationType_name(type); return rm_enum_new(Class_OrientationType, ID2SYM(rb_intern(name)), INT2FIX(type)); } -#endif /* External: Color_from_ColorInfo Purpose: Convert a ColorInfo structure to a Magick::Color @@ -1834,15 +1851,11 @@ name = rb_str_new2(ci->name); compliance_type = ci->compliance; compliance = ComplianceType_new(compliance_type); -#if defined(HAVE_NEW_COLORINFO) color = Pixel_from_MagickPixelPacket((MagickPixelPacket *)(&(ci->color))); -#else - color = Pixel_from_PixelPacket((PixelPacket *)(&(ci->color))); -#endif return rb_funcall(Class_Color, rm_ID_new, 3 , name, compliance, color); } @@ -1868,33 +1881,29 @@ members = rb_funcall(st, rm_ID_values, 0); m = rb_ary_entry(members, 0); if (m != Qnil) { - (void) CloneString((char **)&(ci->name), STRING_PTR(m)); + (void) CloneString((char **)&(ci->name), StringValuePtr(m)); } m = rb_ary_entry(members, 1); if (m != Qnil) { VALUE_TO_ENUM(m, ci->compliance, ComplianceType); } m = rb_ary_entry(members, 2); if (m != Qnil) { Data_Get_Struct(m, Pixel, pixel); -#if defined(HAVE_NEW_COLORINFO) // For >= 6.3.0, ColorInfo.color is a MagickPixelPacket so we have to // convert the PixelPacket. GetMagickPixelPacket(NULL, &ci->color); ci->color.red = (MagickRealType) pixel->red; ci->color.green = (MagickRealType) pixel->green; ci->color.blue = (MagickRealType) pixel->blue; ci->color.opacity = (MagickRealType) OpaqueOpacity; ci->color.index = (MagickRealType) 0; -#else - ci->color = *pixel; -#endif } } /* Static: destroy_ColorInfo @@ -1917,23 +1926,19 @@ ColorInfo ci; char buff[1024]; Color_to_ColorInfo(&ci, self); -#if defined(HAVE_NEW_COLORINFO) sprintf(buff, "name=%s, compliance=%s, " +#if (QuantumDepth == 32 || QuantumDepth == 64) && defined(HAVE_TYPE_LONG_DOUBLE) + "color.red=%Lg, color.green=%Lg, color.blue=%Lg, color.opacity=%Lg ", +#else "color.red=%g, color.green=%g, color.blue=%g, color.opacity=%g ", +#endif ci.name, ComplianceType_name(&ci.compliance), ci.color.red, ci.color.green, ci.color.blue, ci.color.opacity); -#else - sprintf(buff, "name=%s, compliance=%s, " - "color.red=%d, color.green=%d, color.blue=%d, color.opacity=%d ", - ci.name, - ComplianceType_name(&ci.compliance), - ci.color.red, ci.color.green, ci.color.blue, ci.color.opacity); -#endif destroy_ColorInfo(&ci); return rb_str_new2(buff); } @@ -1956,11 +1961,10 @@ /* Static: Pixel_from_MagickPixelPacket Purpose: Create a Magick::Pixel object from a MagickPixelPacket structure. Notes: bypasses normal Pixel.new, Pixel#initialize methods */ -#if defined(HAVE_NEW_COLORINFO) static VALUE Pixel_from_MagickPixelPacket(MagickPixelPacket *pp) { Pixel *pixel; @@ -1970,11 +1974,10 @@ pixel->blue = ROUND_TO_QUANTUM(pp->blue); pixel->opacity = ROUND_TO_QUANTUM(pp->opacity); return Data_Wrap_Struct(Class_Pixel, NULL, destroy_Pixel, pixel); } -#endif /* * Static: color_arg_rescue * Purpose: raise ArgumentError if the color name cannot be converted @@ -2252,13 +2255,11 @@ Purpose: Construct a StretchType enum for a specified StretchType value */ static VALUE StretchType_new(StretchType stretch) { - const char *name; - - name = StretchType_name(stretch); + const char *name = StretchType_name(stretch); return rm_enum_new(Class_StretchType, ID2SYM(rb_intern(name)), INT2FIX(stretch)); } /* @@ -2266,13 +2267,11 @@ Purpose: Construct a StyleType enum for a specified StyleType value */ static VALUE StyleType_new(StyleType style) { - const char *name; - - name = StyleType_name(style); + const char *name = StyleType_name(style); return rm_enum_new(Class_StyleType, ID2SYM(rb_intern(name)), INT2FIX(style)); } /* External: Font_from_TypeInfo @@ -2319,35 +2318,35 @@ members = rb_funcall(st, rm_ID_values, 0); m = rb_ary_entry(members, 0); if (m != Qnil) { - (void) CloneString((char **)&(ti->name), STRING_PTR(m)); + (void) CloneString((char **)&(ti->name), StringValuePtr(m)); } m = rb_ary_entry(members, 1); if (m != Qnil) { - (void) CloneString((char **)&(ti->description), STRING_PTR(m)); + (void) CloneString((char **)&(ti->description), StringValuePtr(m)); } m = rb_ary_entry(members, 2); if (m != Qnil) { - (void) CloneString((char **)&(ti->family), STRING_PTR(m)); + (void) CloneString((char **)&(ti->family), StringValuePtr(m)); } m = rb_ary_entry(members, 3); ti->style = m == Qnil ? 0 : FIX2INT(m); m = rb_ary_entry(members, 4); ti->stretch = m == Qnil ? 0 : FIX2INT(m); m = rb_ary_entry(members, 5); ti->weight = m == Qnil ? 0 : FIX2INT(m); m = rb_ary_entry(members, 6); if (m != Qnil) - (void) CloneString((char **)&(ti->encoding), STRING_PTR(m)); + (void) CloneString((char **)&(ti->encoding), StringValuePtr(m)); m = rb_ary_entry(members, 7); if (m != Qnil) - (void) CloneString((char **)&(ti->foundry), STRING_PTR(m)); + (void) CloneString((char **)&(ti->foundry), StringValuePtr(m)); m = rb_ary_entry(members, 8); if (m != Qnil) - (void) CloneString((char **)&(ti->format), STRING_PTR(m)); + (void) CloneString((char **)&(ti->format), StringValuePtr(m)); } /* Static: destroy_TypeInfo @@ -2513,33 +2512,45 @@ static const char * VirtualPixelMethod_name(VirtualPixelMethod method) { switch (method) { - default: ENUM_TO_NAME(UndefinedVirtualPixelMethod) ENUM_TO_NAME(EdgeVirtualPixelMethod) ENUM_TO_NAME(MirrorVirtualPixelMethod) ENUM_TO_NAME(TileVirtualPixelMethod) -#if defined(HAVE_TRANSPARENTVIRTUALPIXELMETHOD) ENUM_TO_NAME(TransparentVirtualPixelMethod) ENUM_TO_NAME(BackgroundVirtualPixelMethod) + ENUM_TO_NAME(DitherVirtualPixelMethod) + ENUM_TO_NAME(RandomVirtualPixelMethod) + ENUM_TO_NAME(ConstantVirtualPixelMethod) +#if defined(HAVE_ENUM_MASKVIRTUALPIXELMETHOD) + ENUM_TO_NAME(MaskVirtualPixelMethod) #endif +#if defined(HAVE_ENUM_BLACKVIRTUALPIXELMETHOD) + ENUM_TO_NAME(BlackVirtualPixelMethod) +#endif +#if defined(HAVE_ENUM_GRAYVIRTUALPIXELMETHOD) + ENUM_TO_NAME(GrayVirtualPixelMethod) +#endif +#if defined(HAVE_ENUM_WHITEVIRTUALPIXELMETHOD) + ENUM_TO_NAME(WhiteVirtualPixelMethod) +#endif } + + return "UndefinedVirtualPixelMethod"; } /* Static: VirtualPixelMethod_new Purpose: Construct a VirtualPixelMethod enum for a specified VirtualPixelMethod value */ VALUE VirtualPixelMethod_new(VirtualPixelMethod style) { - const char *name; - - name = VirtualPixelMethod_name(style); + const char *name = VirtualPixelMethod_name(style); return rm_enum_new(Class_VirtualPixelMethod, ID2SYM(rb_intern(name)), INT2FIX(style)); } /* @@ -2552,17 +2563,15 @@ class = rb_define_class_under(Module_Magick, tag, Class_Enum);\ rb_define_singleton_method(class, "values", Enum_type_values, 0); rb_define_method(class, "initialize", Enum_type_initialize, 2); - RUBY16(rb_enable_super(class, "initialize");) rb_define_method(class, "inspect", Enum_type_inspect, 0); return class; } -#if defined(HAVE_RB_DEFINE_ALLOC_FUNC) /* Extern: rm_enum_new (1.8) Purpose: Construct a new Enum subclass instance */ VALUE rm_enum_new(VALUE class, VALUE sym, VALUE val) @@ -2587,43 +2596,11 @@ OBJ_FREEZE(enumr); return enumr; } -#else /* - Extern: rm_enum_new (1.6) - Purpose: Construct a new Enum subclass instance -*/ -VALUE rm_enum_new(VALUE class, VALUE sym, VALUE val) -{ - return Enum_new(class, sym, val); -} - -/* - Method: Enum.new - Purpose: Construct a new Enum object - Notes: `class' can be an Enum subclass -*/ -VALUE Enum_new(VALUE class, VALUE sym, VALUE val) -{ - volatile VALUE new_enum; - volatile VALUE argv[2]; - MagickEnum *magick_enum; - - new_enum = Data_Make_Struct(class, MagickEnum, NULL, NULL, magick_enum); - argv[0] = sym; - argv[1] = val; - - rb_obj_call_init(new_enum, 2, argv); - OBJ_FREEZE(new_enum); - return new_enum; -} - -#endif - -/* Method: Enum#initialize Purpose: Initialize a new Enum instance */ VALUE Enum_initialize(VALUE self, VALUE sym, VALUE val) { @@ -2716,21 +2693,24 @@ * Method: xxx#initialize * Purpose: initialize method for all Enum subclasses */ VALUE Enum_type_initialize(VALUE self, VALUE sym, VALUE val) { - VALUE super_argv[2]; + volatile VALUE super_argv[2]; volatile VALUE enumerators; super_argv[0] = sym; super_argv[1] = val; - (void) rb_call_super(2, super_argv); + (void) rb_call_super(2, (VALUE *)super_argv); if (rb_cvar_defined(CLASS_OF(self), rm_ID_enumerators) != Qtrue) { - RUBY18(rb_cvar_set(CLASS_OF(self), rm_ID_enumerators, rb_ary_new(), 0)); - RUBY16(rb_cvar_set(CLASS_OF(self), rm_ID_enumerators, rb_ary_new())); +#if defined(HAVE_NEW_RB_CVAR_SET) + rb_cvar_set(CLASS_OF(self), rm_ID_enumerators, rb_ary_new()); +#else + rb_cvar_set(CLASS_OF(self), rm_ID_enumerators, rb_ary_new(), 0); +#endif } enumerators = rb_cvar_get(CLASS_OF(self), rm_ID_enumerators); (void) rb_ary_push(enumerators, self); @@ -2831,80 +2811,30 @@ return "UndefinedCompliance"; } } -#if defined(HAVE_GETIMAGESTATISTICS) /* - Extern: Statistics_new(stats) - Purpose: Create a Magick::Statistics object from an - ImageStatistics structure. -*/ -VALUE -Statistics_new(ImageStatistics *stats) -{ - volatile VALUE red, green, blue, opacity; - volatile VALUE min, max, mean, stddev, var; - - min = rb_float_new(stats->red.minimum); - max = rb_float_new(stats->red.maximum); - mean = rb_float_new(stats->red.mean); - stddev = rb_float_new(stats->red.standard_deviation); - var = rb_float_new(stats->red.variance); - red = rb_funcall(Class_StatisticsChannel, rm_ID_new, 5, max, min, mean, stddev, var); - - min = rb_float_new(stats->green.minimum); - max = rb_float_new(stats->green.maximum); - mean = rb_float_new(stats->green.mean); - stddev = rb_float_new(stats->green.standard_deviation); - var = rb_float_new(stats->green.variance); - green = rb_funcall(Class_StatisticsChannel, rm_ID_new, 5, max, min, mean, stddev, var); - - min = rb_float_new(stats->blue.minimum); - max = rb_float_new(stats->blue.maximum); - mean = rb_float_new(stats->blue.mean); - stddev = rb_float_new(stats->blue.standard_deviation); - var = rb_float_new(stats->blue.variance); - blue = rb_funcall(Class_StatisticsChannel, rm_ID_new, 5, max, min, mean, stddev, var); - - min = rb_float_new(stats->opacity.minimum); - max = rb_float_new(stats->opacity.maximum); - mean = rb_float_new(stats->opacity.mean); - stddev = rb_float_new(stats->opacity.standard_deviation); - var = rb_float_new(stats->opacity.variance); - opacity = rb_funcall(Class_StatisticsChannel, rm_ID_new, 5, max, min, mean, stddev, var); - - return rb_funcall(Class_Statistics, rm_ID_new, 4, red, green, blue, opacity); - -} -#endif // HAVE_GETIMAGESTATISTICS - -/* Extern: StorageType_name Purpose: Return the string representation of a StorageType value */ const char * StorageType_name(StorageType type) { switch (type) { + ENUM_TO_NAME(UndefinedPixel) ENUM_TO_NAME(CharPixel) ENUM_TO_NAME(DoublePixel) ENUM_TO_NAME(FloatPixel) ENUM_TO_NAME(IntegerPixel) ENUM_TO_NAME(LongPixel) -#if defined(HAVE_QUANTUMPIXEL) ENUM_TO_NAME(QuantumPixel) -#endif ENUM_TO_NAME(ShortPixel) - default: -#if defined(HAVE_UNDEFINEDGRAVITY) // UndefinedGravity & UndefinedPixel were both introduced in IM 6.0.0 - ENUM_TO_NAME(UndefinedPixel) -#else - return "UndefinedPixel"; -#endif } + + return "UndefinedPixel"; } /* Static: StretchType_name Purpose: Return the string representation of a StretchType value @@ -2912,27 +2842,24 @@ static const char * StretchType_name(StretchType stretch) { switch (stretch) { + ENUM_TO_NAME(UndefinedStretch) ENUM_TO_NAME(NormalStretch) ENUM_TO_NAME(UltraCondensedStretch) ENUM_TO_NAME(ExtraCondensedStretch) ENUM_TO_NAME(CondensedStretch) ENUM_TO_NAME(SemiCondensedStretch) ENUM_TO_NAME(SemiExpandedStretch) ENUM_TO_NAME(ExpandedStretch) ENUM_TO_NAME(ExtraExpandedStretch) ENUM_TO_NAME(UltraExpandedStretch) ENUM_TO_NAME(AnyStretch) - default: -#if defined(HAVE_UNDEFINEDGRAVITY) // UndefinedGravity & UndefinedStretch were both introduced in IM 6.0.0 - ENUM_TO_NAME(UndefinedStretch) -#else - return "UndefinedStretch"; -#endif } + + return "UndefinedStretch"; } /* Static: StyleType_name @@ -2941,21 +2868,18 @@ static const char * StyleType_name(StyleType style) { switch (style) { + ENUM_TO_NAME(UndefinedStyle) ENUM_TO_NAME(NormalStyle) ENUM_TO_NAME(ItalicStyle) ENUM_TO_NAME(ObliqueStyle) ENUM_TO_NAME(AnyStyle) - default: -#if defined(HAVE_UNDEFINEDGRAVITY) // UndefinedGravity & UndefinedStyle were both introduced in IM 6.0.0 - ENUM_TO_NAME(UndefinedStyle) -#else - return "UndefinedStyle"; -#endif } + + return "UndefinedStyle"; } /* External: write_temp_image @@ -2988,12 +2912,15 @@ id = 0; rb_define_class_variable(Module_Magick, "@@__tmpnam__", INT2FIX(id)); } id += 1; - RUBY16(rb_cvar_set(Module_Magick, rm_ID__tmpnam_, INT2FIX(id));) - RUBY18(rb_cvar_set(Module_Magick, rm_ID__tmpnam_, INT2FIX(id), 0);) +#if defined(HAVE_NEW_RB_CVAR_SET) + rb_cvar_set(Module_Magick, rm_ID__tmpnam_, INT2FIX(id)); +#else + rb_cvar_set(Module_Magick, rm_ID__tmpnam_, INT2FIX(id), 0); +#endif sprintf(tmpnam, "mpri:%d", id); // Omit "mpri:" from filename to form the key okay = SetImageRegistry(ImageRegistryType, tmpnam+5, image, &exception); @@ -3006,23 +2933,21 @@ #else long registry_id; -#if !defined(GRAPHICSMAGICK) - /* This leak doesn't occur in GraphicsMagick as far as I know. */ - rb_warn("`%s' can cause memory leaks when RMagick was built with " Q(MAGICKNAME) " " MagickLibVersionText - ".\nUpgrade to ImageMagick 6.3.4 or later to prevent this behavior." - , rb_id2name(rb_frame_last_func())); -#endif + rb_warn("`%s' can cause memory leaks with ImageMagick " MagickLibVersionText + ".\nUpgrade to ImageMagick 6.3.4-10 or later to prevent this behavior." + , rb_id2name(THIS_FUNC())); registry_id = SetMagickRegistry(ImageRegistryType, image, sizeof(Image), &image->exception); rm_check_image_exception(image, RetainOnError); if (registry_id < 0) { rb_raise(rb_eRuntimeError, "SetMagickRegistry failed."); } + sprintf(tmpnam, "mpri:%ld", registry_id); #endif } @@ -3049,28 +2974,24 @@ if (registry_id >= 0) { (void) DeleteMagickRegistry(registry_id); } #endif - } /* External: rm_not_implemented Purpose: raise NotImplementedError Notes: Called when a xMagick API is not available. Replaces Ruby's rb_notimplement function. - Notes: The MagickPackageName macro is not available - until 5.5.7. Use MAGICKNAME instead. */ void rm_not_implemented(void) { - rb_raise(rb_eNotImpError, "the `%s' method is not supported by " - Q(MAGICKNAME) " " MagickLibVersionText - , rb_id2name(rb_frame_last_func())); + rb_raise(rb_eNotImpError, "the `%s' method is not supported by ImageMagick " + MagickLibVersionText, rb_id2name(THIS_FUNC())); } /* Static: rm_magick_error(msg, loc) Purpose: create a new ImageMagickError object and raise an exception @@ -3098,11 +3019,11 @@ the "loc" string in the @magick_location instance variable */ VALUE ImageMagickError_initialize(int argc, VALUE *argv, VALUE self) { - VALUE super_argv[1] = {(VALUE)0}; + volatile VALUE super_argv[1] = {(VALUE)0}; int super_argc = 0; volatile VALUE extra = Qnil; switch(argc) { @@ -3115,11 +3036,11 @@ break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 2)", argc); } - (void) rb_call_super(super_argc, super_argv); + (void) rb_call_super(super_argc, (VALUE *)super_argv); (void) rb_iv_set(self, "@"MAGICK_LOC, extra); return self; } @@ -3144,14 +3065,14 @@ /* Function: rm_set_property Purpose: Backport SetImageProperty for pre-6.3.1 versions of ImageMagick */ -unsigned int rm_set_property(Image *image, const char *property, const char *value) +MagickBooleanType rm_set_property(Image *image, const char *property, const char *value) { #if defined(HAVE_SETIMAGEPROPERTY) - return (unsigned int) SetImageProperty(image, property, value); + return SetImageProperty(image, property, value); #else return SetImageAttribute(image, property, value); #endif } @@ -3237,12 +3158,12 @@ xfree(str); return v; #else - const ImageAttribute *attr = GetImageAttribute(image, "EXIF:*"); - return attr ? rb_str_new2(attr->value) : Qnil; + const char *attr = rm_get_property(image, "EXIF:*"); + return attr ? rb_str_new2(attr) : Qnil; #endif } @@ -3327,19 +3248,19 @@ xfree(str); return v; #else - const ImageAttribute *attr = GetImageAttribute(image, "EXIF:!"); - return attr ? rb_str_new2(attr->value) : Qnil; + const char *attr = rm_get_property(image, "EXIF:!"); + return attr ? rb_str_new2(attr) : Qnil; #endif } /* - * Extern: get_geometry + * Extern: rm_get_geometry * Purpose: Get the values from a Geometry object and return * them in C variables. */ void rm_get_geometry( @@ -3387,10 +3308,12 @@ /* * Extern: rm_clone_image * Purpose: clone an image, handle errors + * Notes: don't trace creation - the clone may not be used as an Image + * object. Let the caller do the trace if desired. */ Image *rm_clone_image(Image *image) { Image *clone; ExceptionInfo exception; @@ -3411,37 +3334,35 @@ /* Extern: rm_progress_monitor Purpose: SetImage(Info)ProgressMonitor exit Notes: ImageMagick's "tag" argument is unused. We pass along the method name instead. */ -#if defined(HAVE_SETIMAGEPROGRESSMONITOR) MagickBooleanType rm_progress_monitor( const char *tag, const MagickOffsetType of, const MagickSizeType sp, void *client_data) { volatile VALUE rval; volatile VALUE method, offset, span; - tag = tag; // defeat gcc message + tag = tag; // defeat gcc message #if defined(HAVE_LONG_LONG) // defined in Ruby's defines.h offset = rb_ll2inum(of); span = rb_ull2inum(sp); #else offset = rb_int2big((long)of); span = rb_uint2big((unsigned long)sp); #endif - method = rb_str_new2(rb_id2name(rb_frame_last_func())); + method = rb_str_new2(rb_id2name(THIS_FUNC())); rval = rb_funcall((VALUE)client_data, rm_ID_call, 3, method, offset, span); return RTEST(rval) ? MagickTrue : MagickFalse; } -#endif /* Extern: rm_split Purpose: Remove the ImageMagick links between images in an scene @@ -3461,112 +3382,11 @@ (void) RemoveFirstImageFromList(&image); } } - /* - * Static: copy_exception - * clear_exception - * Purpose: Define alternative implementations of ImageMagick's - * InheritException and ClearMagickException. - * Notes: InheritException is ALWAYS defined in ImageMagick and - * NEVER defined in GraphicsMagick. ClearMagickException - * is defined in ImageMagick 6.2.6 and later and NEVER - * defined in GraphicsMagick. - * - * The purpose of InheritException is to copy the exception - * information from a "related" exception to a destination - * exception if the related exception is more severe than the - * destination exception. - * - * The purpose of ClearException is to reset the ExceptionInfo - * structure to its initial format. - */ - -#if defined(HAVE_INHERITEXCEPTION) - - // This is ImageMagick - InheritException is always defined - static void copy_exception(ExceptionInfo *exception, ExceptionInfo *relative) - { - InheritException(exception, relative); - } - - // ImageMagick < 6.2.6 had a different kind of ExceptionInfo struct - // and doesn't define ClearMagickException. - #if defined(HAVE_CLEARMAGICKEXCEPTION) - static void clear_exception(ExceptionInfo *exception) - { - ClearMagickException(exception); - } - #else - - static void clear_exception(ExceptionInfo *exception) - { - DestroyExceptionInfo(exception); - GetExceptionInfo(exception); - } - - #endif - - -#else // !defined(HAVE_INHERITEXCEPTION) - - // This is GraphicsMagick. Very old versions don't support the - // module, function, and line fields in the ExceptionInfo struct. - - static void copy_exception(ExceptionInfo *exception, ExceptionInfo *relative) - { - assert(exception != NULL); - assert(exception->signature == MagickSignature); - assert(relative != NULL); - - if (relative->severity < exception->severity) - { - return; - } - - DestroyExceptionInfo(exception); - GetExceptionInfo(exception); - - exception->severity = relative->severity; - if (relative->reason) - { - magick_clone_string(&exception->reason, relative->reason); - } - - if (relative->description) - { - magick_clone_string(&exception->description, relative->description); - } - - - #if defined(HAVE_EXCEPTIONINFO_MODULE) - if (relative->module) - { - magick_clone_string(&exception->module, relative->module); - } - if (relative->function) - { - magick_clone_string(&exception->function, relative->function); - } - - exception->line = relative->line; - #endif - } - - - static void clear_exception(ExceptionInfo *exception) - { - DestroyExceptionInfo(exception); - GetExceptionInfo(exception); - } - -#endif - - -/* Extern: rm_check_image_exception Purpose: If an ExceptionInfo struct in a list of images indicates a warning, issue a warning message. If an ExceptionInfo struct indicates an error, raise an exception and optionally destroy the images. */ @@ -3591,14 +3411,14 @@ if (image->exception.severity != UndefinedException) { if (!badboy || image->exception.severity > badboy->exception.severity) { badboy = image; - copy_exception(&exception, &badboy->exception); + InheritException(&exception, &badboy->exception); } - clear_exception(&image->exception); + ClearMagickException(&image->exception); } image = GetNextImageInList(image); } if (badboy) @@ -3639,17 +3459,10 @@ char reason[500]; char desc[500]; char msg[sizeof(reason)+sizeof(desc)+20]; -#if defined(HAVE_EXCEPTIONINFO_MODULE) - char module[200], function[200]; - char extra[sizeof(module)+sizeof(function)+20]; - unsigned long line; -#endif - - memset(msg, 0, sizeof(msg)); // Handle simple warning if (exception->severity < ErrorException) @@ -3717,43 +3530,11 @@ sizeof(desc)-1, desc[0] ? GetLocaleExceptionMessage(exception->severity, desc) : ""); #endif msg[sizeof(msg)-1] = '\0'; - -#if defined(HAVE_EXCEPTIONINFO_MODULE) - - memset(module, 0, sizeof(module)); - memset(function, 0, sizeof(function)); - memset(extra, 0, sizeof(extra)); - - if (exception->module) - { - strncpy(module, exception->module, sizeof(module)-1); - module[sizeof(module)-1] = '\0'; - } - if (exception->function) - { - strncpy(function, exception->function, sizeof(function)-1); - function[sizeof(function)-1] = '\0'; - } - line = exception->line; - -#if defined(HAVE_SNPRINTF) - snprintf(extra, sizeof(extra)-1, "%s at %s:%lu", function, module, line); -#else - sprintf(extra, "%.*s at %.*s:%lu", sizeof(function), function, sizeof(module), module, line); -#endif - - extra[sizeof(extra)-1] = '\0'; - - (void) DestroyExceptionInfo(exception); - rm_magick_error(msg, extra); - -#else - (void) DestroyExceptionInfo(exception); - rm_magick_error(msg, NULL); -#endif + (void) DestroyExceptionInfo(exception); + rm_magick_error(msg, NULL); } /*