rmagick 2.16.0 → 3.0.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 (238) hide show
  1. checksums.yaml +5 -5
  2. data/.appveyor.yml +19 -0
  3. data/.circleci/config.yml +56 -0
  4. data/.rubocop.yml +8 -335
  5. data/.rubocop_todo.yml +255 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +6 -49
  8. data/CHANGELOG.md +23 -0
  9. data/CONTRIBUTING.md +34 -0
  10. data/Gemfile +0 -6
  11. data/README.textile +11 -3
  12. data/Rakefile +23 -15
  13. data/before_install_linux.sh +12 -15
  14. data/doc/ex/InitialCoords.rb +4 -4
  15. data/doc/ex/NewCoordSys.rb +4 -4
  16. data/doc/ex/OrigCoordSys.rb +2 -2
  17. data/doc/ex/PreserveAspectRatio.rb +34 -34
  18. data/doc/ex/RotateScale.rb +7 -7
  19. data/doc/ex/Skew.rb +7 -7
  20. data/doc/ex/Use01.rb +1 -1
  21. data/doc/ex/Use02.rb +4 -4
  22. data/doc/ex/Use03.rb +2 -2
  23. data/doc/ex/ViewBox.rb +4 -4
  24. data/doc/ex/affine.rb +5 -5
  25. data/doc/ex/affine_transform.rb +3 -3
  26. data/doc/ex/arc.rb +9 -9
  27. data/doc/ex/arcpath.rb +2 -2
  28. data/doc/ex/arcs01.rb +6 -6
  29. data/doc/ex/arcs02.rb +8 -8
  30. data/doc/ex/axes.rb +11 -11
  31. data/doc/ex/baseline_shift01.rb +5 -5
  32. data/doc/ex/bilevel_channel.rb +1 -1
  33. data/doc/ex/blur_image.rb +1 -1
  34. data/doc/ex/border.rb +1 -1
  35. data/doc/ex/bounding_box.rb +11 -11
  36. data/doc/ex/cbezier1.rb +12 -12
  37. data/doc/ex/cbezier2.rb +13 -13
  38. data/doc/ex/cbezier3.rb +13 -13
  39. data/doc/ex/cbezier4.rb +13 -13
  40. data/doc/ex/cbezier5.rb +13 -13
  41. data/doc/ex/cbezier6.rb +19 -19
  42. data/doc/ex/channel.rb +2 -2
  43. data/doc/ex/chop.rb +2 -2
  44. data/doc/ex/circle.rb +7 -7
  45. data/doc/ex/circle01.rb +2 -2
  46. data/doc/ex/clip_path.rb +6 -6
  47. data/doc/ex/coalesce.rb +6 -6
  48. data/doc/ex/color_fill_to_border.rb +8 -8
  49. data/doc/ex/color_floodfill.rb +8 -8
  50. data/doc/ex/color_histogram.rb +2 -2
  51. data/doc/ex/color_reset.rb +2 -2
  52. data/doc/ex/colors.rb +4 -4
  53. data/doc/ex/compose_mask.rb +2 -2
  54. data/doc/ex/composite.rb +39 -39
  55. data/doc/ex/composite_layers.rb +1 -2
  56. data/doc/ex/contrast.rb +3 -3
  57. data/doc/ex/crop.rb +2 -2
  58. data/doc/ex/crop_with_gravity.rb +5 -5
  59. data/doc/ex/cubic01.rb +12 -12
  60. data/doc/ex/cubic02.rb +22 -22
  61. data/doc/ex/cycle_colormap.rb +3 -3
  62. data/doc/ex/dissolve.rb +0 -0
  63. data/doc/ex/drawcomp.rb +8 -9
  64. data/doc/ex/drop_shadow.rb +4 -4
  65. data/doc/ex/ellipse.rb +9 -9
  66. data/doc/ex/ellipse01.rb +3 -3
  67. data/doc/ex/enhance.rb +2 -2
  68. data/doc/ex/evenodd.rb +19 -19
  69. data/doc/ex/fill_pattern.rb +3 -3
  70. data/doc/ex/flatten_images.rb +1 -1
  71. data/doc/ex/font_styles.rb +13 -13
  72. data/doc/ex/fonts.rb +2 -6
  73. data/doc/ex/frame.rb +1 -1
  74. data/doc/ex/get_multiline_type_metrics.rb +3 -3
  75. data/doc/ex/get_pixels.rb +4 -6
  76. data/doc/ex/get_type_metrics.rb +26 -25
  77. data/doc/ex/gradientfill.rb +2 -2
  78. data/doc/ex/grav.rb +12 -12
  79. data/doc/ex/gravity.rb +14 -16
  80. data/doc/ex/group.rb +11 -11
  81. data/doc/ex/hatchfill.rb +2 -2
  82. data/doc/ex/image.rb +9 -9
  83. data/doc/ex/implode.rb +2 -2
  84. data/doc/ex/line.rb +10 -10
  85. data/doc/ex/line01.rb +7 -7
  86. data/doc/ex/mask.rb +0 -0
  87. data/doc/ex/matte_fill_to_border.rb +3 -3
  88. data/doc/ex/matte_floodfill.rb +2 -2
  89. data/doc/ex/matte_replace.rb +3 -3
  90. data/doc/ex/median_filter.rb +2 -2
  91. data/doc/ex/mono.rb +2 -2
  92. data/doc/ex/morph.rb +1 -1
  93. data/doc/ex/mosaic.rb +7 -5
  94. data/doc/ex/motion_blur.rb +1 -1
  95. data/doc/ex/negate_channel.rb +0 -0
  96. data/doc/ex/nested_rvg.rb +2 -2
  97. data/doc/ex/nonzero.rb +19 -19
  98. data/doc/ex/opacity.rb +9 -9
  99. data/doc/ex/path.rb +17 -17
  100. data/doc/ex/pattern1.rb +4 -4
  101. data/doc/ex/pattern2.rb +2 -2
  102. data/doc/ex/polaroid.rb +0 -1
  103. data/doc/ex/polygon.rb +7 -7
  104. data/doc/ex/polygon01.rb +7 -7
  105. data/doc/ex/polyline.rb +7 -7
  106. data/doc/ex/polyline01.rb +8 -8
  107. data/doc/ex/posterize.rb +0 -0
  108. data/doc/ex/qbezierpath.rb +16 -16
  109. data/doc/ex/quad01.rb +6 -6
  110. data/doc/ex/quantize-m.rb +2 -2
  111. data/doc/ex/random_threshold_channel.rb +1 -1
  112. data/doc/ex/rect01.rb +2 -2
  113. data/doc/ex/rect02.rb +3 -3
  114. data/doc/ex/rectangle.rb +6 -6
  115. data/doc/ex/reduce_noise.rb +2 -2
  116. data/doc/ex/remap.rb +0 -0
  117. data/doc/ex/resize_to_fill.rb +0 -0
  118. data/doc/ex/resize_to_fit.rb +0 -0
  119. data/doc/ex/roll.rb +1 -1
  120. data/doc/ex/rotate.rb +8 -8
  121. data/doc/ex/rotate_f.rb +1 -1
  122. data/doc/ex/roundrect.rb +6 -6
  123. data/doc/ex/rubyname.rb +4 -4
  124. data/doc/ex/rvg_clippath.rb +3 -3
  125. data/doc/ex/rvg_linecap.rb +7 -7
  126. data/doc/ex/rvg_linejoin.rb +7 -7
  127. data/doc/ex/rvg_opacity.rb +5 -5
  128. data/doc/ex/rvg_pattern.rb +8 -8
  129. data/doc/ex/rvg_stroke_dasharray.rb +2 -2
  130. data/doc/ex/sepiatone.rb +0 -0
  131. data/doc/ex/shadow.rb +6 -6
  132. data/doc/ex/shear.rb +2 -2
  133. data/doc/ex/skewx.rb +8 -8
  134. data/doc/ex/skewy.rb +9 -9
  135. data/doc/ex/smile.rb +5 -4
  136. data/doc/ex/sparse_color.rb +0 -4
  137. data/doc/ex/splice.rb +1 -1
  138. data/doc/ex/stegano.rb +4 -5
  139. data/doc/ex/stroke_dasharray.rb +10 -10
  140. data/doc/ex/stroke_fill.rb +2 -2
  141. data/doc/ex/stroke_linecap.rb +12 -12
  142. data/doc/ex/stroke_linejoin.rb +12 -12
  143. data/doc/ex/stroke_width.rb +11 -11
  144. data/doc/ex/swirl.rb +2 -2
  145. data/doc/ex/text.rb +6 -6
  146. data/doc/ex/text01.rb +4 -4
  147. data/doc/ex/text_align.rb +5 -5
  148. data/doc/ex/text_antialias.rb +2 -2
  149. data/doc/ex/text_styles.rb +8 -8
  150. data/doc/ex/text_undercolor.rb +4 -4
  151. data/doc/ex/texture_fill_to_border.rb +8 -8
  152. data/doc/ex/texture_floodfill.rb +8 -8
  153. data/doc/ex/texturefill.rb +2 -2
  154. data/doc/ex/threshold.rb +2 -2
  155. data/doc/ex/to_blob.rb +1 -1
  156. data/doc/ex/translate.rb +8 -8
  157. data/doc/ex/transparent.rb +6 -6
  158. data/doc/ex/transpose.rb +0 -0
  159. data/doc/ex/transverse.rb +0 -0
  160. data/doc/ex/tref01.rb +6 -6
  161. data/doc/ex/triangle01.rb +2 -2
  162. data/doc/ex/trim.rb +2 -2
  163. data/doc/ex/tspan01.rb +5 -5
  164. data/doc/ex/tspan02.rb +5 -5
  165. data/doc/ex/tspan03.rb +5 -5
  166. data/doc/ex/unsharp_mask.rb +3 -3
  167. data/doc/ex/viewex.rb +5 -5
  168. data/doc/ex/vignette.rb +0 -0
  169. data/doc/ex/watermark.rb +6 -6
  170. data/doc/ex/wet_floor.rb +2 -2
  171. data/doc/ex/writing_mode01.rb +12 -12
  172. data/doc/ex/writing_mode02.rb +12 -12
  173. data/examples/constitute.rb +1 -1
  174. data/examples/crop_with_gravity.rb +5 -5
  175. data/examples/demo.rb +6 -7
  176. data/examples/describe.rb +8 -10
  177. data/examples/find_similar_region.rb +3 -3
  178. data/examples/histogram.rb +192 -201
  179. data/examples/identify.rb +62 -73
  180. data/examples/image_opacity.rb +0 -1
  181. data/examples/import_export.rb +1 -1
  182. data/examples/pattern_fill.rb +3 -4
  183. data/examples/rotating_text.rb +5 -4
  184. data/examples/spinner.rb +5 -5
  185. data/examples/thumbnail.rb +3 -3
  186. data/examples/vignette.rb +5 -5
  187. data/ext/RMagick/extconf.rb +213 -230
  188. data/ext/RMagick/rmagick.c +1 -0
  189. data/ext/RMagick/rmagick.h +26 -29
  190. data/ext/RMagick/rmdraw.c +3 -38
  191. data/ext/RMagick/rmenum.c +36 -0
  192. data/ext/RMagick/rmimage.c +166 -10
  193. data/ext/RMagick/rminfo.c +7 -2
  194. data/ext/RMagick/rmkinfo.c +247 -0
  195. data/ext/RMagick/rmmain.c +96 -0
  196. data/ext/RMagick/rmutil.c +4 -0
  197. data/lib/rmagick/version.rb +3 -3
  198. data/lib/rmagick_internal.rb +226 -308
  199. data/lib/rvg/clippath.rb +2 -4
  200. data/lib/rvg/container.rb +25 -22
  201. data/lib/rvg/deep_equal.rb +11 -11
  202. data/lib/rvg/describable.rb +2 -2
  203. data/lib/rvg/embellishable.rb +60 -66
  204. data/lib/rvg/misc.rb +122 -128
  205. data/lib/rvg/pathdata.rb +15 -17
  206. data/lib/rvg/rvg.rb +41 -44
  207. data/lib/rvg/stretchable.rb +22 -28
  208. data/lib/rvg/stylable.rb +10 -10
  209. data/lib/rvg/text.rb +164 -165
  210. data/lib/rvg/transformable.rb +15 -15
  211. data/lib/rvg/units.rb +2 -2
  212. data/rmagick.gemspec +9 -33
  213. data/spec/rmagick/draw_spec.rb +5 -6
  214. data/spec/rmagick/image/blue_shift_spec.rb +1 -3
  215. data/spec/rmagick/image/channel_entropy_spec.rb +9 -0
  216. data/spec/rmagick/image/composite_spec.rb +2 -4
  217. data/spec/rmagick/image/constitute_spec.rb +2 -4
  218. data/spec/rmagick/image/dispatch_spec.rb +1 -3
  219. data/spec/rmagick/image/from_blob_spec.rb +1 -3
  220. data/spec/rmagick/image/ping_spec.rb +1 -3
  221. data/spec/rmagick/image/properties_spec.rb +0 -2
  222. data/spec/rmagick/image/read_spec.rb +28 -0
  223. data/spec/spec_helper.rb +7 -1
  224. data/spec/support/issue_200/app.rb +8 -0
  225. data/test/Image1.rb +70 -70
  226. data/test/Image2.rb +369 -361
  227. data/test/Image3.rb +64 -63
  228. data/test/ImageList1.rb +796 -792
  229. data/test/ImageList2.rb +43 -44
  230. data/test/Image_attributes.rb +26 -48
  231. data/test/Import_Export.rb +71 -77
  232. data/test/Info.rb +30 -31
  233. data/test/Magick.rb +47 -46
  234. data/test/Pixel.rb +24 -24
  235. data/test/Preview.rb +7 -6
  236. data/test/test_all_basic.rb +15 -7
  237. data/test/tmpnam_test.rb +3 -3
  238. metadata +57 -18
