rmagick 1.7.4 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rmagick might be problematic. Click here for more details.

Files changed (130) hide show
  1. data/ChangeLog +10 -2
  2. data/README.html +284 -290
  3. data/README.txt +298 -307
  4. data/configure +180 -11
  5. data/configure.ac +18 -2
  6. data/doc/comtasks.html +1 -1
  7. data/doc/constants.html +15 -10
  8. data/doc/css/ref.css +67 -0
  9. data/doc/draw.html +1 -1
  10. data/doc/ex/InitialCoords.rb +24 -0
  11. data/doc/ex/NewCoordSys.rb +33 -0
  12. data/doc/ex/OrigCoordSys.rb +19 -0
  13. data/doc/ex/PreserveAspectRatio.rb +206 -0
  14. data/doc/ex/RotateScale.rb +38 -0
  15. data/doc/ex/Skew.rb +39 -0
  16. data/doc/ex/Use01.rb +17 -0
  17. data/doc/ex/Use02.rb +22 -0
  18. data/doc/ex/Use03.rb +17 -0
  19. data/doc/ex/ViewBox.rb +34 -0
  20. data/doc/ex/arcs01.rb +29 -0
  21. data/doc/ex/arcs02.rb +62 -0
  22. data/doc/ex/baseline_shift01.rb +19 -0
  23. data/doc/ex/bounding_box.rb +31 -37
  24. data/doc/ex/circle01.rb +18 -0
  25. data/doc/ex/cubic01.rb +46 -0
  26. data/doc/ex/cubic02.rb +95 -0
  27. data/doc/ex/drop_shadow.rb +1 -1
  28. data/doc/ex/ellipse01.rb +23 -0
  29. data/doc/ex/evenodd.rb +44 -0
  30. data/doc/ex/font_styles.rb +29 -0
  31. data/doc/ex/group.rb +27 -0
  32. data/doc/ex/image.rb +47 -0
  33. data/doc/ex/images/big-duck.gif +0 -0
  34. data/doc/ex/images/duck.gif +0 -0
  35. data/doc/ex/images/duck0.gif +0 -0
  36. data/doc/ex/images/duck1.gif +0 -0
  37. data/doc/ex/images/duck10.gif +0 -0
  38. data/doc/ex/images/duck11.gif +0 -0
  39. data/doc/ex/images/duck12.gif +0 -0
  40. data/doc/ex/images/duck13.gif +0 -0
  41. data/doc/ex/images/duck14.gif +0 -0
  42. data/doc/ex/images/duck15.gif +0 -0
  43. data/doc/ex/images/duck2.gif +0 -0
  44. data/doc/ex/images/duck3.gif +0 -0
  45. data/doc/ex/images/duck4.gif +0 -0
  46. data/doc/ex/images/duck5.gif +0 -0
  47. data/doc/ex/images/duck6.gif +0 -0
  48. data/doc/ex/images/duck7.gif +0 -0
  49. data/doc/ex/images/duck8.gif +0 -0
  50. data/doc/ex/images/duck9.gif +0 -0
  51. data/doc/ex/line01.rb +24 -0
  52. data/doc/ex/nested_rvg.rb +22 -0
  53. data/doc/ex/nonzero.rb +44 -0
  54. data/doc/ex/polygon01.rb +24 -0
  55. data/doc/ex/polyline01.rb +24 -0
  56. data/doc/ex/quad01.rb +37 -0
  57. data/doc/ex/rect01.rb +16 -0
  58. data/doc/ex/rect02.rb +23 -0
  59. data/doc/ex/rvg_clippath.rb +15 -0
  60. data/doc/ex/rvg_linecap.rb +44 -0
  61. data/doc/ex/rvg_linejoin.rb +42 -0
  62. data/doc/ex/rvg_opacity.rb +20 -0
  63. data/doc/ex/rvg_pattern.rb +27 -0
  64. data/doc/ex/rvg_stroke_dasharray.rb +13 -0
  65. data/doc/ex/sepiatone.rb +15 -0
  66. data/doc/ex/shadow.rb +37 -0
  67. data/doc/ex/smile.rb +9 -9
  68. data/doc/ex/stroke_fill.rb +12 -0
  69. data/doc/ex/text01.rb +18 -0
  70. data/doc/ex/text_styles.rb +22 -0
  71. data/doc/ex/texture_fill_to_border.rb +3 -3
  72. data/doc/ex/texture_floodfill.rb +3 -2
  73. data/doc/ex/tref01.rb +26 -0
  74. data/doc/ex/triangle01.rb +17 -0
  75. data/doc/ex/tspan01.rb +19 -0
  76. data/doc/ex/tspan02.rb +20 -0
  77. data/doc/ex/tspan03.rb +22 -0
  78. data/doc/ex/writing_mode01.rb +28 -0
  79. data/doc/ex/writing_mode02.rb +27 -0
  80. data/doc/ilist.html +1 -1
  81. data/doc/image1.html +66 -30
  82. data/doc/image2.html +1 -1
  83. data/doc/image3.html +274 -49
  84. data/doc/imageattrs.html +87 -10
  85. data/doc/imusage.html +1 -1
  86. data/doc/index.html +80 -39
  87. data/doc/info.html +149 -13
  88. data/doc/magick.html +1 -1
  89. data/doc/rvg.html +890 -0
  90. data/doc/rvgclip.html +249 -0
  91. data/doc/rvggroup.html +305 -0
  92. data/doc/rvgimage.html +288 -0
  93. data/doc/rvgpattern.html +456 -0
  94. data/doc/rvgshape.html +376 -0
  95. data/doc/rvgstyle.html +269 -0
  96. data/doc/rvgtext.html +464 -0
  97. data/doc/rvgtspan.html +237 -0
  98. data/doc/rvgtut.html +512 -0
  99. data/doc/rvguse.html +145 -0
  100. data/doc/rvgxform.html +294 -0
  101. data/doc/struct.html +9 -71
  102. data/doc/usage.html +22 -7
  103. data/ext/RMagick/MANIFEST +94 -2
  104. data/ext/RMagick/rmagick.h +10 -4
  105. data/ext/RMagick/rmagick_config.h.in +8 -2
  106. data/ext/RMagick/rmdraw.c +2 -2
  107. data/ext/RMagick/rmfill.c +2 -2
  108. data/ext/RMagick/rmilist.c +3 -3
  109. data/ext/RMagick/rmimage.c +152 -5
  110. data/ext/RMagick/rminfo.c +208 -2
  111. data/ext/RMagick/rmmain.c +14 -5
  112. data/ext/RMagick/rmutil.c +83 -22
  113. data/lib/RMagick.rb +2 -2
  114. data/lib/rvg/clippath.rb +46 -0
  115. data/lib/rvg/container.rb +129 -0
  116. data/lib/rvg/deep_equal.rb +54 -0
  117. data/lib/rvg/describable.rb +51 -0
  118. data/lib/rvg/embellishable.rb +395 -0
  119. data/lib/rvg/misc.rb +729 -0
  120. data/lib/rvg/paint.rb +48 -0
  121. data/lib/rvg/pathdata.rb +129 -0
  122. data/lib/rvg/rvg.rb +279 -0
  123. data/lib/rvg/stretchable.rb +150 -0
  124. data/lib/rvg/stylable.rb +116 -0
  125. data/lib/rvg/text.rb +185 -0
  126. data/lib/rvg/transformable.rb +131 -0
  127. data/lib/rvg/units.rb +64 -0
  128. data/rmagick.gemspec +1 -1
  129. data/uninstall.rb +3 -2
  130. metadata +96 -3
