ext/RMagick/rminfo.c in rmagick-1.15.17 vs ext/RMagick/rminfo.c in rmagick-2.0.0
- old
+ new
@@ -1,166 +1,317 @@
-/* $Id: rminfo.c,v 1.45.2.2.2.3 2008/09/10 23:22:46 rmagick Exp $ */
+/* $Id: rminfo.c,v 1.67 2007/10/28 23:43:24 rmagick Exp $ */
/*============================================================================\
-| Copyright (C) 2008 by Timothy P. Hunter
+| Copyright (C) 2007 by Timothy P. Hunter
| Name: rminfo.c
| Author: Tim Hunter
| Purpose: Info class method definitions for RMagick.
\============================================================================*/
#include "rmagick.h"
-static VALUE get_option(VALUE, char *);
-static VALUE set_option(VALUE, char *, VALUE);
-DEF_ATTR_ACCESSOR(Info, antialias, bool)
+
/*
- * Method: value = Info[format, key]
- * Purpose: get the value of an option set by Info[]=
+ Method: Info#get_option
+ Purpose: Return the value of the specified option
*/
-#define MAX_FORMAT_LEN 60
-
-VALUE
-Info_aref(VALUE self, VALUE format, VALUE key)
+static VALUE
+get_option(VALUE self, const char *key)
{
-#if defined(HAVE_SETIMAGEOPTION)
Info *info;
- char *format_p, *key_p;
- long format_l, key_l;
const char *value;
- char fkey[MaxTextExtent];
- format_p = STRING_PTR_LEN(format, format_l);
- key_p = STRING_PTR_LEN(key, key_l);
+ Data_Get_Struct(self, Info, info);
- if (format_l > MAX_FORMAT_LEN || format_l + key_l > MaxTextExtent-1)
+ value = GetImageOption(info, key);
+ if (value)
{
- rb_raise(rb_eArgError, "can't reference %.60s:%.1024s - too long", format_p, key_p);
+ return rb_str_new2(value);
}
+ return Qnil;
+}
- sprintf(fkey, "%.60s:%.*s", STRING_PTR(format), (int)(MaxTextExtent-61), STRING_PTR(key));
+/*
+ Method: Info#set_option
+ Purpose: Set the specified option to this value.
+ If the value is nil just unset any current value
+*/
+static VALUE
+set_option(VALUE self, const char *key, VALUE string)
+{
+ Info *info;
+ char *value;
Data_Get_Struct(self, Info, info);
- value = GetImageOption(info, fkey);
- if (!value)
+
+ if (NIL_P(string))
{
- return Qnil;
+ (void) RemoveImageOption(info, key);
}
+ else
+ {
+ value = StringValuePtr(string);
+ (void) SetImageOption(info, key, value);
+ }
+ return self;
+}
- return rb_str_new2(value);
-#elif defined(HAVE_ADDDEFINITIONS)
+/*
+ Static: set_color_option
+ Purpose: Set a color name as the value of the specified option
+ Note: Call QueryColorDatabase to validate color name
+*/
+static VALUE set_color_option(VALUE self, const char *option, VALUE color)
+{
Info *info;
+ char *name;
+ PixelPacket pp;
+ ExceptionInfo exception;
+ MagickBooleanType okay;
+
+ Data_Get_Struct(self, Info, info);
+
+ if (NIL_P(color))
+ {
+ (void) RemoveImageOption(info, option);
+ }
+ else
+ {
+ GetExceptionInfo(&exception);
+ name = StringValuePtr(color);
+ okay = QueryColorDatabase(name, &pp, &exception);
+ (void) DestroyExceptionInfo(&exception);
+ if (!okay)
+ {
+ rb_raise(rb_eArgError, "invalid color name `%s'", name);
+ }
+
+ (void) RemoveImageOption(info, option);
+ (void) SetImageOption(info, option, name);
+ }
+
+ return self;
+}
+
+
+/*
+ Static: get_dbl_option(obj, option)
+ Purpose: Get an Image::Info option floating-point value
+ Notes: Convert the string value to a float
+*/
+static VALUE get_dbl_option(VALUE self, const char *option)
+{
+ Info *info;
const char *value;
+ double d;
+ long n;
Data_Get_Struct(self, Info, info);
- value = AccessDefinition(info, STRING_PTR(format), STRING_PTR(key));
+ value = GetImageOption(info, option);
if (!value)
{
return Qnil;
}
- return rb_str_new2(value);
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
+ d = atof(value);
+ n = (long) floor(d);
+ return d == (double)n ? LONG2NUM(n) : rb_float_new(d);
}
/*
- Method: Info[format, key] = value
- Purpose: Call AddDefinitions (GM) or SetImageOption (IM)
- Note: Essentially the same function as Info#define but paired
- with Info#[]=
+ Static: set_dbl_option(obj, option, value)
+ Purpose: Set an Image::Info option to a floating-point value
+ Notes: SetImageOption expects the value to be a string.
*/
+static VALUE set_dbl_option(VALUE self, const char *option, VALUE value)
+{
+ Info *info;
+ char buff[50];
+ double d;
+ long n;
+ int len;
+
+ Data_Get_Struct(self, Info, info);
+
+ if (NIL_P(value))
+ {
+ (void) RemoveImageOption(info, option);
+ }
+ else
+ {
+ d = NUM2DBL(value);
+ n = floor(d);
+ if (d == n)
+ {
+ len = sprintf(buff, "%-10ld", n);
+ }
+ else
+ {
+ len = sprintf(buff, "%-10.2f", d);
+ }
+ memset(buff+len, '\0', sizeof(buff)-len);
+ (void) RemoveImageOption(info, option);
+ (void) SetImageOption(info, option, buff);
+ }
+
+ return self;
+}
+
+
+DEF_ATTR_ACCESSOR(Info, antialias, bool)
+
+/*
+ Method: value = Info[format, key]
+ value = Info[key]
+ Purpose: get the value of an option set by Info[]=
+ The 2 argument form is the original form. Added support for a
+ single argument after ImageMagick started using Set/GetImageOption
+ for options that aren't represented by fields in the ImageInfo
+ structure.
+*/
+#define MAX_FORMAT_LEN 60
+
VALUE
-Info_aset(VALUE self, VALUE format, VALUE key, VALUE value)
+Info_aref(int argc, VALUE *argv, VALUE self)
{
-#if defined(HAVE_SETIMAGEOPTION)
Info *info;
- char *format_p, *key_p, *value_p = "";
+ char *format_p, *key_p;
long format_l, key_l;
- char ckey[MaxTextExtent];
- unsigned int okay;
+ const char *value;
+ char fkey[MaxTextExtent];
+ switch (argc)
+ {
+ case 2:
+ format_p = rb_str2cstr(argv[0], &format_l);
+ key_p = rb_str2cstr(argv[1], &key_l);
+ if (format_l > MAX_FORMAT_LEN || format_l + key_l > MaxTextExtent-1)
+ {
+ rb_raise(rb_eArgError, "can't reference %.60s:%.1024s - too long", format_p, key_p);
+ }
- Data_Get_Struct(self, Info, info);
+ sprintf(fkey, "%.60s:%.*s", format_p, (int)(MaxTextExtent-61), key_p);
+ break;
- format_p = STRING_PTR_LEN(format, format_l);
- key_p = STRING_PTR_LEN(key, key_l);
+ case 1:
+ strncpy(fkey, StringValuePtr(argv[0]), sizeof(fkey)-1);
+ fkey[sizeof(fkey)-1] = '\0';
+ break;
- /* Allow any argument that supports to_s */
- value = rb_funcall(value, rm_ID_to_s, 0);
- value_p = STRING_PTR(value);
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
+ break;
- if (format_l > MAX_FORMAT_LEN || format_l+key_l > MaxTextExtent-1)
- {
- rb_raise(rb_eArgError, "%.60s:%.1024s not defined - too long", format_p, key_p);
}
- (void) sprintf(ckey, "%.60s:%.*s", format_p, (int)(sizeof(ckey)-MAX_FORMAT_LEN), key_p);
-
- okay = SetImageOption(info, ckey, value_p);
- if (!okay)
+ Data_Get_Struct(self, Info, info);
+ value = GetImageOption(info, fkey);
+ if (!value)
{
- rb_warn("%.60s:%.1024s not defined - SetImageOption failed.", format_p, key_p);
return Qnil;
}
- return self;
+ return rb_str_new2(value);
+}
-#elif defined(HAVE_ADDDEFINITIONS)
+
+/*
+ Method: Info[format, key] = value
+ Purpose: Call SetImageOption
+ Note: Essentially the same function as Info#define but paired with Info#[]=
+ If the value is nil it is equivalent to #undefine.
+
+ The 2 argument form is the original form. Added support for a
+ single argument after ImageMagick started using Set/GetImageOption
+ for options that aren't represented by fields in the ImageInfo
+ structure.
+*/
+VALUE
+Info_aset(int argc, VALUE *argv, VALUE self)
+{
Info *info;
- char *format_p, *key_p, *value_p = NULL;
- long format_l, key_l, value_l = 0;
+ volatile VALUE value;
+ char *format_p, *key_p, *value_p = "";
+ long format_l, key_l;
+ char ckey[MaxTextExtent];
unsigned int okay;
- ExceptionInfo exception;
- char definitions[MaxTextExtent*2];/* Make this buffer longer than the buffer used */
- /* for SetImageOptions since AddDefinitions cats */
- /* the value onto the format:key pair. */
+
Data_Get_Struct(self, Info, info);
- format_p = STRING_PTR_LEN(format, format_l);
- key_p = STRING_PTR_LEN(key, key_l);
- value = rb_funcall(value, rm_ID_to_s, 0);
- value_p = STRING_PTR_LEN(value, value_l);
-
- if ((3 + format_l + key_l + value_l) > sizeof(definitions))
+ switch (argc)
{
- rb_raise(rb_eArgError, "%.60s:%.1024s not defined - too long", format_p, key_p);
+ case 3:
+ format_p = rb_str2cstr(argv[0], &format_l);
+ key_p = rb_str2cstr(argv[1], &key_l);
+
+ if (format_l > MAX_FORMAT_LEN || format_l+key_l > MaxTextExtent-1)
+ {
+ rb_raise(rb_eArgError, "%.60s:%.1024s not defined - too long", format_p, key_p);
+ }
+
+ (void) sprintf(ckey, "%.60s:%.*s", format_p, (int)(sizeof(ckey)-MAX_FORMAT_LEN), key_p);
+
+ value = argv[2];
+ break;
+
+ case 2:
+ strncpy(ckey, StringValuePtr(argv[0]), sizeof(ckey)-1);
+ ckey[sizeof(ckey)-1] = '\0';
+
+ value = argv[1];
+ break;
+
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc);
+ break;
}
- (void)sprintf(definitions, "%s:%s=", format_p, key_p);
- if (value_l > 0)
+
+ if (NIL_P(value))
{
- strcat(definitions, value_p);
+ (void) RemoveImageOption(info, ckey);
}
-
- GetExceptionInfo(&exception);
- okay = AddDefinitions(info, definitions, &exception);
- CHECK_EXCEPTION()
- (void) DestroyExceptionInfo(&exception);
-
- if (!okay)
+ else
{
- rb_warn("%.60s:%.1024s not defined - AddDefinitions failed.", format_p, key_p);
- return Qnil;
+ /* Allow any argument that supports to_s */
+ value = rb_funcall(value, rm_ID_to_s, 0);
+ value_p = StringValuePtr(value);
+
+ (void) RemoveImageOption(info, ckey);
+ okay = SetImageOption(info, ckey, value_p);
+ if (!okay)
+ {
+ rb_warn("`%s' not defined - SetImageOption failed.", ckey);
+ return Qnil;
+ }
}
+
return self;
+}
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
+
+VALUE
+Info_attenuate(VALUE self)
+{
+ return get_dbl_option(self, "attenuate");
}
VALUE
+Info_attenuate_eq(VALUE self, VALUE value)
+{
+ return set_dbl_option(self, "attenuate", value);
+}
+
+
+VALUE
Info_authenticate(VALUE self)
{
Info *info;
Data_Get_Struct(self, Info, info);
@@ -184,11 +335,11 @@
Data_Get_Struct(self, Info, info);
if (!NIL_P(passwd))
{
- passwd_p = STRING_PTR_LEN(passwd, passwd_len);
+ passwd_p = rb_str2cstr(passwd, &passwd_len);
}
if (info->authenticate)
{
magick_free(info->authenticate);
@@ -269,11 +420,10 @@
Thanks: Douglas Sellers
*/
VALUE
Info_channel(int argc, VALUE *argv, VALUE self)
{
-#if defined(HAVE_IMAGEINFO_CHANNEL)
Info *info;
ChannelType channels;
channels = extract_channels(&argc, argv);
@@ -285,14 +435,10 @@
Data_Get_Struct(self, Info, info);
info->channel = channels;
return self;
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}
/*
Method: Info#colorspace
@@ -353,124 +499,65 @@
return self;
}
/*
Method: Info#define(format, key[, value])
- Purpose: Call AddDefinitions (GM) or SetImageOption (IM)
+ Purpose: Call SetImageOption
Note: The only method in Info that is not an
attribute accessor.
*/
VALUE
Info_define(int argc, VALUE *argv, VALUE self)
{
-#if defined(HAVE_SETIMAGEOPTION)
Info *info;
char *format, *key, *value = "";
long format_l, key_l;
char ckey[100];
unsigned int okay;
volatile VALUE fmt_arg;
Data_Get_Struct(self, Info, info);
- switch(argc)
+ switch (argc)
{
case 3:
/* Allow any argument that supports to_s */
fmt_arg = rb_funcall(argv[2], rm_ID_to_s, 0);
- value = STRING_PTR(fmt_arg);
+ value = StringValuePtr(fmt_arg);
case 2:
- key = STRING_PTR_LEN(argv[1], key_l);
- format = STRING_PTR_LEN(argv[0], format_l);
+ key = rb_str2cstr(argv[1], &key_l);
+ format = rb_str2cstr(argv[0], &format_l);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc);
}
- if (2 + format_l + key_l > (int)sizeof(ckey))
+ if (2 + format_l + key_l > (long)sizeof(ckey))
{
rb_raise(rb_eArgError, "%.20s:%.20s not defined - format or key too long", format, key);
}
(void) sprintf(ckey, "%s:%s", format, key);
+ (void) RemoveImageOption(info, ckey);
okay = SetImageOption(info, ckey, value);
if (!okay)
{
rb_warn("%.20s=\"%.78s\" not defined - SetImageOption failed.", ckey, value);
return Qnil;
}
return self;
-
-#elif defined(HAVE_ADDDEFINITIONS)
- Info *info;
- char *format, *key, *value = NULL;
- long format_l, key_l, value_l = 0;
- unsigned int okay;
- volatile VALUE fmt_arg;
- ExceptionInfo exception;
- char definitions[200]; /* Make this buffer longer than the buffer used */
- /* for SetImageOptions since AddDefinitions cats */
- /* the value onto the format:key pair. */
-
- Data_Get_Struct(self, Info, info);
-
- switch(argc)
- {
- case 3:
- /* Allow any argument that supports to_s */
- fmt_arg = rb_funcall(argv[2], rm_ID_to_s, 0);
- value = STRING_PTR_LEN(fmt_arg, value_l);
- /* Fall through */
- case 2:
- key = STRING_PTR_LEN(argv[1], key_l);
- format = STRING_PTR_LEN(argv[0], format_l);
- break;
- default:
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc);
- break;
- }
-
-
- if ((3 + format_l + key_l + value_l) > sizeof(definitions))
- {
- rb_raise(rb_eArgError, "%.20s:%.20s not defined - too long", format, key);
- }
- (void)sprintf(definitions, "%s:%s=", format, key);
- if (value)
- {
- strcat(definitions, value);
- }
-
- GetExceptionInfo(&exception);
- okay = AddDefinitions(info, definitions, &exception);
- CHECK_EXCEPTION()
- (void) DestroyExceptionInfo(&exception);
-
- if (!okay)
- {
- rb_warn("%.*s not defined - AddDefinitions failed.", sizeof(definitions), definitions);
- return Qnil;
- }
-
- return self;
-
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}
/*
Method: Info#delay
Purpose: Get the delay attribute
Notes: Convert from string to numeric
*/
VALUE
Info_delay(VALUE self)
{
-#if defined(HAVE_SETIMAGEOPTION)
Info *info;
const char *delay;
char *p;
long d;
@@ -485,38 +572,31 @@
rb_raise(rb_eRangeError, "failed to convert %s to Numeric", delay);
}
return LONG2NUM(d);
}
return Qnil;
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}
/*
* Will raise an exception if `arg' can't be converted to an int.
*/
-#if defined(HAVE_SETIMAGEOPTION)
static VALUE
arg_is_integer(VALUE arg)
{
int d = NUM2INT(arg);
d = d; // satisfy icc
return arg;
}
-#endif
/*
Method: Info#delay=
Purpose: Set the delay attribute
Notes: Convert from numeric value to string.
*/
VALUE
Info_delay_eq(VALUE self, VALUE string)
{
-#if defined(HAVE_SETIMAGEOPTION)
Info *info;
int delay;
int not_num;
char dstr[20];
@@ -534,17 +614,14 @@
{
rb_raise(rb_eTypeError, "failed to convert %s into Integer", rb_class2name(CLASS_OF(string)));
}
delay = NUM2INT(string);
sprintf(dstr, "%d", delay);
+ (void) RemoveImageOption(info, "delay");
(void) SetImageOption(info, "delay", dstr);
}
return self;
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}
DEF_ATTR_READER(Info, density, str)
/*
@@ -559,19 +636,19 @@
volatile VALUE density;
char *dens;
Data_Get_Struct(self, Info, info);
- if(NIL_P(density_arg))
+ if (NIL_P(density_arg))
{
magick_free(info->density);
info->density = NULL;
return self;
}
density = rb_funcall(density_arg, rm_ID_to_s, 0);
- dens = STRING_PTR(density);
+ dens = StringValuePtr(density);
if (!IsGeometry(dens))
{
rb_raise(rb_eArgError, "invalid density geometry: %s", dens);
}
@@ -596,16 +673,19 @@
Data_Get_Struct(self, Info, info);
d = NUM2ULONG(depth);
switch (d)
{
case 8: // always okay
-#if QuantumDepth == 16 || QuantumDepth == 32
+#if QuantumDepth == 16 || QuantumDepth == 32 || QuantumDepth == 64
case 16:
-#endif
-#if QuantumDepth == 32
+#if QuantumDepth == 32 || QuantumDepth == 64
case 32:
+#if QuantumDepth == 64
+ case 64:
#endif
+#endif
+#endif
break;
default:
rb_raise(rb_eArgError, "invalid depth (%lu)", d);
break;
}
@@ -617,35 +697,32 @@
/*
Method: Info#dispose
Purpose: Retrieve a dispose option string and convert it to
a DisposeType enumerator
*/
-#if defined(HAVE_SETIMAGEOPTION)
static struct
{
char *string;
char *enum_name;
DisposeType enumerator;
} Dispose_Option[] = {
- { "Background", "BackgroundDispose", BackgroundDispose },
- { "None", "NoneDispose", NoneDispose },
- { "Previous", "PreviousDispose", PreviousDispose },
- { "Undefined", "UndefinedDispose", UndefinedDispose },
- { "0", "UndefinedDispose", UndefinedDispose },
- { "1", "NoneDispose", NoneDispose },
- { "2", "BackgroundDispose", BackgroundDispose },
- { "3", "PreviousDispose", PreviousDispose },
- };
-#define N_DISPOSE_OPTIONS (sizeof(Dispose_Option)/sizeof(Dispose_Option[0]))
-#endif
+ { "Background", "BackgroundDispose", BackgroundDispose},
+ { "None", "NoneDispose", NoneDispose},
+ { "Previous", "PreviousDispose", PreviousDispose},
+ { "Undefined", "UndefinedDispose", UndefinedDispose},
+ { "0", "UndefinedDispose", UndefinedDispose},
+ { "1", "NoneDispose", NoneDispose},
+ { "2", "BackgroundDispose", BackgroundDispose},
+ { "3", "PreviousDispose", PreviousDispose},
+};
+#define N_DISPOSE_OPTIONS (int)(sizeof(Dispose_Option)/sizeof(Dispose_Option[0]))
VALUE
Info_dispose(VALUE self)
{
-#if defined(HAVE_SETIMAGEOPTION)
Info *info;
- unsigned int x;
+ int x;
ID dispose_id;
const char *dispose;
Data_Get_Struct(self, Info, info);
@@ -664,29 +741,24 @@
}
}
}
return rb_const_get(Module_Magick, dispose_id);
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}
/*
Method: Info#dispose=
Purpose: Convert a DisposeType enumerator into the equivalent
dispose option string
*/
VALUE
Info_dispose_eq(VALUE self, VALUE disp)
{
-#if defined(HAVE_SETIMAGEOPTION)
Info *info;
DisposeType dispose;
char *option;
- unsigned int x;
+ int x;
Data_Get_Struct(self, Info, info);
if (NIL_P(disp))
{
@@ -695,31 +767,25 @@
}
VALUE_TO_ENUM(disp, dispose, DisposeType);
option = "Undefined";
- for(x = 0; x < N_DISPOSE_OPTIONS; x++)
+ for (x = 0; x < N_DISPOSE_OPTIONS; x++)
{
if (dispose == Dispose_Option[x].enumerator)
{
option = Dispose_Option[x].string;
break;
}
}
(void) SetImageOption(info, "dispose", option);
return self;
-
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}
DEF_ATTR_ACCESSOR(Info, dither, bool)
-#ifdef HAVE_IMAGE_EXTRACT_INFO
/*
Method: aString=Info#extract
Info#extract=aString
Purpose: Get/set the extract string, e.g. "200x200+100+100"
@@ -743,105 +809,23 @@
info->extract = NULL;
return self;
}
extract = rb_funcall(extract_arg, rm_ID_to_s, 0);
- extr = STRING_PTR(extract);
+ extr = StringValuePtr(extract);
if (!IsGeometry(extr))
{
rb_raise(rb_eArgError, "invalid extract geometry: %s", extr);
}
magick_clone_string(&info->extract, extr);
return self;
}
-/*
- Method: aString=Info#tile
- Info#tile=aString
- Purpose: Get/set the "tile" string, e.g. "200x200+100+100"
- Raise: ArgumentError
- Notes: defined for IM 5.5.6 and later. Actually these are effectively
- aliases for extract & extract= but with warning messages.
-*/
-VALUE
-Info_tile(VALUE self)
-{
- rb_warning("RMagick: tile is deprecated in this release of ImageMagick. Use extract instead.");
- return Info_extract(self);
-}
-VALUE
-Info_tile_eq(VALUE self, VALUE tile)
-{
- rb_warning("RMagick: tile= is deprecated in this release of ImageMagick. Use extract= instead.");
- return Info_extract_eq(self, tile);
-}
-
-#else
-
/*
- Method: aString=Info#extract
- Info#extract=aString
- Purpose: Get/set the extract string, e.g. "200x200+100+100"
- Raise: ArgumentError
- Notes: defined for IM 5.5.6 and later
-*/
-VALUE
-Info_extract(VALUE self)
-{
- rm_not_implemented();
- return (VALUE)0;
-}
-VALUE
-Info_extract_eq(VALUE self, VALUE extr)
-{
- rm_not_implemented();
- return (VALUE)0;
-}
-
-/*
- Method: aString = Info#tile
- Info#tile=aString
- Purpose: Get/set the tile string, e.g. "200x200+100+100"
- Raise: ArgumentError
- Notes: defined for IM 5.5.5 and earlier, before the tile field was
- deprecated and replaced by extract
-*/
-DEF_ATTR_READER(Info, tile, str)
-
-VALUE
-Info_tile_eq(VALUE self, VALUE tile_arg)
-{
- Info *info;
- char *til;
- volatile VALUE tile;
-
- Data_Get_Struct(self, Info, info);
-
- if (NIL_P(tile_arg))
- {
- magick_free(info->tile);
- info->tile = NULL;
- return self;
- }
-
- tile = rb_funcall(tile_arg, rm_ID_to_s, 0);
- til = STRING_PTR(tile);
- if (!IsGeometry(til))
- {
- rb_raise(rb_eArgError, "invalid tile geometry: %s", til);
- }
-
- magick_clone_string(&info->tile, til);
-
- return self;
-}
-#endif
-
-/*
Methods: aString=Info#filename
Info#filename=aString
Purpose: Get/set the "filename"
Notes: Only used for Image#capture
Returns "" if filename not set
@@ -862,67 +846,43 @@
char *fname;
Data_Get_Struct(self, Info, info);
// Allow "nil" - remove current filename
- if (NIL_P(filename) || STRING_PTR(filename) == NULL)
+ if (NIL_P(filename) || StringValuePtr(filename) == NULL)
{
info->filename[0] = '\0';
}
else
{
// Otherwise copy in filename
- fname = STRING_PTR(filename);
+ fname = StringValuePtr(filename);
strncpy(info->filename, fname, MaxTextExtent);
}
return self;
}
/*
Method: Info#fill
- Purpose: return the fill (a.k.a pen) color as a String
- Note: Compare with Image#fill!
+ Purpose: return the fill color as a String
*/
VALUE
Info_fill(VALUE self)
{
-#if defined(HAVE_SETIMAGEOPTION)
- Info *info;
- const char *fill;
-
- Data_Get_Struct(self, Info, info);
- fill = GetImageOption(info, "fill");
- return fill ? rb_str_new2(fill) : Qnil;
-#else
- Info *info;
-
- Data_Get_Struct(self, Info, info);
- return PixelPacket_to_Color_Name_Info(info, &info->pen);
-#endif
+ return get_option(self, "fill");
}
/*
Method: Info#fill=<aString>
- Purpose: set the fill (a.k.a. pen) color
+ Purpose: set the fill color
Raises: ArgumentError
*/
VALUE
Info_fill_eq(VALUE self, VALUE color)
{
- Info *info;
-
- Data_Get_Struct(self, Info, info);
- Color_to_PixelPacket(&info->pen, color);
-
-#if defined(HAVE_SETIMAGEOPTION)
- // Color_to_PixelPacket will raise an exception if `color' isn't a real color.
- (void) RemoveImageOption(info, "fill");
- (void) SetImageOption(info, "fill", STRING_PTR(color));
-#endif
-
- return self;
+ return set_color_option(self, "fill", color);
}
/*
Methods: aString=Info#font
@@ -936,18 +896,18 @@
{
Info *info;
char *font;
Data_Get_Struct(self, Info, info);
- if (NIL_P(font_arg) || STRING_PTR(font_arg) == NULL)
+ if (NIL_P(font_arg) || StringValuePtr(font_arg) == NULL)
{
magick_free(info->font);
info->font = NULL;
}
else
{
- font = STRING_PTR(font_arg);
+ font = StringValuePtr(font_arg);
magick_clone_string(&info->font, font);
}
return self;
}
@@ -988,11 +948,11 @@
Data_Get_Struct(self, Info, info);
GetExceptionInfo(&exception);
- mgk = STRING_PTR(magick);
+ mgk = StringValuePtr(magick);
m = GetMagickInfo(mgk, &exception);
CHECK_EXCEPTION()
(void) DestroyExceptionInfo(&exception);
if (!m)
@@ -1023,37 +983,34 @@
/*
Method: Info#gravity
Purpose: Return the value of the gravity option as a GravityType enumerator
*/
-#if defined(HAVE_SETIMAGEOPTION)
static struct
{
char *string;
char *enum_name;
GravityType enumerator;
} Gravity_Option[] = {
- { "Undefined", "UndefinedGravity", UndefinedGravity },
- { "None", "UndefinedGravity", UndefinedGravity },
- { "Center", "CenterGravity", CenterGravity },
+ { "Undefined", "UndefinedGravity", UndefinedGravity},
+ { "None", "UndefinedGravity", UndefinedGravity},
+ { "Center", "CenterGravity", CenterGravity},
{ "East", "EastGravity", EastGravity},
- { "Forget", "ForgetGravity", ForgetGravity },
- { "NorthEast", "NorthEastGravity", NorthEastGravity },
- { "North", "NorthGravity", NorthGravity },
- { "NorthWest", "NorthWestGravity", NorthWestGravity },
- { "SouthEast", "SouthEastGravity", SouthEastGravity },
- { "South", "SouthGravity", SouthGravity },
- { "SouthWest", "SouthWestGravity", SouthWestGravity },
- { "West", "WestGravity", WestGravity },
- { "Static", "StaticGravity", StaticGravity }
- };
-#define N_GRAVITY_OPTIONS (sizeof(Gravity_Option)/sizeof(Gravity_Option[0]))
-#endif
+ { "Forget", "ForgetGravity", ForgetGravity},
+ { "NorthEast", "NorthEastGravity", NorthEastGravity},
+ { "North", "NorthGravity", NorthGravity},
+ { "NorthWest", "NorthWestGravity", NorthWestGravity},
+ { "SouthEast", "SouthEastGravity", SouthEastGravity},
+ { "South", "SouthGravity", SouthGravity},
+ { "SouthWest", "SouthWestGravity", SouthWestGravity},
+ { "West", "WestGravity", WestGravity},
+ { "Static", "StaticGravity", StaticGravity}
+};
+#define N_GRAVITY_OPTIONS (int)(sizeof(Gravity_Option)/sizeof(Gravity_Option[0]))
VALUE Info_gravity(VALUE self)
{
-#if defined(HAVE_SETIMAGEOPTION)
Info *info;
const char *gravity;
int x;
ID gravity_id;
@@ -1074,26 +1031,20 @@
}
}
}
return rb_const_get(Module_Magick, gravity_id);
-
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}
/*
Method: Info#gravity=
Purpose: Convert a GravityType enum to a gravity option name and
store in the Info structure
*/
VALUE
Info_gravity_eq(VALUE self, VALUE grav)
{
-#if defined(HAVE_SETIMAGEOPTION)
Info *info;
GravityType gravity;
char *option;
int x;
@@ -1106,26 +1057,21 @@
}
VALUE_TO_ENUM(grav, gravity, GravityType);
option = "Undefined";
- for(x = 0; x < N_GRAVITY_OPTIONS; x++)
+ for (x = 0; x < N_GRAVITY_OPTIONS; x++)
{
if (gravity == Gravity_Option[x].enumerator)
{
option = Gravity_Option[x].string;
break;
}
}
(void) SetImageOption(info, "gravity", option);
return self;
-
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}
DEF_ATTR_ACCESSOR(Info, group, long)
@@ -1224,11 +1170,10 @@
Notes: See Image_monitor_eq
*/
VALUE
Info_monitor_eq(VALUE self, VALUE monitor)
{
-#if defined(HAVE_SETIMAGEPROGRESSMONITOR)
Info *info;
Data_Get_Struct(self, Info, info);
if (NIL_P(monitor))
@@ -1240,59 +1185,30 @@
(void) SetImageInfoProgressMonitor(info, rm_progress_monitor, (void *)monitor);
}
return self;
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}
DEF_ATTR_ACCESSOR(Info, monochrome, bool)
-#ifdef HAVE_IMAGEINFO_NUMBER_SCENES
DEF_ATTR_ACCESSOR(Info, number_scenes, ulong)
-#else
/*
- Methods: num = Info#number_scenes
- Info#number_scenes = num
- Purpose: alias for subrange when IM < 5.5.6
-*/
-VALUE
-Info_number_scenes(VALUE self)
-{
- return Info_subrange(self);
-}
-
-VALUE
-Info_number_scenes_eq(VALUE self, VALUE nscenes)
-{
- return Info_subrange_eq(self, nscenes);
-}
-#endif
-
-/*
Method: Info#orientation
Purpose: Return the orientation attribute as an OrientationType enum value.
*/
VALUE
Info_orientation(VALUE self)
{
-#if defined(HAVE_IMAGEINFO_ORIENTATION)
Info *info;
Data_Get_Struct(self, Info, info);
return OrientationType_new(info->orientation);
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}
/*
Method: Info#Orientation=
@@ -1300,43 +1216,32 @@
Raises: ArgumentError
*/
VALUE
Info_orientation_eq(VALUE self, VALUE inter)
{
-#if defined(HAVE_IMAGEINFO_ORIENTATION)
Info *info;
Data_Get_Struct(self, Info, info);
VALUE_TO_ENUM(inter, info->orientation, OrientationType);
return self;
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}
/*
Method: Info#origin
Purpose: Return origin geometry
*/
VALUE
Info_origin(VALUE self)
{
-#if defined(HAVE_SETIMAGEOPTION)
Info *info;
const char *origin;
Data_Get_Struct(self, Info, info);
origin = GetImageOption(info, "origin");
return origin ? rb_str_new2(origin) : Qnil;
-
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}
/*
Method: Info#origin=+-x+-y
@@ -1344,11 +1249,10 @@
as a geometry string.
*/
VALUE
Info_origin_eq(VALUE self, VALUE origin_arg)
{
-#if defined(HAVE_SETIMAGEOPTION)
Info *info;
volatile VALUE origin_str;
char *origin;
Data_Get_Struct(self, Info, info);
@@ -1358,39 +1262,30 @@
(void) RemoveImageOption(info, "origin");
return self;
}
origin_str = rb_funcall(origin_arg, rm_ID_to_s, 0);
- origin = GetPageGeometry(STRING_PTR(origin_str));
+ origin = GetPageGeometry(StringValuePtr(origin_str));
if (IsGeometry(origin) == MagickFalse)
{
rb_raise(rb_eArgError, "invalid origin geometry: %s", origin);
}
(void) SetImageOption(info, "origin", origin);
return self;
-
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}
VALUE
Info_page(VALUE self)
{
Info *info;
const char *page;
Data_Get_Struct(self, Info, info);
-#if defined(HAVE_SETIMAGEOPTION)
page = GetImageOption(info, "page");
-#else
- page = (const char *)info->page;
-#endif
return page ? rb_str_new2(page) : Qnil;
}
/*
@@ -1410,21 +1305,19 @@
magick_free(info->page);
info->page = NULL;
return self;
}
geom_str = rb_funcall(page_arg, rm_ID_to_s, 0);
- geometry=GetPageGeometry(STRING_PTR(geom_str));
+ geometry=GetPageGeometry(StringValuePtr(geom_str));
if (*geometry == '\0')
{
magick_free(info->page);
info->page = NULL;
return self;
}
magick_clone_string(&info->page, geometry);
-#if defined(HAVE_SETIMAGEOPTION)
- (void) SetImageOption(info, "page", STRING_PTR(geom_str));
-#endif
+ (void) SetImageOption(info, "page", StringValuePtr(geom_str));
return self;
}
DEF_ATTR_ACCESSOR(Info, pointsize, dbl)
@@ -1460,11 +1353,11 @@
Data_Get_Struct(self, Info, info);
if (!NIL_P(sampling_factor))
{
- sampling_factor_p = STRING_PTR_LEN(sampling_factor, sampling_factor_len);
+ sampling_factor_p = rb_str2cstr(sampling_factor, &sampling_factor_len);
}
if (info->sampling_factor)
{
magick_free(info->sampling_factor);
@@ -1476,91 +1369,11 @@
}
return self;
}
-#ifdef HAVE_IMAGEINFO_NUMBER_SCENES
-
-// Info#scene, scene= is the IM >= 5.5.6 version of the now-deprecated
-// subimage accessors.
DEF_ATTR_ACCESSOR(Info, scene, ulong)
-
-/*
- Methods: num=Info#subimage
- Info#subimage=num
- Purpose: Get/set the "subimage" value, for IM >= 5.5.6
- Raises: ArgumentError
- Notes: synonyms for Info#scene, Info#scene=
-*/
-VALUE
-Info_subimage(VALUE self)
-{
- rb_warning("RMagick: subimage is deprecated in this release of ImageMagick. Use scene instead.");
- return Info_scene(self);
-}
-
-VALUE
-Info_subimage_eq(VALUE self, VALUE subimage)
-{
- rb_warning("RMagick: subimage= is deprecated in this release of ImageMagick. Use scene= instead.");
- return Info_scene_eq(self, subimage);
-}
-
-/*
- Methods: num=Info#subrange
- Info#subrange=num
- Purpose: Get/set the "subrange" value, for IM >= 5.5.6
- Raises: ArgumentError
- Notes: synonyms for Info#number_scenes, Info#number_scenes=
-*/
-VALUE
-Info_subrange(VALUE self)
-{
- rb_warning("RMagick: subrange is deprecated in this release of ImageMagick. Use number_scenes instead.");
- return Info_number_scenes(self);
-}
-
-VALUE
-Info_subrange_eq(VALUE self, VALUE subrange)
-{
- rb_warning("RMagick: subrange= is deprecated in this release of ImageMagick. Use number_scenes= instead.");
- return Info_number_scenes_eq(self, subrange);
-}
-
-#else
-
-/*
- Methods: num=Info#scene
- Info#scene=num
- Purpose: Get/set the scene number, for IM < 5.5.6
- Raises: ArgumentError
- Notes: synonyms for Info#subimage, Info#subimage=
-*/
-VALUE
-Info_scene(VALUE self)
-{
- Info *info;
-
- Data_Get_Struct(self, Info, info);
- return UINT2NUM(info->subimage);
-}
-
-VALUE
-Info_scene_eq(VALUE self, VALUE scene)
-{
- Info *info;
-
- Data_Get_Struct(self, Info, info);
- info->subimage = NUM2ULONG(scene);
- return self;
-}
-
-DEF_ATTR_ACCESSOR(Info, subimage, ulong)
-DEF_ATTR_ACCESSOR(Info, subrange, ulong)
-
-#endif
-
DEF_ATTR_READER(Info, server_name, str)
/*
Method: Info#server_name=<aString>
Purpose: Set the server name
@@ -1570,18 +1383,18 @@
{
Info *info;
char *server;
Data_Get_Struct(self, Info, info);
- if (NIL_P(server_arg) || STRING_PTR(server_arg) == NULL)
+ if (NIL_P(server_arg) || StringValuePtr(server_arg) == NULL)
{
magick_free(info->server_name);
info->server_name = NULL;
}
else
{
- server = STRING_PTR(server_arg);
+ server = StringValuePtr(server_arg);
magick_clone_string(&info->server_name, server);
}
return self;
}
@@ -1608,11 +1421,11 @@
info->size = NULL;
return self;
}
size = rb_funcall(size_arg, rm_ID_to_s, 0);
- sz = STRING_PTR(size);
+ sz = StringValuePtr(size);
if (!IsGeometry(sz))
{
rb_raise(rb_eArgError, "invalid size geometry: %s", sz);
}
@@ -1621,10 +1434,56 @@
return self;
}
/*
+ Method: Info#stroke
+ Purpose: return the stroke color as a String
+*/
+VALUE
+Info_stroke(VALUE self)
+{
+ return get_option(self, "stroke");
+}
+
+/*
+ Method: Info#stroke=<aString>
+ Purpose: set the stroke color
+ Raises: ArgumentError
+*/
+VALUE
+Info_stroke_eq(VALUE self, VALUE color)
+{
+ return set_color_option(self, "stroke", color);
+}
+
+
+/*
+ Method: Info#stroke_width
+ Purpose: Support for caption: format
+ Notes: Supported >= 6.3.2-6
+*/
+VALUE
+Info_stroke_width(VALUE self)
+{
+ return get_dbl_option(self, "strokewidth");
+}
+
+
+/*
+ Method: Info#stroke_width=
+ Purpose: Support for caption: format
+ Notes: Supported >= 6.3.2-6
+*/
+VALUE
+Info_stroke_width_eq(VALUE self, VALUE stroke_width)
+{
+ return set_dbl_option(self, "strokewidth", stroke_width);
+}
+
+
+/*
Method: Image::Info#texture=texture_image
Purpose: Set name of texture to tile onto the image background
*/
VALUE
Info_texture_eq(VALUE self, VALUE texture)
@@ -1648,35 +1507,83 @@
{
return self;
}
// Create a temp copy of the texture and store its name in the texture field
- Data_Get_Struct(texture, Image, image);
+ image = rm_check_destroyed(texture);
rm_write_temp_image(image, name);
magick_clone_string(&info->texture, name);
return self;
}
/*
+ Method: Image::Info#tile_offset= geometry
+ Purpose: info.tile_offset = [+/-]x[+/-]y
+*/
+VALUE
+Info_tile_offset_eq(VALUE self, VALUE offset)
+{
+ Info *info;
+ volatile VALUE offset_str;
+ char *tile_offset;
+
+ offset_str = rb_funcall(offset, rm_ID_to_s, 0);
+ tile_offset = StringValuePtr(offset_str);
+ if (!IsGeometry(tile_offset))
+ {
+ rb_raise(rb_eArgError, "invalid tile offset geometry: %s", tile_offset);
+ }
+
+ Data_Get_Struct(self, Info, info);
+
+ (void) DeleteImageOption(info, "tile-offset");
+ (void) SetImageOption(info, "tile-offset", tile_offset);
+ return self;
+}
+
+
+/*
+ Method: Image::Info#tile_offset
+ Purpose: returns tile_offset attribute values
+*/
+VALUE
+Info_tile_offset(VALUE self)
+{
+ Info *info;
+ const char *tile_offset;
+
+ Data_Get_Struct(self, Info, info);
+
+ tile_offset = GetImageOption(info, "tile-offset");
+
+ if (!tile_offset)
+ {
+ return Qnil;
+ }
+
+ return rb_str_new2(tile_offset);
+}
+
+
+/*
Method: Info#undefine
Purpose: Undefine image option
*/
VALUE
Info_undefine(VALUE self, VALUE format, VALUE key)
{
-#if defined(HAVE_SETIMAGEOPTION)
Info *info;
char *format_p, *key_p;
long format_l, key_l;
char fkey[MaxTextExtent];
- format_p = STRING_PTR_LEN(format, format_l);
- key_p = STRING_PTR_LEN(key, key_l);
+ format_p = rb_str2cstr(format, &format_l);
+ key_p = rb_str2cstr(key, &key_l);
if (format_l > MAX_FORMAT_LEN || format_l + key_l > MaxTextExtent)
{
rb_raise(rb_eArgError, "can't undefine %.60s:%.1024s - too long", format_p, key_p);
}
@@ -1685,41 +1592,34 @@
Data_Get_Struct(self, Info, info);
/* Depending on the IM version, RemoveImageOption returns either */
/* char * or MagickBooleanType. Ignore the return value. */
(void) RemoveImageOption(info, fkey);
+
return self;
+}
-#elif defined(HAVE_ADDDEFINITIONS)
- Info *info;
- unsigned int okay;
- char *format_p, *key_p;
- long format_l, key_l;
- char fkey[MaxTextExtent];
- format_p = STRING_PTR_LEN(format, format_l);
- key_p = STRING_PTR_LEN(key, key_l);
+/*
+ Method: Info#undercolor
+ Purpose: return the undercolor color as a String
+*/
+VALUE
+Info_undercolor(VALUE self)
+{
+ return get_option(self, "undercolor");
+}
- if (format_l > MAX_FORMAT_LEN || format_l + key_l > MaxTextExtent)
- {
- rb_raise(rb_eArgError, "can't undefine %.60s:%.1024s - too long", format_p, key_p);
- }
-
- sprintf(fkey, "%.60s:%.*s", format_p, MaxTextExtent-61, key_p);
-
- Data_Get_Struct(self, Info, info);
- okay = RemoveDefinitions(info, fkey);
- if (!okay)
- {
- rb_raise(rb_eArgError, "no such key: `%s'", fkey);
- }
- return self;
-
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
+/*
+ Method: Info#undercolor=<aString>
+ Purpose: set the undercolor color
+ Raises: ArgumentError
+*/
+VALUE
+Info_undercolor_eq(VALUE self, VALUE color)
+{
+ return set_color_option(self, "undercolor", color);
}
/*
Method: Info#units
Purpose: Get the resolution type
@@ -1760,18 +1660,18 @@
Info *info;
char *view;
Data_Get_Struct(self, Info, info);
- if (NIL_P(view_arg) || STRING_PTR(view_arg) == NULL)
+ if (NIL_P(view_arg) || StringValuePtr(view_arg) == NULL)
{
- magick_free(info->view);
- info->view = NULL;
+ magick_free(info->view);
+ info->view = NULL;
}
else
{
- view = STRING_PTR(view_arg);
+ view = StringValuePtr(view_arg);
magick_clone_string(&info->view, view);
}
return self;
}
@@ -1794,44 +1694,12 @@
}
(void) DestroyImageInfo(info);
}
-/*
- Method: Info.new
- Purpose: Create an Info object by calling CloneInfo
-*/
-#if !defined(HAVE_RB_DEFINE_ALLOC_FUNC)
-VALUE
-Info_new(VALUE class)
-{
- Info *info;
- volatile VALUE new_obj;
- info = CloneImageInfo(NULL);
- if (!info)
- {
- rb_raise(rb_eNoMemError, "not enough memory to initialize Info object");
- }
- new_obj = Data_Wrap_Struct(class, NULL, destroy_Info, info);
- rb_obj_call_init(new_obj, 0, NULL);
- return new_obj;
-}
-
/*
- Extern: rm_info_new
- Purpose: provide a Info.new method for internal use
- Notes: takes no parameters, but runs the parm block if present
-*/
-VALUE
-rm_info_new()
-{
- return Info_new(Class_Info);
-}
-#else
-
-/*
Extern: Info_alloc
Purpose: Create an ImageInfo object
*/
VALUE
Info_alloc(VALUE class)
@@ -1845,25 +1713,27 @@
rb_raise(rb_eNoMemError, "not enough memory to initialize Info object");
}
info_obj = Data_Wrap_Struct(class, NULL, destroy_Info, info);
return info_obj;
}
+
+
/*
Extern: rm_info_new
Purpose: provide a Info.new method for internal use
Notes: takes no parameters, but runs the parm block if present
*/
VALUE
-rm_info_new(void)
+rm_info_new()
{
volatile VALUE info_obj;
info_obj = Info_alloc(Class_Info);
return Info_initialize(info_obj);
}
-#endif
+
/*
Method: Info#initialize
Purpose: If an initializer block is present, run it.
*/
VALUE
@@ -1873,63 +1743,7 @@
{
// Run the block in self's context
(void) rb_obj_instance_eval(0, NULL, self);
}
return self;
-}
-
-
-/*
- Method: Info#get_option
- Purpose: Return the value of the specified option
-*/
-static VALUE
-get_option(VALUE self, char *key)
-{
-#if defined(HAVE_SETIMAGEOPTION)
- Info *info;
- const char *value;
-
- Data_Get_Struct(self, Info, info);
-
- value = GetImageOption(info, key);
- if (value)
- {
- return rb_str_new2(value);
- }
- return Qnil;
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
-}
-
-/*
- Method: Info#set_option
- Purpose: Set the specified option to this value.
- If the value is nil just unset any current value
-*/
-static VALUE
-set_option(VALUE self, char *key, VALUE string)
-{
-#if defined(HAVE_SETIMAGEOPTION)
- Info *info;
- char *value;
-
- Data_Get_Struct(self, Info, info);
-
- if (NIL_P(string))
- {
- (void) RemoveImageOption(info, key);
- }
- else
- {
- value = STRING_PTR(string);
- (void) SetImageOption(info, key, value);
- }
- return self;
-#else
- rm_not_implemented();
- return (VALUE)0;
-#endif
}