@@ -188,6 +188,7 @@ Magick_init_formats(VALUE class)
188
188
  , rb_str_new2(magick_info[x]->name)
189
189
  , MagickInfo_to_format((const MagickInfo *)magick_info[x]));
190
190
  }
191
+ magick_free((void *)magick_info);
191
192
  RB_GC_GUARD(formats);
192
193
  return formats;
193
194
  }
@@ -29,11 +29,7 @@
29
29
  #include <sys/types.h>
30
30
  #endif
31
31
  #include "ruby.h"
32
- #if defined(HAVE_RUBY_IO_H)
33
- #include "ruby/io.h" // >= 1.9.0-5
34
- #else
35
- #include "rubyio.h"
36
- #endif
32
+ #include "ruby/io.h"
37
33
 
38
34
 
39
35
  // Undef Ruby's versions of these symbols
@@ -85,7 +81,7 @@
85
81
 
86
82
  //! degrees to radians conversion
87
83
  #undef DegreesToRadians // defined in ImageMagick.h in 6.0.2
88
- #define DegreesToRadians(x) ((x)*3.14159265358979323846/180.0)
84
+ #define DegreesToRadians(x) ((x)*3.14159265358979323846/180.0)
89
85
 
90
86
  //! pixel intensity calculation
91
87
  #define PIXEL_INTENSITY(q) ((Quantum)(0.299*(q)->red + 0.587*(q)->green + 0.114*(q)->blue + 0.5))