@@ -1,6 +1,6 @@
1
- /* $Id: rminfo.c,v 1.22 2004/08/18 23:22:36 rmagick Exp $ */
1
+ /* $Id: rminfo.c,v 1.28 2005/04/30 23:01:13 rmagick Exp $ */
2
2
  /*============================================================================\
3
- | Copyright (C) 2004 by Timothy P. Hunter
3
+ | Copyright (C) 2005 by Timothy P. Hunter
4
4
  | Name: rminfo.c
5
5
  | Author: Tim Hunter
6
6
  | Purpose: Info class method definitions for RMagick.
@@ -10,6 +10,148 @@
10
10
 
11
11
  DEF_ATTR_ACCESSOR(Info, antialias, bool)
12
12
 
13
+ /*
14
+ * Method: value = Info[format, key]
15
+ * Purpose: get the value of an option set by Info[]=
16
+ */
17
+ #define MAX_FORMAT_LEN 60
18
+
19
+ VALUE
20
+ Info_aref(VALUE self, VALUE format, VALUE key)
21
+ {
22
+ #if defined(HAVE_SETIMAGEOPTION)
23
+ Info *info;
24
+ char *format_p, *key_p;
25
+ long format_l, key_l;
26
+ const char *value;
27
+ char fkey[MaxTextExtent];
28
+
29
+ format_p = STRING_PTR_LEN(format, format_l);
30
+ key_p = STRING_PTR_LEN(key, key_l);
31
+
32
+ if (format_l > MAX_FORMAT_LEN || format_l + key_l > MaxTextExtent-1)
33
+ {
34
+ rb_raise(rb_eArgError, "can't reference %.60s:%.1024s - too long", format_p, key_p);
35
+ }
36
+
37
+ sprintf(fkey, "%.60s:%.*s", STRING_PTR(format), (int)(MaxTextExtent-61), STRING_PTR(key));
38
+
39
+ Data_Get_Struct(self, Info, info);
40
+ value = GetImageOption(info, fkey);
41
+ if (!value)
42
+ {
43
+ return Qnil;
44
+ }
45
+
46
+ return rb_str_new2(value);
47
+
48
+ #elif defined(HAVE_ADDDEFINITIONS)
49
+ Info *info;
50
+ const char *value;
51
+
52
+ Data_Get_Struct(self, Info, info);
53
+ value = AccessDefinition(info, STRING_PTR(format), STRING_PTR(key));
54
+
55
+ if (!value)
56
+ {
57
+ return Qnil;
58
+ }
59
+
60
+ return rb_str_new2(value);
61
+ #else
62
+ rm_not_implemented();
63
+ return (VALUE)0;
64
+ #endif
65
+ }
66
+
67
+
68
+ /*
69
+ Method: Info[format, key] = value
70
+ Purpose: Call AddDefinitions (GM) or SetImageOption (IM)
71
+ Note: Essentially the same function as Info#define but paired
72
+ with Info#[]=
73
+ */
74
+ VALUE
75
+ Info_aset(VALUE self, VALUE format, VALUE key, VALUE value)
76
+ {
77
+ #if defined(HAVE_SETIMAGEOPTION)
78
+ Info *info;
79
+ char *format_p, *key_p, *value_p = "";
80
+ long format_l, key_l;
81
+ char ckey[MaxTextExtent];
82
+ unsigned int okay;
83
+
84
+
85
+ Data_Get_Struct(self, Info, info);
86
+
87
+ format_p = STRING_PTR_LEN(format, format_l);
88
+ key_p = STRING_PTR_LEN(key, key_l);
89
+
90
+ /* Allow any argument that supports to_s */
91
+ value = rb_funcall(value, ID_to_s, 0);
92
+ value_p = STRING_PTR(value);
93
+
94
+ if (format_l > MAX_FORMAT_LEN || format_l+key_l > MaxTextExtent-1)
95
+ {
96
+ rb_raise(rb_eArgError, "%.60s:%.1024s not defined - too long", format_p, key_p);
97
+ }
98
+
99
+ (void) sprintf(ckey, "%.60s:%.*s", format_p, (int)(sizeof(ckey)-MAX_FORMAT_LEN), key_p);
100
+
101
+ okay = SetImageOption(info, ckey, value_p);
102
+ if (!okay)
103
+ {
104
+ rb_warn("%.60s:%.1024s not defined - SetImageOption failed.", format_p, key_p);
105
+ return Qnil;
106
+ }
107
+
108
+ return self;
109
+
110
+ #elif defined(HAVE_ADDDEFINITIONS)
111
+ Info *info;
112
+ char *format_p, *key_p, *value_p = NULL;
113
+ long format_l, key_l, value_l = 0;
114
+ unsigned int okay;
115
+ ExceptionInfo exception;
116
+ char definitions[MaxTextExtent*2];/* Make this buffer longer than the buffer used */
117
+ /* for SetImageOptions since AddDefinitions cats */
118
+ /* the value onto the format:key pair. */
119
+
120
+ Data_Get_Struct(self, Info, info);
121
+
122
+ format_p = STRING_PTR_LEN(format, format_l);
123
+ key_p = STRING_PTR_LEN(key, key_l);
124
+ value = rb_funcall(value, ID_to_s, 0);
125
+ value_p = STRING_PTR_LEN(value, value_l);
126
+
127
+ if ((3 + format_l + key_l + value_l) > sizeof(definitions))
128
+ {
129
+ rb_raise(rb_eArgError, "%.60s:%.1024s not defined - too long", format_p, key_p);
130
+ }
131
+ (void)sprintf(definitions, "%s:%s=", format_p, key_p);
132
+ if (value_l > 0)
133
+ {
134
+ strcat(definitions, value_p);
135
+ }
136
+
137
+ GetExceptionInfo(&exception);
138
+ okay = AddDefinitions(info, definitions, &exception);
139
+ HANDLE_ERROR
140
+ if (!okay)
141
+ {
142
+ rb_warn("%.60s:%.1024s not defined - AddDefinitions failed.", format_p, key_p);
143
+ return Qnil;
144
+ }
145
+
146
+ return self;
147
+
148
+ #else
149
+ rm_not_implemented();
150
+ return (VALUE)0;
151
+ #endif
152
+ }
153
+
154
+
13
155
  /*
14
156
  Method: Info#background_color
15
157
  Purpose: return the name of the background color as a String
@@ -230,6 +372,7 @@ Info_define(int argc, VALUE *argv, VALUE self)
230
372
  #endif
231
373
  }
232
374
 
375
+
233
376
  DEF_ATTR_READER(Info, density, str)
234
377
 
235
378
  /*
@@ -554,6 +697,7 @@ VALUE Info_fuzz_eq(VALUE self, VALUE fuzz)
554
697
  return self;
555
698
  }
556
699
 
700
+
557
701
  DEF_ATTR_ACCESSOR(Info, group, long)
558
702
 
559
703
  /*
@@ -845,6 +989,68 @@ Info_size_eq(VALUE self, VALUE size_arg)
845
989
  return self;
846
990
  }
847
991
 
992
+
993
+ /*
994
+ Method: Info#undefine
995
+ Purpose: Undefine image option
996
+ */
997
+
998
+ VALUE
999
+ Info_undefine(VALUE self, VALUE format, VALUE key)
1000
+ {
1001
+ #if defined(HAVE_SETIMAGEOPTION)
1002
+ Info *info;
1003
+ char *format_p, *key_p;
1004
+ long format_l, key_l;
1005
+ char fkey[MaxTextExtent];
1006
+
1007
+ format_p = STRING_PTR_LEN(format, format_l);
1008
+ key_p = STRING_PTR_LEN(key, key_l);
1009
+
1010
+ if (format_l > MAX_FORMAT_LEN || format_l + key_l > MaxTextExtent)
1011
+ {
1012
+ rb_raise(rb_eArgError, "can't undefine %.60s:%.1024s - too long", format_p, key_p);
1013
+ }
1014
+
1015
+ sprintf(fkey, "%.60s:%.*s", format_p, (int)(MaxTextExtent-61), key_p);
1016
+
1017
+ Data_Get_Struct(self, Info, info);
1018
+ /* Depending on the IM version, RemoveImageOption returns either */
1019
+ /* char * or MagickBooleanType. Ignore the return value. */
1020
+ (void) RemoveImageOption(info, fkey);
1021
+ return self;
1022
+
1023
+ #elif defined(HAVE_ADDDEFINITIONS)
1024
+ Info *info;
1025
+ unsigned int okay;
1026
+ char *format_p, *key_p;
1027
+ long format_l, key_l;
1028
+ char fkey[MaxTextExtent];
1029
+
1030
+ format_p = STRING_PTR_LEN(format, format_l);
1031
+ key_p = STRING_PTR_LEN(key, key_l);
1032
+
1033
+ if (format_l > MAX_FORMAT_LEN || format_l + key_l > MaxTextExtent)
1034
+ {
1035
+ rb_raise(rb_eArgError, "can't undefine %.60s:%.1024s - too long", format_p, key_p);
1036
+ }
1037
+
1038
+ sprintf(fkey, "%.60s:%.*s", format_p, MaxTextExtent-61, key_p);
1039
+
1040
+ Data_Get_Struct(self, Info, info);
1041
+ okay = RemoveDefinitions(info, fkey);
1042
+ if (!okay)
1043
+ {
1044
+ rb_raise(rb_eArgError, "no such key: `%s'", fkey);
1045
+ }
1046
+ return self;
1047
+
1048
+ #else
1049
+ rm_not_implemented();
1050
+ return (VALUE)0;
1051
+ #endif
1052
+ }
1053
+
848
1054
  /*
849
1055
  Method: Info#units
850
1056
  Purpose: Get the resolution type
@@ -1,6 +1,6 @@
1
- /* $Id: rmmain.c,v 1.74.2.3 2005/02/27 15:42:09 rmagick Exp $ */
1
+ /* $Id: rmmain.c,v 1.84 2005/04/30 23:01:39 rmagick Exp $ */
2
2
  /*============================================================================\
3
- | Copyright (C) 2004 by Timothy P. Hunter
3
+ | Copyright (C) 2005 by Timothy P. Hunter
4
4
  | Name: rmmain.c
5
5
  | Author: Tim Hunter
6
6
  | Purpose: Contains all module, class, method declarations.
@@ -731,13 +731,16 @@ Init_RMagick(void)
731
731
  rb_define_method(Class_Image, "scale", Image_scale, -1);
732
732
  rb_define_method(Class_Image, "scale!", Image_scale_bang, -1);
733
733
  rb_define_method(Class_Image, "segment", Image_segment, -1);
734
+ rb_define_method(Class_Image, "sepiatone", Image_sepiatone, -1);
734
735
  rb_define_method(Class_Image, "set_channel_depth", Image_set_channel_depth, 2);
735
736
  rb_define_method(Class_Image, "shade", Image_shade, -1);
737
+ rb_define_method(Class_Image, "shadow", Image_shadow, -1);
736
738
  rb_define_method(Class_Image, "sharpen", Image_sharpen, -1);
737
739
  rb_define_method(Class_Image, "sharpen_channel", Image_sharpen_channel, -1);
738
740
  rb_define_method(Class_Image, "shave", Image_shave, 2);
739
741
  rb_define_method(Class_Image, "shave!", Image_shave_bang, 2);
740
742
  rb_define_method(Class_Image, "shear", Image_shear, 2);
743
+ rb_define_method(Class_Image, "sigmoidal_contrast_channel", Image_sigmoidal_contrast_channel, -1);
741
744
  rb_define_method(Class_Image, "signature", Image_signature, 0);
742
745
  rb_define_method(Class_Image, "solarize", Image_solarize, -1);
743
746
  rb_define_method(Class_Image, "<=>", Image_spaceship, 1);
@@ -925,6 +928,9 @@ Init_RMagick(void)
925
928
  rb_define_method(Class_Info, "initialize", Info_initialize, 0);
926
929
  rb_define_method(Class_Info, "freeze", rm_no_freeze, 0);
927
930
  rb_define_method(Class_Info, "define", Info_define, -1);
931
+ rb_define_method(Class_Info, "[]=", Info_aset, 3);
932
+ rb_define_method(Class_Info, "[]", Info_aref, 2);
933
+ rb_define_method(Class_Info, "undefine", Info_undefine, 2);
928
934
 
929
935
  DCL_ATTR_ACCESSOR(Info, antialias)
930
936
  DCL_ATTR_ACCESSOR(Info, background_color)
@@ -1187,6 +1193,9 @@ Init_RMagick(void)
1187
1193
  ENUMERATOR(FaxCompression)
1188
1194
  ENUMERATOR(Group4Compression)
1189
1195
  ENUMERATOR(JPEGCompression)
1196
+ #if defined(HAVE_JPEG2000COMPRESSION)
1197
+ ENUMERATOR(JPEG2000Compression)
1198
+ #endif
1190
1199
  ENUMERATOR(LosslessJPEGCompression)
1191
1200
  ENUMERATOR(LZWCompression)
1192
1201
  ENUMERATOR(RunlengthEncodedCompression)
@@ -1441,7 +1450,7 @@ Init_RMagick(void)
1441
1450
 
1442
1451
 
1443
1452
  // Magick::Primary
1444
- Class_Primary = rb_struct_define(NULL, "x", "y", "z", 0);
1453
+ Class_Primary = rb_struct_define(NULL, "x", "y", "z", NULL);
1445
1454
  rb_define_method(Class_Primary, "to_s", PrimaryInfo_to_s, 0);
1446
1455
  rb_define_const(Module_Magick, "Primary", Class_Primary);
1447
1456
 
@@ -1498,14 +1507,14 @@ Init_RMagick(void)
1498
1507
  static void version_constants(void)
1499
1508
  {
1500
1509
  const char *mgk_version;
1501
- char long_version[300];
1510
+ char long_version[400];
1502
1511
 
1503
1512
  mgk_version = GetMagickVersion(NULL);
1504
1513
  rb_define_const(Module_Magick, "Magick_version", rb_str_new2(mgk_version));
1505
1514
 
1506
1515
  rb_define_const(Module_Magick, "Version", rb_str_new2(PACKAGE_STRING));
1507
1516
  sprintf(long_version,
1508
- "This is %s ($Date: 2005/02/27 15:42:09 $) Copyright (C) 2004 by Timothy P. Hunter\n"
1517
+ "This is %s ($Date: 2005/04/30 23:01:39 $) Copyright (C) 2005 by Timothy P. Hunter\n"
1509
1518
  "Built with %s\n"
1510
1519
  "Built for %s\n"
1511
1520
  "Web page: http://rmagick.rubyforge.org\n"
@@ -1,12 +1,13 @@
1
- /* $Id: rmutil.c,v 1.47.2.1 2005/01/11 23:00:56 rmagick Exp $ */
1
+ /* $Id: rmutil.c,v 1.51 2005/03/05 16:18:39 rmagick Exp $ */
2
2
  /*============================================================================\
3
- | Copyright (C) 2004 by Timothy P. Hunter
3
+ | Copyright (C) 2005 by Timothy P. Hunter
4
4
  | Name: rmutil.c
5
5
  | Author: Tim Hunter
6
6
  | Purpose: Utility functions for RMagick
7
7
  \============================================================================*/
8
8
 
9
9
  #include "rmagick.h"
10
+ #include <errno.h>
10
11
 
11
12
  static const char *Compliance_Const_Name(ComplianceType *);
12
13
  static const char *StyleType_Const_Name(StyleType);
@@ -168,21 +169,6 @@ rm_no_freeze(VALUE obj)
168
169
  }
169
170
 
170
171
 
171
- /*
172
- * Extern: rm_obj_to_s(obj)
173
- * Purpose: try to convert object to string by calling its `to_s' method
174
- * Notes: Usually run via rb_rescue so TypeError or NoMethodError can be
175
- * rescued. I use this instead of rb_str_to_str so that objects
176
- * that don't have `to_str' but do have `to_s' can be converted.
177
- */
178
- VALUE
179
- rm_obj_to_s(VALUE obj)
180
- {
181
- return TYPE(obj) == T_STRING ? obj : rb_funcall(obj, ID_to_s, 0);
182
- }
183
-
184
-
185
-
186
172
  /*
187
173
  * Static: arg_is_number
188
174
  * Purpose: Try to convert the argument to a double,
@@ -199,16 +185,74 @@ arg_is_number(VALUE arg)
199
185
 
200
186
 
201
187
  /*
202
- * Static: fuzz_arg_rescue
188
+ * Static: rescue_not_str
203
189
  * Purpose: called when `rb_str_to_str' raised an exception below
204
190
  */