@@ -122,28 +118,6 @@
122
118
  #define OpenFile rb_io_t /**< Ruby open file */
123
119
  #endif
124
120
 
125
- // These macros are required in 1.9.1 but aren't defined prior to 1.8.6.
126
- #if !defined(RSTRING_LEN)
127
- #define RSTRING_LEN(s) (RSTRING((s))->len) /**< Ruby string length */
128
- #endif
129
- #if !defined(RSTRING_PTR)
130
- #define RSTRING_PTR(s) (RSTRING((s))->ptr) /**< Ruby string pointer */
131
- #endif
132
-
133
- // Backport these two macros to 1.8
134
- #if !defined(RARRAY_LEN)
135
- #define RARRAY_LEN(a) RARRAY((a))->len /**< Ruby array length */
136
- #endif
137
- // Matz says this macro is read-only! (see http://www.ruby-forum.com/topic/146072)
138
- #if !defined(RARRAY_PTR)
139
- #define RARRAY_PTR(a) RARRAY((a))->ptr /**< Ruby array pointer */
140
- #endif
141
-
142
- // Backport this macro to 1.8.6
143
- #if !defined(RB_GC_GUARD)
144
- #define RB_GC_GUARD(x) (x)
145
- #endif
146
-
147
121
  //! Convert a C string to a Ruby symbol. Used in marshal_dump/marshal_load methods