205
191
  static VALUE
206
- fuzz_arg_rescue(VALUE arg)
192
+ rescue_not_str(VALUE arg)
207
193
  {
208
194
  rb_raise(rb_eArgError, "argument must be a number or a string in the form 'NN%' (%s given)",
209
195
  rb_class2name(CLASS_OF(arg)));
210
196
  }
211
197
 
198
+ /*
199
+ * Extern: rm_percentage(obj)
200
+ * Purpose: Return a double between 0.0 and 1.0, inclusive.
201
+ * If the argument is a number convert to a Float object,
202
+ * otherwise it's supposed to be a string in the form "NN%".
203
+ * Convert to a number and then to a Float.
204
+ */
205
+ double
206
+ rm_percentage(VALUE arg)
207
+ {
208
+ double pct;
209
+ long pct_long;
210
+ char *pct_str, *end;
211
+ int not_num;
212
+
213
+ // Try to convert the argument to a number. If failure, sets not_num to non-zero.
214
+ rb_protect(arg_is_number, arg, &not_num);
215
+
216
+ if (not_num)
217
+ {
218
+ arg = rb_rescue(rb_str_to_str, arg, rescue_not_str, arg);
219
+ pct_str = STRING_PTR(arg);
220
+ errno = 0;
221
+ pct_long = strtol(pct_str, &end, 10);
222
+ if (errno == ERANGE)
223
+ {
224
+ rb_raise(rb_eRangeError, "`%s' out of range", pct_str);
225
+ }
226
+ if (*end != '\0' && *end != '%')
227
+ {
228
+ rb_raise(rb_eArgError, "expected percentage, got `%s'", pct_str);
229
+ }
230
+
231
+ if (*end == '%' && pct_long != 0)
232
+ {
233
+ pct = ((double)pct_long) / 100.0;
234
+ }
235
+ else
236
+ {
237
+ pct = (double) pct_long;
238
+ }
239
+ if (pct < 0.0)
240
+ {
241
+ rb_raise(rb_eArgError, "percentages may not be negative (got `%s')", pct_str);
242
+ }
243
+ }
244
+ else
245
+ {
246
+ pct = NUM2DBL(arg);
247
+ if (pct < 0.0)
248
+ {
249
+ rb_raise(rb_eArgError, "percentages may not be negative (got `%g')", pct);
250
+ }
251
+ }
252
+
253
+ return pct;
254
+ }
255
+
212
256
 
213
257
  /*
214
258
  * Extern: rm_fuzz_to_dbl(obj)
@@ -230,12 +274,21 @@ rm_fuzz_to_dbl(VALUE fuzz_arg)
230
274
  if (not_num)
231
275
  {
232
276
  // Convert to string, issue error message if failure.
233
- fuzz_arg = rb_rescue(rb_str_to_str, fuzz_arg, fuzz_arg_rescue, fuzz_arg);
277
+ fuzz_arg = rb_rescue(rb_str_to_str, fuzz_arg, rescue_not_str, fuzz_arg);
234
278
  fuzz_str = STRING_PTR(fuzz_arg);
279
+ errno = 0;
235
280
  fuzz = strtod(fuzz_str, &end);
281
+ if (errno == ERANGE)
282
+ {
283
+ rb_raise(rb_eRangeError, "`%s' out of range", fuzz_str);
284
+ }
236
285
  if(*end == '%')
237
286
  {
238
- fuzz = (fuzz * MaxRGB) / 100;
287
+ if (fuzz < 0.0)
288
+ {
289
+ rb_raise(rb_eArgError, "percentages may not be negative (got `%s')", fuzz_arg);
290
+ }
291
+ fuzz = (fuzz * MaxRGB) / 100.0;
239
292
  }
240
293
  else if(*end != '\0')
241
294
  {
@@ -245,6 +298,10 @@ rm_fuzz_to_dbl(VALUE fuzz_arg)
245
298
  else
246
299
  {
247
300
  fuzz = NUM2DBL(fuzz_arg);
301
+ if (fuzz < 0.0)
302
+ {
303
+ rb_raise(rb_eArgError, "fuzz may not be negative (got `%g')", fuzz_arg);
304
+ }
248
305
  }
249
306
 
250
307
  return fuzz;
@@ -448,7 +505,11 @@ Pixel_from_HSL(VALUE class, VALUE hsl)
448
505
 
449
506
  class = class; // defeat "never referenced" message from icc
450
507
 
451
- Check_Type(hsl, T_ARRAY);
508
+ hsl = rb_Array(hsl); // Ensure array
509
+ if (RARRAY(hsl)->len < 3)
510
+ {
511
+ rb_raise(rb_eArgError, "array argument must have at least 3 elements");
512
+ }
452
513
 
453
514
  hue = NUM2DBL(rb_ary_entry(hsl, 0));
454
515
  saturation = NUM2DBL(rb_ary_entry(hsl, 1));