148
122
  #define CSTR2SYM(s) ID2SYM(rb_intern(s))
149
123
  //! Convert a C string to a Ruby String, or nil if the ptr is NULL
@@ -356,6 +330,7 @@ typedef enum _QuantumExpressionOperator
356
330
  EXTERN VALUE Module_Magick;
357
331
  EXTERN VALUE Class_ImageList;
358
332
  EXTERN VALUE Class_Info;
333
+ EXTERN VALUE Class_KernelInfo;
359
334
  EXTERN VALUE Class_Draw;
360
335
  EXTERN VALUE Class_DrawOptions;
361
336
  EXTERN VALUE Class_Image;
@@ -421,6 +396,9 @@ EXTERN VALUE Class_StretchType;
421
396
  EXTERN VALUE Class_StyleType;
422
397
  EXTERN VALUE Class_WeightType;
423
398
  EXTERN VALUE Class_VirtualPixelMethod;
399
+ EXTERN VALUE Class_GeometryFlags;
400
+ EXTERN VALUE Class_MorphologyMethod;
401
+ EXTERN VALUE Class_KernelInfoType;
424
402
 
425
403
  /**
426
404
  * Commonly-used IDs
@@ -469,7 +447,7 @@ EXTERN ID rm_ID_y; /**< "y" */
469
447
  */
470
448
  //! attribute reader
471
449
  #define DCL_ATTR_READER(class, attr) \
472
- rb_define_method(Class_##class, #attr, class##_##attr, 0);
450
+ rb_define_method(Class_##class, #attr, class##_##attr, 0);
473
451
  //! attribute writer
474
452
  #define DCL_ATTR_WRITER(class, attr) \
475
453
  rb_define_method(Class_##class, #attr "=", class##_##attr##_eq, 1);
@@ -843,6 +821,21 @@ extern VALUE rm_info_new(void);
843
821
  extern DisposeType rm_dispose_to_enum(const char *);
844
822
  extern GravityType rm_gravity_to_enum(const char *);
845
823
 
824
+ // rmkinfo.c
825
+
826
+ extern VALUE KernelInfo_alloc(VALUE);
827
+
828
+ extern VALUE KernelInfo_initialize(VALUE, VALUE);
829
+ extern VALUE KernelInfo_zero_nans(VALUE);
830
+ extern VALUE KernelInfo_unity_add(VALUE, VALUE);
831
+ extern VALUE KernelInfo_show(VALUE);
832
+ extern VALUE KernelInfo_scale(VALUE, VALUE, VALUE);
833
+ extern VALUE KernelInfo_scale_geometry(VALUE, VALUE);
834
+ extern VALUE KernelInfo_clone(VALUE);
835
+
836
+ extern VALUE KernelInfo_builtin(VALUE, VALUE, VALUE);
837
+
838
+
846
839
  // rmimage.c
847
840
  ATTR_WRITER(Image, alpha)
848
841
  ATTR_ACCESSOR(Image, background_color)
@@ -954,6 +947,7 @@ extern VALUE Image_compare_channel(int, VALUE *, VALUE);
954
947
  extern VALUE Image_channel_depth(int, VALUE *, VALUE);
955
948
  extern VALUE Image_channel_extrema(int, VALUE *, VALUE);
956
949
  extern VALUE Image_channel_mean(int, VALUE *, VALUE);
950
+ extern VALUE Image_channel_entropy(int, VALUE *, VALUE);
957
951
  extern VALUE Image_charcoal(int, VALUE *, VALUE);
958
952
  extern VALUE Image_chop(VALUE, VALUE, VALUE, VALUE, VALUE);
959
953
  extern VALUE Image_clone(VALUE);
@@ -977,6 +971,8 @@ extern VALUE Image_contrast(int, VALUE *, VALUE);
977
971
  extern VALUE Image_contrast_stretch_channel(int, VALUE *, VALUE);
978
972
  extern VALUE Image_convolve(VALUE, VALUE, VALUE);
979
973
  extern VALUE Image_convolve_channel(int, VALUE *, VALUE);
974
+ extern VALUE Image_morphology(VALUE, VALUE, VALUE, VALUE);
975
+ extern VALUE Image_morphology_channel(VALUE, VALUE, VALUE, VALUE, VALUE);
980
976
  extern VALUE Image_copy(VALUE);
981
977
  extern VALUE Image_crop(int, VALUE *, VALUE);
982
978
  extern VALUE Image_crop_bang(int, VALUE *, VALUE);
@@ -1197,6 +1193,7 @@ extern VALUE Enum_initialize(VALUE, VALUE, VALUE);
1197
1193
  extern VALUE Enum_to_s(VALUE);
1198
1194
  extern VALUE Enum_to_i(VALUE);
1199
1195
  extern VALUE Enum_spaceship(VALUE, VALUE);
1196
+ extern VALUE Enum_bitwise_or(VALUE, VALUE);
1200
1197
  extern VALUE Enum_case_eq(VALUE, VALUE);
1201
1198
  extern VALUE Enum_type_initialize(VALUE, VALUE, VALUE);
1202
1199
  extern VALUE Enum_type_each(VALUE);
@@ -670,13 +670,6 @@ Draw_marshal_load(VALUE self, VALUE ddraw)
670
670
 
671
671
  Data_Get_Struct(self, Draw, draw);
672
672
 
673
- draw->info = magick_malloc(sizeof(DrawInfo));
674
- if (!draw->info)
675
- {
676
- rb_raise(rb_eNoMemError, "not enough memory to continue");
677
- }
678
- GetDrawInfo(NULL, draw->info);
679
-
680
673
  OBJ_TO_MAGICK_STRING(draw->info->geometry, rb_hash_aref(ddraw, CSTR2SYM("geometry")));
681
674
 
682
675
  //val = rb_hash_aref(ddraw, CSTR2SYM("viewbox"));
@@ -1727,7 +1720,7 @@ DrawOptions_initialize(VALUE self)
1727
1720
  Draw *draw_options;
1728
1721
 
1729
1722
  Data_Get_Struct(self, Draw, draw_options);
1730
- draw_options->info = magick_malloc(sizeof(DrawInfo));
1723
+ draw_options->info = AcquireDrawInfo();
1731
1724
  if (!draw_options->info)
1732
1725
  {
1733
1726
  rb_raise(rb_eNoMemError, "not enough memory to continue");
@@ -1804,6 +1797,8 @@ PolaroidOptions_initialize(VALUE self)
1804
1797
  (void) QueryColorDatabase("gray75", &draw->shadow_color, exception);
1805
1798
  CHECK_EXCEPTION()
1806
1799
  (void) QueryColorDatabase("#dfdfdf", &draw->info->border_color, exception);
1800
+ CHECK_EXCEPTION()
1801
+ DestroyExceptionInfo(exception);
1807
1802
 
1808
1803
  if (rb_block_given_p())
1809
1804
  {
@@ -1935,8 +1930,6 @@ get_type_metrics(
1935
1930
  VALUE self,
1936
1931
  get_type_metrics_func_t getter)
1937
1932
  {
1938
- static char attrs[] = "OPbcdefghiklmnopqrstuwxyz[@#%";
1939
- #define ATTRS_L ((int)(sizeof(attrs)-1))
1940
1933
  Image *image;
1941
1934
  Draw *draw;
1942
1935
  VALUE t;
@@ -1950,34 +1943,6 @@ get_type_metrics(
1950
1943
  {
1951
1944
  case 1: // use default image
1952
1945
  text = rm_str2cstr(argv[0], &text_l);
1953
-
1954
- for (x = 0; x < text_l-1; x++)
1955
- {
1956
- // Ensure text string doesn't refer to image attributes.
1957
- if (text[x] == '%')
1958
- {
1959
- int y;
1960
- char spec = text[x+1];
1961
-
1962
- if (spec == '%')
1963
- {
1964
- x++;
1965
- }
1966
- else
1967
- {
1968
- for (y = 0; y < ATTRS_L; y++)
1969
- {
1970
- if (spec == attrs[y])
1971
- {
1972
- rb_raise(rb_eArgError,
1973
- "text string contains image attribute reference `%%%c'",
1974
- spec);
1975
- }
1976
- }
1977
- }
1978
- }
1979
- }
1980
-
1981
1946
  Data_Get_Struct(get_dummy_tm_img(CLASS_OF(self)), Image, image);
1982
1947
  break;
1983
1948
  case 2:
@@ -198,6 +198,42 @@ Enum_spaceship(VALUE self, VALUE other)
198
198
  return INT2FIX(0);
199
199
  }
200
200
 
201
+ /**
202
+ * Bitwise OR for enums
203
+ *
204
+ * Ruby usage:
205
+ * - @verbatim Enum1 | Enum2 @endverbatim
206
+ *
207
+ * Notes:
208
+ * - Enums must be instances of the same class.
209
+ *
210
+ * @param Enum1 this object
211
+ * @param Enum2 another enum
212
+ * @return new Enum instance
213
+ */
214
+ VALUE
215
+ Enum_bitwise_or(VALUE self, VALUE another)
216
+ {
217
+ VALUE new_enum, cls;
218
+ MagickEnum *this, *that, *new_enum_data;
219
+
220
+ cls = CLASS_OF(self);
221
+ if (CLASS_OF(another) != cls)
222
+ {
223
+ rb_raise(rb_eArgError, "Expected class %s but got %s", rb_class2name(cls), rb_class2name(CLASS_OF(another)));
224
+ }
225
+
226
+ new_enum = Enum_alloc(cls);
227
+
228
+ Data_Get_Struct(self, MagickEnum, this);
229
+ Data_Get_Struct(another, MagickEnum, that);
230
+ Data_Get_Struct(new_enum, MagickEnum, new_enum_data);
231
+
232
+ new_enum_data->id = rb_to_id(rb_sprintf("%s|%s", rb_id2name(this->id), rb_id2name(that->id)));
233
+ new_enum_data->val = this->val | that->val;
234
+
235
+ return new_enum;
236
+ }
201
237
 
202
238
  /**
203
239
  * Return the name of an enum.
@@ -2328,6 +2328,62 @@ Image_channel_mean(int argc, VALUE *argv, VALUE self)
2328
2328
  return ary;
2329
2329
  }
2330
2330
 
2331
+ /**
2332
+ * Return an array of the entropy for the channel.
2333
+ *
2334
+ * Ruby usage:
2335
+ * - @verbatim Image#channel_entropy @endverbatim
2336
+ * - @verbatim Image#channel_entropy(channel) @endverbatim
2337
+ *
2338
+ * Notes:
2339
+ * - Default channel is AllChannels
2340
+ *
2341
+ * @param argc number of input arguments
2342
+ * @param argv array of input arguments
2343
+ * @param self this object
2344
+ * @return an array [mean, std. deviation]
2345
+ */
2346
+ VALUE
2347
+ Image_channel_entropy(int argc, VALUE *argv, VALUE self)
2348
+ {
2349
+ #if defined(HAVE_GETIMAGECHANNELENTROPY)
2350
+ Image *image;
2351
+ ChannelType channels;
2352
+ ExceptionInfo *exception;
2353
+ double entropy;
2354
+ VALUE ary;
2355
+
2356
+ image = rm_check_destroyed(self);
2357
+
2358
+ channels = extract_channels(&argc, argv);
2359
+
2360
+ // Ensure all arguments consumed.
2361
+ if (argc > 0)
2362
+ {
2363
+ raise_ChannelType_error(argv[argc-1]);
2364
+ }
2365
+
2366
+ exception = AcquireExceptionInfo();
2367
+ (void) GetImageChannelEntropy(image, channels, &entropy, exception);
2368
+ CHECK_EXCEPTION()
2369
+
2370
+ (void) DestroyExceptionInfo(exception);
2371
+
2372
+ ary = rb_ary_new2(1);
2373
+ rb_ary_store(ary, 0, rb_float_new(entropy));
2374
+
2375
+ RB_GC_GUARD(ary);
2376
+
2377
+ return ary;
2378
+ #else
2379
+ rm_not_implemented();
2380
+ return (VALUE) 0;
2381
+ argc = argc;
2382
+ argv = argv;
2383
+ self = self;
2384
+ #endif
2385
+ }
2386
+
2331
2387
 
2332
2388
  /**
2333
2389
  * Return a new image that is a copy of the input image with the edges
@@ -3107,6 +3163,7 @@ VALUE Image_combine(int argc, VALUE *argv, VALUE self)
3107
3163
  ReverseImageList(&images);
3108
3164
  new_image = CombineImages(images, channel, exception);
3109
3165
  rm_check_exception(exception, images, RetainOnError);
3166
+ (void) DestroyExceptionInfo(exception);
3110
3167
  rm_split(images);
3111
3168
 
3112
3169
  rm_ensure_result(new_image);
@@ -4119,6 +4176,78 @@ Image_contrast_stretch_channel(int argc, VALUE *argv, VALUE self)
4119
4176
  return rm_image_new(new_image);
4120
4177
  }
4121
4178
 
4179
+ /** Apply a user supplied kernel to the image according to the given mophology method.
4180
+ *
4181
+ * Ruby Usage:
4182
+ * - @verbatim Image#morphology(method, iterations, kernel) @endverbatim
4183
+ *
4184
+ * @param self this object
4185
+ * @param method is one of morphology methods defined by Magick::MorphologyMethod
4186
+ * @param iterations apply the operation this many times (or no change).
4187
+ * A value of -1 means loop until no change found.
4188
+ * How this is applied may depend on the morphology method.
4189
+ * Typically this is a value of 1.
4190
+ * @param kernel morphology kernel to apply
4191
+ */
4192
+
4193
+ VALUE
4194
+ Image_morphology(VALUE self, VALUE method_v, VALUE iterations, VALUE kernel_v)
4195
+ {
4196
+ static VALUE default_channels_const = 0;
4197
+
4198
+ if(!default_channels_const)
4199
+ default_channels_const = rb_const_get(Module_Magick, rb_intern("DefaultChannels"));
4200
+
4201
+ return Image_morphology_channel(self, default_channels_const, method_v, iterations, kernel_v);
4202
+ }
4203
+
4204
+ /** Apply a user supplied kernel to the image channel according to the given mophology method.
4205
+ *
4206
+ * Ruby Usage:
4207
+ * - @verbatim Image#morphology_channel(channel, method, iterations, kernel) @endverbatim
4208
+ *
4209
+ * @param self this object
4210
+ * @param channel is a channel type defined by Magick::ChannelType
4211
+ * @param method is one of morphology methods defined by Magick::MorphologyMethod
4212
+ * @param iterations apply the operation this many times (or no change).
4213
+ * A value of -1 means loop until no change found.
4214
+ * How this is applied may depend on the morphology method.
4215
+ * Typically this is a value of 1.
4216
+ * @param kernel morphology kernel to apply
4217
+ */
4218
+
4219
+ VALUE
4220
+ Image_morphology_channel(VALUE self, VALUE channel_v, VALUE method_v, VALUE iterations, VALUE kernel_v)
4221
+ {
4222
+ Image *image, *new_image;
4223
+ ExceptionInfo *exception;
4224
+ MorphologyMethod method;
4225
+ ChannelType channel;
4226
+ KernelInfo *kernel;
4227
+
4228
+ VALUE_TO_ENUM(method_v, method, MorphologyMethod);
4229
+ VALUE_TO_ENUM(channel_v, channel, ChannelType);
4230
+ Check_Type(iterations, T_FIXNUM);
4231
+
4232
+ if (TYPE(kernel_v) == T_STRING)
4233
+ kernel_v = rb_class_new_instance(1, &kernel_v, Class_KernelInfo);
4234
+
4235
+ if (!rb_obj_is_kind_of(kernel_v, Class_KernelInfo))
4236
+ rb_raise(rb_eArgError, "expected String or Magick::KernelInfo");
4237
+
4238
+ Data_Get_Struct(kernel_v, KernelInfo, kernel);
4239
+
4240
+ image = rm_check_destroyed(self);
4241
+ exception = AcquireExceptionInfo();
4242
+
4243
+ new_image = MorphologyImageChannel(image, channel, method, NUM2LONG(iterations), kernel, exception);
4244
+ rm_check_exception(exception, new_image, DestroyOnError);
4245
+ DestroyExceptionInfo(exception);
4246
+
4247
+ rm_ensure_result(new_image);
4248
+ return rm_image_new(new_image);
4249
+ }
4250
+
4122
4251
  /**
4123
4252
  * Apply a custom convolution kernel to the image.
4124
4253
  *
@@ -6602,7 +6731,7 @@ Image_frame(int argc, VALUE *argv, VALUE self)
6602
6731
  * - @verbatim Image.from_blob(blob) <{ parm block }> @endverbatim
6603
6732
  *
6604
6733
  * @param class the Ruby Image class (unused)
6605
- * @param blob_arg the blog as a Ruby string
6734
+ * @param blob_arg the blob as a Ruby string
6606
6735
  * @return an array of new images
6607
6736
  */
6608
6737
  VALUE
@@ -7111,6 +7240,7 @@ has_attribute(VALUE self, MagickBooleanType (attr_test)(const Image *, Exception
7111
7240
 
7112
7241
  r = (attr_test)(image, exception);
7113
7242
  CHECK_EXCEPTION()
7243
+ (void) DestroyExceptionInfo(exception);
7114
7244
 
7115
7245
  return r ? Qtrue : Qfalse;
7116
7246
  }
@@ -8931,6 +9061,9 @@ Image_monitor_eq(VALUE self, VALUE monitor)
8931
9061
  (void) SetImageProgressMonitor(image, rm_progress_monitor, (void *)monitor);
8932
9062
  }
8933
9063
 
9064
+ #if defined(_WIN32)
9065
+ rb_warn("Image#monitor= does not work on Windows");
9066
+ #endif
8934
9067
 
8935
9068
  return self;
8936
9069
  }
@@ -10766,6 +10899,11 @@ rd_image(VALUE class, VALUE file, reader_t reader)
10766
10899
 
10767
10900
  filename = rm_str2cstr(file, &filename_l);
10768
10901
  filename_l = min(filename_l, MaxTextExtent-1);
10902
+ if (filename_l == 0)
10903
+ {
10904
+ rb_raise(rb_eArgError, "invalid path");
10905
+ }
10906
+
10769
10907
  memcpy(info->filename, filename, (size_t)filename_l);
10770
10908
  info->filename[filename_l] = '\0';
10771
10909
  SetImageInfoFile(info, NULL);
@@ -12685,6 +12823,7 @@ Image_sparse_color(int argc, VALUE *argv, VALUE self)
12685
12823
  new_image = SparseColorImage(image, channels, method, nargs, args, exception);
12686
12824
  xfree(args);
12687
12825
  CHECK_EXCEPTION();
12826
+ (void) DestroyExceptionInfo(exception);
12688
12827
  rm_ensure_result(new_image);
12689
12828
 
12690
12829
  RB_GC_GUARD(args);
@@ -12988,6 +13127,9 @@ Image_store_pixels(VALUE self, VALUE x_arg, VALUE y_arg, VALUE cols_arg
12988
13127
  long x, y;
12989
13128
  unsigned long cols, rows;
12990
13129
  unsigned int okay;
13130
+ #if defined(HAVE_SYNCAUTHENTICPIXELS) || defined(HAVE_GETAUTHENTICPIXELS)
13131
+ ExceptionInfo *exception;
13132
+ #endif
12991
13133
 
12992
13134
  image = rm_check_destroyed(self);
12993
13135
 
@@ -13014,14 +13156,12 @@ Image_store_pixels(VALUE self, VALUE x_arg, VALUE y_arg, VALUE cols_arg
13014
13156
  // Get a pointer to the pixels. Replace the values with the PixelPackets
13015
13157
  // from the pixels argument.
13016
13158
  {
13017
- #if defined(HAVE_SYNCAUTHENTICPIXELS) || defined(HAVE_GETAUTHENTICPIXELS)
13018
- ExceptionInfo *exception;
13159
+ #if defined(HAVE_GETAUTHENTICPIXELS)
13019
13160
  exception = AcquireExceptionInfo();
13020
- #endif
13021
13161
 
13022
- #if defined(HAVE_GETAUTHENTICPIXELS)
13023
13162
  pixels = GetAuthenticPixels(image, x, y, cols, rows, exception);
13024
13163
  CHECK_EXCEPTION()
13164
+ DestroyExceptionInfo(exception);
13025
13165
  #else
13026
13166
  pixels = GetImagePixels(image, x, y, cols, rows);
13027
13167
  rm_check_image_exception(image, RetainOnError);
@@ -13036,17 +13176,16 @@ Image_store_pixels(VALUE self, VALUE x_arg, VALUE y_arg, VALUE cols_arg
13036
13176
  pixels[n] = *pixel;
13037
13177
  }
13038
13178
  #if defined(HAVE_SYNCAUTHENTICPIXELS)
13179
+ exception = AcquireExceptionInfo();
13180
+
13039
13181
  SyncAuthenticPixels(image, exception);
13040
13182
  CHECK_EXCEPTION()
13183
+ DestroyExceptionInfo(exception);
13041
13184
  #else
13042
13185
  SyncImagePixels(image);
13043
13186
  rm_check_image_exception(image, RetainOnError);
13044
13187
  #endif
13045
13188
  }
13046
-
13047
- #if defined(HAVE_SYNCAUTHENTICPIXELS) || defined(HAVE_GETAUTHENTICPIXELS)
13048
- DestroyExceptionInfo(exception);
13049
- #endif
13050
13189
  }
13051
13190
 
13052
13191
  RB_GC_GUARD(new_pixel);
@@ -15386,6 +15525,23 @@ static void call_trace_proc(Image *image, const char *which)
15386
15525
  }
15387
15526
 
15388
15527
 
15528
+ static VALUE
15529
+ rm_trace_creation_body(VALUE img)
15530
+ {
15531
+ Image *image = (Image *)img;
15532
+ call_trace_proc(image, "c");
15533
+ return Qnil;
15534
+ }
15535
+
15536
+ static VALUE
15537
+ rm_trace_creation_handle_exception(VALUE img, VALUE exc)
15538
+ {
15539
+ Image *image = (Image *)img;
15540
+ DestroyImage(image);
15541
+ rb_exc_raise(exc);
15542
+ return Qnil; /* not reachable */
15543
+ }
15544
+
15389
15545
  /**
15390
15546
  * Trace image creation
15391
15547
  *
@@ -15396,7 +15552,7 @@ static void call_trace_proc(Image *image, const char *which)
15396
15552
  */
15397
15553
  void rm_trace_creation(Image *image)
15398
15554
  {
15399
- call_trace_proc(image, "c");
15555
+ rb_rescue(rm_trace_creation_body, (VALUE)image, rm_trace_creation_handle_exception, (VALUE)image);
15400
15556
  }
15401
15557
 
15402
15558