rmagick 2.16.0 → 5.1.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 (405) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +63 -0
  3. data/.devcontainer/Dockerfile +14 -0
  4. data/.devcontainer/ImageMagick6/devcontainer.json +11 -0
  5. data/.devcontainer/devcontainer.json +11 -0
  6. data/.devcontainer/setup-repo.sh +10 -0
  7. data/.devcontainer/setup-user.sh +45 -0
  8. data/.editorconfig +3 -0
  9. data/.github/ISSUE_TEMPLATE.md +17 -0
  10. data/.github/workflows/ci.yml +79 -0
  11. data/.gitignore +5 -1
  12. data/.rspec +1 -0
  13. data/.rubocop.yml +37 -340
  14. data/.rubocop_todo.yml +448 -0
  15. data/.yardopts +5 -0
  16. data/CHANGELOG.md +435 -0
  17. data/CODE_OF_CONDUCT.md +122 -7
  18. data/CONTRIBUTING.md +37 -6
  19. data/Gemfile +0 -6
  20. data/README.md +317 -0
  21. data/Rakefile +37 -35
  22. data/before_install_linux.sh +65 -28
  23. data/before_install_osx.sh +58 -2
  24. data/ext/RMagick/extconf.rb +286 -393
  25. data/ext/RMagick/rmagick.c +106 -111
  26. data/ext/RMagick/rmagick.h +235 -331
  27. data/ext/RMagick/rmagick_gvl.h +224 -0
  28. data/ext/RMagick/rmdraw.c +484 -842
  29. data/ext/RMagick/rmenum.c +316 -755
  30. data/ext/RMagick/rmfill.c +281 -191
  31. data/ext/RMagick/rmilist.c +450 -455
  32. data/ext/RMagick/rmimage.c +6247 -5289
  33. data/ext/RMagick/rminfo.c +721 -894
  34. data/ext/RMagick/rmkinfo.c +228 -0
  35. data/ext/RMagick/rmmain.c +727 -519
  36. data/ext/RMagick/rmmontage.c +127 -172
  37. data/ext/RMagick/rmpixel.c +638 -431
  38. data/ext/RMagick/rmstruct.c +102 -282
  39. data/ext/RMagick/rmutil.c +450 -363
  40. data/lib/rmagick/version.rb +5 -4
  41. data/lib/rmagick.rb +2 -0
  42. data/lib/rmagick_internal.rb +349 -413
  43. data/lib/rvg/clippath.rb +3 -4
  44. data/lib/rvg/container.rb +30 -22
  45. data/lib/rvg/deep_equal.rb +11 -11
  46. data/lib/rvg/describable.rb +2 -2
  47. data/lib/rvg/embellishable.rb +63 -68
  48. data/lib/rvg/misc.rb +136 -139
  49. data/lib/rvg/paint.rb +2 -1
  50. data/lib/rvg/pathdata.rb +7 -8
  51. data/lib/rvg/rvg.rb +47 -46
  52. data/lib/rvg/stretchable.rb +22 -28
  53. data/lib/rvg/stylable.rb +12 -10
  54. data/lib/rvg/text.rb +169 -165
  55. data/lib/rvg/transformable.rb +17 -16
  56. data/lib/rvg/units.rb +5 -5
  57. data/rmagick.gemspec +16 -39
  58. metadata +118 -395
  59. data/.hound.yml +0 -2
  60. data/.simplecov +0 -27
  61. data/.travis.yml +0 -74
  62. data/Doxyfile +0 -1514
  63. data/README.textile +0 -251
  64. data/deprecated/RMagick.rb +0 -6
  65. data/doc/.cvsignore +0 -1
  66. data/doc/comtasks.html +0 -287
  67. data/doc/constants.html +0 -1581
  68. data/doc/css/doc.css +0 -299
  69. data/doc/css/popup.css +0 -34
  70. data/doc/css/ref.css +0 -67
  71. data/doc/draw.html +0 -3272
  72. data/doc/ex/InitialCoords.rb +0 -22
  73. data/doc/ex/NewCoordSys.rb +0 -30
  74. data/doc/ex/OrigCoordSys.rb +0 -16
  75. data/doc/ex/PreserveAspectRatio.rb +0 -204
  76. data/doc/ex/RotateScale.rb +0 -36
  77. data/doc/ex/Skew.rb +0 -38
  78. data/doc/ex/Use01.rb +0 -15
  79. data/doc/ex/Use02.rb +0 -20
  80. data/doc/ex/Use03.rb +0 -16
  81. data/doc/ex/ViewBox.rb +0 -31
  82. data/doc/ex/adaptive_threshold.rb +0 -9
  83. data/doc/ex/add_noise.rb +0 -16
  84. data/doc/ex/affine.rb +0 -48
  85. data/doc/ex/affine_transform.rb +0 -20
  86. data/doc/ex/arc.rb +0 -49
  87. data/doc/ex/arcpath.rb +0 -32
  88. data/doc/ex/arcs01.rb +0 -28
  89. data/doc/ex/arcs02.rb +0 -59
  90. data/doc/ex/average.rb +0 -15
  91. data/doc/ex/axes.rb +0 -64
  92. data/doc/ex/baseline_shift01.rb +0 -17
  93. data/doc/ex/bilevel_channel.rb +0 -8
  94. data/doc/ex/blur_image.rb +0 -12
  95. data/doc/ex/border.rb +0 -10
  96. data/doc/ex/bounding_box.rb +0 -42
  97. data/doc/ex/cbezier1.rb +0 -41
  98. data/doc/ex/cbezier2.rb +0 -41
  99. data/doc/ex/cbezier3.rb +0 -41
  100. data/doc/ex/cbezier4.rb +0 -42
  101. data/doc/ex/cbezier5.rb +0 -42
  102. data/doc/ex/cbezier6.rb +0 -53
  103. data/doc/ex/channel.rb +0 -25
  104. data/doc/ex/charcoal.rb +0 -12
  105. data/doc/ex/chop.rb +0 -29
  106. data/doc/ex/circle.rb +0 -33
  107. data/doc/ex/circle01.rb +0 -16
  108. data/doc/ex/clip_path.rb +0 -60
  109. data/doc/ex/coalesce.rb +0 -57
  110. data/doc/ex/color_fill_to_border.rb +0 -29
  111. data/doc/ex/color_floodfill.rb +0 -28
  112. data/doc/ex/color_histogram.rb +0 -47
  113. data/doc/ex/color_reset.rb +0 -11
  114. data/doc/ex/colorize.rb +0 -16
  115. data/doc/ex/colors.rb +0 -64
  116. data/doc/ex/compose_mask.rb +0 -22
  117. data/doc/ex/composite.rb +0 -133
  118. data/doc/ex/composite_layers.rb +0 -53
  119. data/doc/ex/composite_tiled.rb +0 -21
  120. data/doc/ex/contrast.rb +0 -36
  121. data/doc/ex/crop.rb +0 -31
  122. data/doc/ex/crop_with_gravity.rb +0 -42
  123. data/doc/ex/cubic01.rb +0 -43
  124. data/doc/ex/cubic02.rb +0 -91
  125. data/doc/ex/cycle_colormap.rb +0 -21
  126. data/doc/ex/dissolve.rb +0 -12
  127. data/doc/ex/drawcomp.rb +0 -42
  128. data/doc/ex/drop_shadow.rb +0 -60
  129. data/doc/ex/edge.rb +0 -11
  130. data/doc/ex/ellipse.rb +0 -45
  131. data/doc/ex/ellipse01.rb +0 -21
  132. data/doc/ex/emboss.rb +0 -11
  133. data/doc/ex/enhance.rb +0 -28
  134. data/doc/ex/equalize.rb +0 -11
  135. data/doc/ex/evenodd.rb +0 -42
  136. data/doc/ex/fill_pattern.rb +0 -23
  137. data/doc/ex/flatten_images.rb +0 -36
  138. data/doc/ex/flip.rb +0 -11
  139. data/doc/ex/flop.rb +0 -11
  140. data/doc/ex/font_styles.rb +0 -32
  141. data/doc/ex/fonts.rb +0 -20
  142. data/doc/ex/frame.rb +0 -12
  143. data/doc/ex/gaussian_blur.rb +0 -11
  144. data/doc/ex/get_multiline_type_metrics.rb +0 -41
  145. data/doc/ex/get_pixels.rb +0 -47
  146. data/doc/ex/get_type_metrics.rb +0 -141
  147. data/doc/ex/gradientfill.rb +0 -27
  148. data/doc/ex/grav.rb +0 -45
  149. data/doc/ex/gravity.rb +0 -80
  150. data/doc/ex/group.rb +0 -26
  151. data/doc/ex/hatchfill.rb +0 -27
  152. data/doc/ex/image.rb +0 -44
  153. data/doc/ex/images/Apple.miff +0 -0
  154. data/doc/ex/images/Ballerina.jpg +0 -0
  155. data/doc/ex/images/Ballerina3.jpg +0 -0
  156. data/doc/ex/images/Button_0.gif +0 -0
  157. data/doc/ex/images/Button_1.gif +0 -0
  158. data/doc/ex/images/Button_2.gif +0 -0
  159. data/doc/ex/images/Button_3.gif +0 -0
  160. data/doc/ex/images/Button_4.gif +0 -0
  161. data/doc/ex/images/Button_5.gif +0 -0
  162. data/doc/ex/images/Button_6.gif +0 -0
  163. data/doc/ex/images/Button_7.gif +0 -0
  164. data/doc/ex/images/Button_8.gif +0 -0
  165. data/doc/ex/images/Button_9.gif +0 -0
  166. data/doc/ex/images/Button_A.gif +0 -0
  167. data/doc/ex/images/Button_B.gif +0 -0
  168. data/doc/ex/images/Button_C.gif +0 -0
  169. data/doc/ex/images/Button_D.gif +0 -0
  170. data/doc/ex/images/Button_E.gif +0 -0
  171. data/doc/ex/images/Button_F.gif +0 -0
  172. data/doc/ex/images/Button_G.gif +0 -0
  173. data/doc/ex/images/Button_H.gif +0 -0
  174. data/doc/ex/images/Button_I.gif +0 -0
  175. data/doc/ex/images/Button_J.gif +0 -0
  176. data/doc/ex/images/Button_K.gif +0 -0
  177. data/doc/ex/images/Button_L.gif +0 -0
  178. data/doc/ex/images/Button_M.gif +0 -0
  179. data/doc/ex/images/Button_N.gif +0 -0
  180. data/doc/ex/images/Button_O.gif +0 -0
  181. data/doc/ex/images/Button_P.gif +0 -0
  182. data/doc/ex/images/Button_Q.gif +0 -0
  183. data/doc/ex/images/Button_R.gif +0 -0
  184. data/doc/ex/images/Button_S.gif +0 -0
  185. data/doc/ex/images/Button_T.gif +0 -0
  186. data/doc/ex/images/Button_U.gif +0 -0
  187. data/doc/ex/images/Button_V.gif +0 -0
  188. data/doc/ex/images/Button_W.gif +0 -0
  189. data/doc/ex/images/Button_X.gif +0 -0
  190. data/doc/ex/images/Button_Y.gif +0 -0
  191. data/doc/ex/images/Button_Z.gif +0 -0
  192. data/doc/ex/images/Cheetah.jpg +0 -0
  193. data/doc/ex/images/Coffee.wmf +0 -0
  194. data/doc/ex/images/Flower_Hat.jpg +0 -0
  195. data/doc/ex/images/Gold_Statue.jpg +0 -0
  196. data/doc/ex/images/Hot_Air_Balloons.jpg +0 -0
  197. data/doc/ex/images/Hot_Air_Balloons_H.jpg +0 -0
  198. data/doc/ex/images/Leaf.miff +0 -0
  199. data/doc/ex/images/No.wmf +0 -0
  200. data/doc/ex/images/Polynesia.jpg +0 -0
  201. data/doc/ex/images/Red_Rocks.jpg +0 -0
  202. data/doc/ex/images/Rocks_On_Beach.miff +0 -0
  203. data/doc/ex/images/Shorts.jpg +0 -0
  204. data/doc/ex/images/Snake.wmf +0 -0
  205. data/doc/ex/images/Violin.jpg +0 -0
  206. data/doc/ex/images/Yellow_Rose.miff +0 -0
  207. data/doc/ex/images/big-duck.gif +0 -0
  208. data/doc/ex/images/duck.gif +0 -0
  209. data/doc/ex/images/duck0.gif +0 -0
  210. data/doc/ex/images/duck1.gif +0 -0
  211. data/doc/ex/images/duck10.gif +0 -0
  212. data/doc/ex/images/duck11.gif +0 -0
  213. data/doc/ex/images/duck12.gif +0 -0
  214. data/doc/ex/images/duck13.gif +0 -0
  215. data/doc/ex/images/duck14.gif +0 -0
  216. data/doc/ex/images/duck15.gif +0 -0
  217. data/doc/ex/images/duck2.gif +0 -0
  218. data/doc/ex/images/duck3.gif +0 -0
  219. data/doc/ex/images/duck4.gif +0 -0
  220. data/doc/ex/images/duck5.gif +0 -0
  221. data/doc/ex/images/duck6.gif +0 -0
  222. data/doc/ex/images/duck7.gif +0 -0
  223. data/doc/ex/images/duck8.gif +0 -0
  224. data/doc/ex/images/duck9.gif +0 -0
  225. data/doc/ex/images/graydient230x6.gif +0 -0
  226. data/doc/ex/images/image_with_profile.jpg +0 -0
  227. data/doc/ex/images/logo400x83.gif +0 -0
  228. data/doc/ex/images/model.miff +0 -0
  229. data/doc/ex/images/notimplemented.gif +0 -0
  230. data/doc/ex/images/smile.miff +0 -0
  231. data/doc/ex/images/spin.gif +0 -0
  232. data/doc/ex/implode.rb +0 -34
  233. data/doc/ex/level.rb +0 -11
  234. data/doc/ex/level_colors.rb +0 -11
  235. data/doc/ex/line.rb +0 -41
  236. data/doc/ex/line01.rb +0 -21
  237. data/doc/ex/mask.rb +0 -35
  238. data/doc/ex/matte_fill_to_border.rb +0 -39
  239. data/doc/ex/matte_floodfill.rb +0 -32
  240. data/doc/ex/matte_replace.rb +0 -39
  241. data/doc/ex/median_filter.rb +0 -28
  242. data/doc/ex/modulate.rb +0 -11
  243. data/doc/ex/mono.rb +0 -23
  244. data/doc/ex/morph.rb +0 -25
  245. data/doc/ex/mosaic.rb +0 -35
  246. data/doc/ex/motion_blur.rb +0 -11
  247. data/doc/ex/negate.rb +0 -11
  248. data/doc/ex/negate_channel.rb +0 -9
  249. data/doc/ex/nested_rvg.rb +0 -21
  250. data/doc/ex/nonzero.rb +0 -42
  251. data/doc/ex/normalize.rb +0 -11
  252. data/doc/ex/oil_paint.rb +0 -11
  253. data/doc/ex/opacity.rb +0 -37
  254. data/doc/ex/ordered_dither.rb +0 -11
  255. data/doc/ex/path.rb +0 -63
  256. data/doc/ex/pattern1.rb +0 -25
  257. data/doc/ex/pattern2.rb +0 -26
  258. data/doc/ex/polaroid.rb +0 -27
  259. data/doc/ex/polygon.rb +0 -23
  260. data/doc/ex/polygon01.rb +0 -21
  261. data/doc/ex/polyline.rb +0 -22
  262. data/doc/ex/polyline01.rb +0 -21
  263. data/doc/ex/posterize.rb +0 -8
  264. data/doc/ex/preview.rb +0 -8
  265. data/doc/ex/qbezierpath.rb +0 -52
  266. data/doc/ex/quad01.rb +0 -34
  267. data/doc/ex/quantize-m.rb +0 -25
  268. data/doc/ex/radial_blur.rb +0 -9
  269. data/doc/ex/raise.rb +0 -8
  270. data/doc/ex/random_threshold_channel.rb +0 -13
  271. data/doc/ex/rect01.rb +0 -14
  272. data/doc/ex/rect02.rb +0 -20
  273. data/doc/ex/rectangle.rb +0 -34
  274. data/doc/ex/reduce_noise.rb +0 -28
  275. data/doc/ex/remap.rb +0 -11
  276. data/doc/ex/remap_images.rb +0 -19
  277. data/doc/ex/resize_to_fill.rb +0 -8
  278. data/doc/ex/resize_to_fit.rb +0 -8
  279. data/doc/ex/roll.rb +0 -9
  280. data/doc/ex/rotate.rb +0 -44
  281. data/doc/ex/rotate_f.rb +0 -14
  282. data/doc/ex/roundrect.rb +0 -33
  283. data/doc/ex/rubyname.rb +0 -30
  284. data/doc/ex/rvg_clippath.rb +0 -12
  285. data/doc/ex/rvg_linecap.rb +0 -42
  286. data/doc/ex/rvg_linejoin.rb +0 -40
  287. data/doc/ex/rvg_opacity.rb +0 -18
  288. data/doc/ex/rvg_pattern.rb +0 -26
  289. data/doc/ex/rvg_stroke_dasharray.rb +0 -11
  290. data/doc/ex/segment.rb +0 -11
  291. data/doc/ex/sepiatone.rb +0 -7
  292. data/doc/ex/shade.rb +0 -11
  293. data/doc/ex/shadow.rb +0 -30
  294. data/doc/ex/shave.rb +0 -15
  295. data/doc/ex/shear.rb +0 -10
  296. data/doc/ex/sketch.rb +0 -17
  297. data/doc/ex/skewx.rb +0 -51
  298. data/doc/ex/skewy.rb +0 -47
  299. data/doc/ex/smile.rb +0 -125
  300. data/doc/ex/solarize.rb +0 -11
  301. data/doc/ex/sparse_color.rb +0 -54
  302. data/doc/ex/splice.rb +0 -8
  303. data/doc/ex/spread.rb +0 -11
  304. data/doc/ex/stegano.rb +0 -55
  305. data/doc/ex/stroke_dasharray.rb +0 -42
  306. data/doc/ex/stroke_fill.rb +0 -10
  307. data/doc/ex/stroke_linecap.rb +0 -44
  308. data/doc/ex/stroke_linejoin.rb +0 -48
  309. data/doc/ex/stroke_width.rb +0 -49
  310. data/doc/ex/swirl.rb +0 -17
  311. data/doc/ex/text.rb +0 -37
  312. data/doc/ex/text01.rb +0 -16
  313. data/doc/ex/text_align.rb +0 -36
  314. data/doc/ex/text_antialias.rb +0 -37
  315. data/doc/ex/text_styles.rb +0 -19
  316. data/doc/ex/text_undercolor.rb +0 -28
  317. data/doc/ex/texture_fill_to_border.rb +0 -34
  318. data/doc/ex/texture_floodfill.rb +0 -32
  319. data/doc/ex/texturefill.rb +0 -24
  320. data/doc/ex/threshold.rb +0 -13
  321. data/doc/ex/to_blob.rb +0 -13
  322. data/doc/ex/translate.rb +0 -39
  323. data/doc/ex/transparent.rb +0 -38
  324. data/doc/ex/transpose.rb +0 -9
  325. data/doc/ex/transverse.rb +0 -9
  326. data/doc/ex/tref01.rb +0 -24
  327. data/doc/ex/triangle01.rb +0 -15
  328. data/doc/ex/trim.rb +0 -23
  329. data/doc/ex/tspan01.rb +0 -17
  330. data/doc/ex/tspan02.rb +0 -17
  331. data/doc/ex/tspan03.rb +0 -19
  332. data/doc/ex/unsharp_mask.rb +0 -28
  333. data/doc/ex/viewex.rb +0 -33
  334. data/doc/ex/vignette.rb +0 -12
  335. data/doc/ex/watermark.rb +0 -27
  336. data/doc/ex/wave.rb +0 -9
  337. data/doc/ex/wet_floor.rb +0 -58
  338. data/doc/ex/writing_mode01.rb +0 -26
  339. data/doc/ex/writing_mode02.rb +0 -26
  340. data/doc/ilist.html +0 -2056
  341. data/doc/image1.html +0 -4680
  342. data/doc/image2.html +0 -3665
  343. data/doc/image3.html +0 -4522
  344. data/doc/imageattrs.html +0 -1638
  345. data/doc/imusage.html +0 -514
  346. data/doc/index.html +0 -416
  347. data/doc/info.html +0 -1499
  348. data/doc/magick.html +0 -565
  349. data/doc/optequiv.html +0 -2435
  350. data/doc/rvg.html +0 -975
  351. data/doc/rvgclip.html +0 -248
  352. data/doc/rvggroup.html +0 -305
  353. data/doc/rvgimage.html +0 -289
  354. data/doc/rvgpattern.html +0 -475
  355. data/doc/rvgshape.html +0 -406
  356. data/doc/rvgstyle.html +0 -270
  357. data/doc/rvgtext.html +0 -465
  358. data/doc/rvgtspan.html +0 -238
  359. data/doc/rvgtut.html +0 -530
  360. data/doc/rvguse.html +0 -145
  361. data/doc/rvgxform.html +0 -294
  362. data/doc/scripts/doc.js +0 -22
  363. data/doc/scripts/stripeTables.js +0 -23
  364. data/doc/struct.html +0 -1339
  365. data/doc/usage.html +0 -1621
  366. data/examples/constitute.rb +0 -7
  367. data/examples/crop_with_gravity.rb +0 -42
  368. data/examples/demo.rb +0 -324
  369. data/examples/describe.rb +0 -43
  370. data/examples/find_similar_region.rb +0 -34
  371. data/examples/histogram.rb +0 -321
  372. data/examples/identify.rb +0 -185
  373. data/examples/image_opacity.rb +0 -29
  374. data/examples/import_export.rb +0 -31
  375. data/examples/pattern_fill.rb +0 -38
  376. data/examples/rotating_text.rb +0 -44
  377. data/examples/spinner.rb +0 -49
  378. data/examples/thumbnail.rb +0 -64
  379. data/examples/vignette.rb +0 -78
  380. data/spec/rmagick/ImageList1_spec.rb +0 -24
  381. data/spec/rmagick/draw_spec.rb +0 -156
  382. data/spec/rmagick/image/blue_shift_spec.rb +0 -16
  383. data/spec/rmagick/image/composite_spec.rb +0 -140
  384. data/spec/rmagick/image/constitute_spec.rb +0 -15
  385. data/spec/rmagick/image/dispatch_spec.rb +0 -18
  386. data/spec/rmagick/image/from_blob_spec.rb +0 -14
  387. data/spec/rmagick/image/ping_spec.rb +0 -14
  388. data/spec/rmagick/image/properties_spec.rb +0 -29
  389. data/spec/spec_helper.rb +0 -4
  390. data/test/Image1.rb +0 -565
  391. data/test/Image2.rb +0 -1304
  392. data/test/Image3.rb +0 -1030
  393. data/test/ImageList1.rb +0 -806
  394. data/test/ImageList2.rb +0 -385
  395. data/test/Image_attributes.rb +0 -697
  396. data/test/Import_Export.rb +0 -121
  397. data/test/Info.rb +0 -345
  398. data/test/Magick.rb +0 -321
  399. data/test/Pixel.rb +0 -116
  400. data/test/Preview.rb +0 -57
  401. data/test/cmyk.icm +0 -0
  402. data/test/srgb.icm +0 -0
  403. data/test/test_all_basic.rb +0 -38
  404. data/test/tmpnam_test.rb +0 -50
  405. data/wercker.yml +0 -10
@@ -16,27 +16,56 @@ static Image *clone_imagelist(Image *);
16
16
  static Image *images_from_imagelist(VALUE);
17
17
  static long imagelist_length(VALUE);
18
18
  static long check_imagelist_length(VALUE);
19
- static VALUE imagelist_scene_eq(VALUE, VALUE);
20
19
  static void imagelist_push(VALUE, VALUE);
21
20
  static VALUE ImageList_new(void);
22
21
 
23
22
 
23
+ DEFINE_GVL_STUB3(AppendImages, const Image *, const MagickBooleanType, ExceptionInfo *);
24
+ DEFINE_GVL_STUB5(CloneImage, const Image *, const size_t, const size_t, const MagickBooleanType, ExceptionInfo *);
25
+ DEFINE_GVL_STUB2(CloneImageList, const Image *, ExceptionInfo *);
26
+ DEFINE_GVL_STUB2(CoalesceImages, const Image *, ExceptionInfo *);
27
+ DEFINE_GVL_STUB2(DisposeImages, const Image *, ExceptionInfo *);
28
+ DEFINE_GVL_STUB3(EvaluateImages, const Image *, const MagickEvaluateOperator, ExceptionInfo *);
29
+ DEFINE_GVL_STUB4(ImagesToBlob, const ImageInfo *, Image *, size_t *, ExceptionInfo *);
30
+ DEFINE_GVL_STUB3(MergeImageLayers, Image *, const LayerMethod, ExceptionInfo *);
31
+ DEFINE_GVL_STUB3(MontageImages, const Image *, const MontageInfo *, ExceptionInfo *);
32
+ DEFINE_GVL_STUB3(MorphImages, const Image *, const size_t, ExceptionInfo *);
33
+ DEFINE_GVL_STUB2(OptimizeImageLayers, const Image *, ExceptionInfo *);
34
+ DEFINE_GVL_STUB2(OptimizePlusImageLayers, const Image *, ExceptionInfo *);
35
+ #if defined(IMAGEMAGICK_7)
36
+ DEFINE_GVL_STUB3(AnimateImages, const ImageInfo *, Image *, ExceptionInfo *);
37
+ DEFINE_GVL_STUB3(CombineImages, const Image *, const ColorspaceType, ExceptionInfo *);
38
+ DEFINE_GVL_STUB3(CompareImagesLayers, const Image *, const LayerMethod, ExceptionInfo *);
39
+ DEFINE_GVL_STUB3(QuantizeImages, const QuantizeInfo *, Image *, ExceptionInfo *);
40
+ DEFINE_GVL_STUB4(RemapImages, const QuantizeInfo *, Image *, const Image *, ExceptionInfo *);
41
+ DEFINE_GVL_STUB3(WriteImage, const ImageInfo *, Image *, ExceptionInfo *);
42
+ #else
43
+ DEFINE_GVL_STUB2(AnimateImages, const ImageInfo *, Image *);
44
+ DEFINE_GVL_STUB3(CombineImages, const Image *, const ChannelType, ExceptionInfo *);
45
+ DEFINE_GVL_STUB3(CompareImageLayers, const Image *, const ImageLayerMethod, ExceptionInfo *);
46
+ DEFINE_GVL_STUB2(DeconstructImages, const Image *, ExceptionInfo *);
47
+ DEFINE_GVL_STUB2(QuantizeImages, const QuantizeInfo *, Image *);
48
+ DEFINE_GVL_STUB3(RemapImages, const QuantizeInfo *, Image *, const Image *);
49
+ DEFINE_GVL_STUB2(WriteImage, const ImageInfo *, Image *);
50
+ #endif
24
51
 
52
+ DEFINE_GVL_VOID_STUB6(CompositeLayers, Image *, const CompositeOperator, Image *, const ssize_t, const ssize_t, ExceptionInfo *);
53
+ DEFINE_GVL_VOID_STUB2(OptimizeImageTransparency, const Image *, ExceptionInfo *);
54
+ DEFINE_GVL_VOID_STUB2(RemoveDuplicateLayers, Image **, ExceptionInfo *);
55
+ DEFINE_GVL_VOID_STUB2(RemoveZeroDelayLayers, Image **, ExceptionInfo *);
25
56
 
26
57
 
27
58
  /**
28
59
  * Repeatedly display the images in the images array to an XWindow screen. The
29
- * "delay" argument is the number of 1/100ths of a second (0 to 65535) to delay
60
+ * +delay+ argument is the number of 1/100ths of a second (0 to 65535) to delay
30
61
  * between images.
31
62
  *
32
- * Ruby usage:
33
- * - @verbatim ImageList#animate @endverbatim
34
- * - @verbatim ImageList#animate(delay) @endverbatim
63
+ * @overload animate
64
+ *
65
+ * @overload animate(delay)
66
+ * @param delay [Numeric] the length of time between each image in an animation
35
67
  *
36
- * @param argc number of input arguments
37
- * @param argv array of input arguments
38
- * @param self this object
39
- * @return self
68
+ * @return [Magick::ImageList] self
40
69
  */
41
70
 
42
71
  VALUE
@@ -45,7 +74,15 @@ ImageList_animate(int argc, VALUE *argv, VALUE self)
45
74
  Image *images;
46
75
  Info *info;
47
76
  VALUE info_obj;
77
+ unsigned int delay;
78
+ #if defined(IMAGEMAGICK_7)
79
+ ExceptionInfo *exception;
80
+ #endif
48
81
 
82
+ if (argc == 1)
83
+ {
84
+ delay = NUM2UINT(argv[0]);
85
+ }
49
86
  if (argc > 1)
50
87
  {
51
88
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
@@ -60,19 +97,27 @@ ImageList_animate(int argc, VALUE *argv, VALUE self)
60
97
  if (argc == 1)
61
98
  {
62
99
  Image *img;
63
- unsigned int delay;
64
100
 
65
- delay = NUM2UINT(argv[0]);
66
101
  for (img = images; img; img = GetNextImageInList(img))
67
102
  {
68
103
  img->delay = delay;
69
104
  }
70
105
  }
71
106
 
72
- Data_Get_Struct(info_obj, Info, info);
73
- (void) AnimateImages(info, images);
74
- rm_check_image_exception(images, RetainOnError);
107
+ TypedData_Get_Struct(info_obj, Info, &rm_info_data_type, info);
108
+ #if defined(IMAGEMAGICK_7)
109
+ exception = AcquireExceptionInfo();
110
+ GVL_STRUCT_TYPE(AnimateImages) args = { info, images, exception };
111
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(AnimateImages), &args);
75
112
  rm_split(images);
113
+ CHECK_EXCEPTION();
114
+ DestroyExceptionInfo(exception);
115
+ #else
116
+ GVL_STRUCT_TYPE(AnimateImages) args = { info, images };
117
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(AnimateImages), &args);
118
+ rm_split(images);
119
+ rm_check_image_exception(images, RetainOnError);
120
+ #endif
76
121
 
77
122
  RB_GC_GUARD(info_obj);
78
123
 
@@ -81,14 +126,10 @@ ImageList_animate(int argc, VALUE *argv, VALUE self)
81
126
 
82
127
 
83
128
  /**
84
- * Append all the images by calling ImageAppend.
85
- *
86
- * Ruby usage:
87
- * - @verbatim ImageList#append(stack) @endverbatim
129
+ * Append all the images
88
130
  *
89
- * @param self this object
90
- * @param stack_arg the stack of images
91
- * @return a Frame object for the result
131
+ * @param stack_arg [Magick::ImageList] the stack of images
132
+ * @return [Magick::Image] a frame object for the result
92
133
  */
93
134
  VALUE
94
135
  ImageList_append(VALUE self, VALUE stack_arg)
@@ -105,25 +146,20 @@ ImageList_append(VALUE self, VALUE stack_arg)
105
146
  stack = RTEST(stack_arg);
106
147
 
107
148
  exception = AcquireExceptionInfo();
108
- new_image = AppendImages(images, stack, exception);
149
+ GVL_STRUCT_TYPE(AppendImages) args = { images, stack, exception };
150
+ new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(AppendImages), &args);
109
151
  rm_split(images);
110
152
  rm_check_exception(exception, new_image, DestroyOnError);
111
- (void) DestroyExceptionInfo(exception);
112
-
113
- rm_ensure_result(new_image);
153
+ DestroyExceptionInfo(exception);
114
154
 
115
155
  return rm_image_new(new_image);
116
156
  }
117
157
 
118
158
 
119
159
  /**
120
- * Average all images together by calling AverageImages.
121
- *
122
- * Ruby usage:
123
- * - @verbatim ImageList#average @endverbatim
160
+ * Average all images together
124
161
  *
125
- * @param self this object
126
- * @return a Frame object for the averaged image
162
+ * @return [Magick::Image] a frame object for the averaged image
127
163
  */
128
164
  VALUE
129
165
  ImageList_average(VALUE self)
@@ -135,34 +171,23 @@ ImageList_average(VALUE self)
135
171
  images = images_from_imagelist(self);
136
172
 
137
173
  exception = AcquireExceptionInfo();
138
- #if defined(HAVE_EVALUATEIMAGES)
139
- new_image = EvaluateImages(images, MeanEvaluateOperator, exception);
140
- #else
141
- new_image = AverageImages(images, exception);
142
- #endif
143
-
174
+ GVL_STRUCT_TYPE(EvaluateImages) args = { images, MeanEvaluateOperator, exception };
175
+ new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(EvaluateImages), &args);
144
176
  rm_split(images);
145
177
  rm_check_exception(exception, new_image, DestroyOnError);
146
- (void) DestroyExceptionInfo(exception);
147
-
148
- rm_ensure_result(new_image);
178
+ DestroyExceptionInfo(exception);
149
179
 
150
180
  return rm_image_new(new_image);
151
181
  }
152
182
 
153
183
 
154
184
  /**
155
- * Call CoalesceImages.
156
- *
157
- * Ruby usage:
158
- * - @verbatim ImageList#coalesce @endverbatim
185
+ * Composites a set of images while respecting any page offsets and disposal methods.
159
186
  *
160
- * Notes:
161
- * - Respects the delay, matte, and start_loop fields in each image.
187
+ * - Respects the delay, matte, and start_loop fields in each image.
162
188
  *
163
- * @param self this object
164
- * @return a new Image with the coalesced image sequence return stored in the
165
- * images array
189
+ * @return [Magick::ImageList] a new image with the coalesced image sequence return stored in the
190
+ * images array
166
191
  */
167
192
  VALUE
168
193
  ImageList_coalesce(VALUE self)
@@ -174,32 +199,124 @@ ImageList_coalesce(VALUE self)
174
199
  images = images_from_imagelist(self);
175
200
 
176
201
  exception = AcquireExceptionInfo();
177
- new_images = CoalesceImages(images, exception);
202
+ GVL_STRUCT_TYPE(CoalesceImages) args = { images, exception };
203
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CoalesceImages), &args);
178
204
  rm_split(images);
179
205
  rm_check_exception(exception, new_images, DestroyOnError);
180
- (void) DestroyExceptionInfo(exception);
181
-
182
- rm_ensure_result(new_images);
206
+ DestroyExceptionInfo(exception);
183
207
 
184
208
  return rm_imagelist_from_images(new_images);
185
209
  }
186
210
 
187
211
 
188
212
  /**
189
- * Equivalent to convert's -layers composite option.
213
+ * Combines the images using the specified colorspace.
190
214
  *
191
- * Ruby usage:
192
- * - @verbatim ImageList#composite_layers(images) @endverbatim
193
- * - @verbatim ImageList#composite_layers(images,operator) @endverbatim
215
+ * @overload combine
194
216
  *
195
- * Notes:
196
- * - Default operator is OverCompositeOp
217
+ * @overload combine(colorspace)
218
+ * @param colorspace [Magick::ColorspaceType] the colorspace
197
219
  *
198
- * @param argc number of input arguments
199
- * @param argv array of input arguments
200
- * @param self this object
201
- * @return a new imagelist
202
- * @see mogrify.c in ImageMagick
220
+ * @return [Magick::Image] a new image
221
+ */
222
+ VALUE ImageList_combine(int argc, VALUE *argv, VALUE self)
223
+ {
224
+ #if defined(IMAGEMAGICK_6)
225
+ ChannelType channel;
226
+ ColorspaceType old_colorspace;
227
+ #endif
228
+ ColorspaceType colorspace;
229
+ long len;
230
+ Image *images, *new_image;
231
+ ExceptionInfo *exception;
232
+
233
+ len = check_imagelist_length(self);
234
+
235
+ switch (argc)
236
+ {
237
+ case 1:
238
+ VALUE_TO_ENUM(argv[0], colorspace, ColorspaceType);
239
+ break;
240
+ case 0:
241
+ colorspace = sRGBColorspace;
242
+ break;
243
+ default:
244
+ rb_raise(rb_eArgError, "wrong number of arguments (expected 1, got %d)", argc);
245
+ break;
246
+ }
247
+
248
+ #if defined(IMAGEMAGICK_7)
249
+ if (len > 5)
250
+ {
251
+ rb_raise(rb_eArgError, "invalid number of images in this image list");
252
+ }
253
+ if (len == 5 && colorspace != CMYKColorspace)
254
+ {
255
+ rb_raise(rb_eArgError, "invalid number of images in this image list");
256
+ }
257
+ #else
258
+ channel = RedChannel;
259
+ switch (len)
260
+ {
261
+ case 5:
262
+ if (colorspace == CMYKColorspace)
263
+ channel |= AlphaChannel;
264
+ else
265
+ rb_raise(rb_eArgError, "invalid number of images in this image list");
266
+ case 4:
267
+ if (colorspace == CMYKColorspace)
268
+ channel |= IndexChannel;
269
+ else
270
+ channel |= AlphaChannel;
271
+ case 3:
272
+ channel |= GreenChannel;
273
+ channel |= BlueChannel;
274
+ break;
275
+ case 2:
276
+ channel |= AlphaChannel;
277
+ break;
278
+ case 1:
279
+ break;
280
+ default:
281
+ rb_raise(rb_eArgError, "invalid number of images in this image list");
282
+ break;
283
+ }
284
+ #endif
285
+
286
+ images = images_from_imagelist(self);
287
+ exception = AcquireExceptionInfo();
288
+ #if defined(IMAGEMAGICK_6)
289
+ old_colorspace = images->colorspace;
290
+ SetImageColorspace(images, colorspace);
291
+ GVL_STRUCT_TYPE(CombineImages) args = { images, channel, exception };
292
+ #else
293
+ GVL_STRUCT_TYPE(CombineImages) args = { images, colorspace, exception };
294
+ #endif
295
+ new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CombineImages), &args);
296
+
297
+ rm_split(images);
298
+ #if defined(IMAGEMAGICK_6)
299
+ images->colorspace = old_colorspace;
300
+ #endif
301
+ rm_check_exception(exception, new_image, DestroyOnError);
302
+ DestroyExceptionInfo(exception);
303
+
304
+ return rm_image_new(new_image);
305
+ }
306
+
307
+
308
+ /**
309
+ * An image from source images is composited over an image from receiver's list until one list is finished.
310
+ *
311
+ * @overload composite_layers(images)
312
+ * @param images [Magick::ImageList] the source images
313
+ *
314
+ * @overload composite_layers(images, operator)
315
+ * - Default operator is {Magick::OverCompositeOp}
316
+ * @param images [Magick::ImageList] the source images
317
+ * @param operator [Magick::CompositeOperator] the operator
318
+ *
319
+ * @return [Magick::ImageList] a new imagelist
203
320
  */
204
321
  VALUE
205
322
  ImageList_composite_layers(int argc, VALUE *argv, VALUE self)
@@ -229,20 +346,21 @@ ImageList_composite_layers(int argc, VALUE *argv, VALUE self)
229
346
 
230
347
  source = images_from_imagelist(source_images);
231
348
 
232
- SetGeometry(new_images,&geometry);
233
- (void) ParseAbsoluteGeometry(new_images->geometry, &geometry);
349
+ SetGeometry(new_images, &geometry);
350
+ ParseAbsoluteGeometry(new_images->geometry, &geometry);
234
351
 
235
352
  geometry.width = source->page.width != 0 ? source->page.width : source->columns;
236
353
  geometry.height = source->page.height != 0 ? source->page.height : source->rows;
237
- GravityAdjustGeometry(new_images->page.width != 0 ? new_images->page.width : new_images->columns
238
- , new_images->page.height != 0 ? new_images->page.height : new_images->rows
239
- , new_images->gravity, &geometry);
354
+ GravityAdjustGeometry(new_images->page.width != 0 ? new_images->page.width : new_images->columns,
355
+ new_images->page.height != 0 ? new_images->page.height : new_images->rows,
356
+ new_images->gravity, &geometry);
240
357
 
241
358
  exception = AcquireExceptionInfo();
242
- CompositeLayers(new_images, operator, source, geometry.x, geometry.y, exception);
359
+ GVL_STRUCT_TYPE(CompositeLayers) args = { new_images, operator, source, geometry.x, geometry.y, exception };
360
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CompositeLayers), &args);
243
361
  rm_split(source);
244
362
  rm_check_exception(exception, new_images, DestroyOnError);
245
- (void) DestroyExceptionInfo(exception);
363
+ DestroyExceptionInfo(exception);
246
364
 
247
365
  RB_GC_GUARD(source_images);
248
366
 
@@ -254,11 +372,7 @@ ImageList_composite_layers(int argc, VALUE *argv, VALUE self)
254
372
  * Compare each image with the next in a sequence and returns the maximum
255
373
  * bounding region of any pixel differences it discovers.
256
374
  *
257
- * Ruby usage:
258
- * - @verbatim ImageList#deconstruct @endverbatim
259
- *
260
- * @param self this object
261
- * @return a new imagelist
375
+ * @return [Magick::ImageList] a new imagelist
262
376
  */
263
377
  VALUE
264
378
  ImageList_deconstruct(VALUE self)
@@ -268,12 +382,16 @@ ImageList_deconstruct(VALUE self)
268
382
 
269
383
  images = images_from_imagelist(self);
270
384
  exception = AcquireExceptionInfo();
271
- new_images = DeconstructImages(images, exception);
385
+ #if defined(IMAGEMAGICK_7)
386
+ GVL_STRUCT_TYPE(CompareImagesLayers) args = { images, CompareAnyLayer, exception };
387
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CompareImagesLayers), &args);
388
+ #else
389
+ GVL_STRUCT_TYPE(DeconstructImages) args = { images, exception };
390
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(DeconstructImages), &args);
391
+ #endif
272
392
  rm_split(images);
273
393
  rm_check_exception(exception, new_images, DestroyOnError);
274
- (void) DestroyExceptionInfo(exception);
275
-
276
- rm_ensure_result(new_images);
394
+ DestroyExceptionInfo(exception);
277
395
 
278
396
  return rm_imagelist_from_images(new_images);
279
397
  }
@@ -282,11 +400,7 @@ ImageList_deconstruct(VALUE self)
282
400
  /**
283
401
  * Display all the images to an X window screen.
284
402
  *
285
- * Ruby usage:
286
- * - @verbatim ImageList#display @endverbatim
287
- *
288
- * @param self this object
289
- * @return self
403
+ * @return [Magick::ImageList] self
290
404
  */
291
405
  VALUE
292
406
  ImageList_display(VALUE self)
@@ -294,17 +408,27 @@ ImageList_display(VALUE self)
294
408
  Image *images;
295
409
  Info *info;
296
410
  VALUE info_obj;
411
+ #if defined(IMAGEMAGICK_7)
412
+ ExceptionInfo *exception;
413
+ #endif
297
414
 
298
415
  // Create a new Info object to use with this call
299
416
  info_obj = rm_info_new();
300
- Data_Get_Struct(info_obj, Info, info);
417
+ TypedData_Get_Struct(info_obj, Info, &rm_info_data_type, info);
301
418
 
302
419
  // Convert the images array to an images sequence.
303
420
  images = images_from_imagelist(self);
304
-
305
- (void) DisplayImages(info, images);
421
+ #if defined(IMAGEMAGICK_7)
422
+ exception = AcquireExceptionInfo();
423
+ DisplayImages(info, images, exception);
424
+ rm_split(images);
425
+ CHECK_EXCEPTION();
426
+ DestroyExceptionInfo(exception);
427
+ #else
428
+ DisplayImages(info, images);
306
429
  rm_split(images);
307
430
  rm_check_image_exception(images, RetainOnError);
431
+ #endif
308
432
 
309
433
  RB_GC_GUARD(info_obj);
310
434
 
@@ -315,14 +439,7 @@ ImageList_display(VALUE self)
315
439
  /**
316
440
  * Merge all the images into a single image.
317
441
  *
318
- * Ruby usage:
319
- * - @verbatim ImageList#flatten_images @endverbatim
320
- *
321
- * Notes:
322
- * - Can't use "flatten" because that's an Array method
323
- *
324
- * @param self this object
325
- * @return the new image
442
+ * @return [Magick::ImageList] the new image
326
443
  */
327
444
  VALUE
328
445
  ImageList_flatten_images(VALUE self)
@@ -333,164 +450,28 @@ ImageList_flatten_images(VALUE self)
333
450
  images = images_from_imagelist(self);
334
451
  exception = AcquireExceptionInfo();
335
452
 
336
- #if defined(HAVE_ENUM_FLATTENLAYER)
337
- new_image = MergeImageLayers(images, FlattenLayer, exception);
338
- #else
339
- new_image = FlattenImages(images, exception);
340
- #endif
341
-
342
- rm_split(images);
343
- rm_check_exception(exception, new_image, DestroyOnError);
344
- (void) DestroyExceptionInfo(exception);
345
-
346
- rm_ensure_result(new_image);
347
-
348
- return rm_image_new(new_image);
349
- }
350
-
351
-
352
- /**
353
- * Apply fx on the images.
354
- *
355
- * Ruby usage:
356
- * - @verbatim ImageList#fx(expression) @endverbatim
357
- * - @verbatim ImageList#fx(expression, channel) @endverbatim
358
- * - @verbatim ImageList#fx(expression, channel, ...) @endverbatim
359
- *
360
- * Notes:
361
- * - Default channel is AllChannels
362
- *
363
- * @param argc number of input arguments
364
- * @param argv array of input arguments
365
- * @param self this object
366
- * @return a new image
367
- */
368
- VALUE
369
- ImageList_fx(int argc, VALUE *argv, VALUE self)
370
- {
371
- Image *images, *new_image;
372
- char *expression;
373
- ChannelType channels;
374
- ExceptionInfo *exception;
375
-
376
-
377
- channels = extract_channels(&argc, argv);
453
+ GVL_STRUCT_TYPE(MergeImageLayers) args = { images, FlattenLayer, exception };
454
+ new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
378
455
 
379
- // There must be exactly 1 remaining argument.
380
- if (argc == 0)
381
- {
382
- rb_raise(rb_eArgError, "wrong number of arguments (0 for 1 or more)");
383
- }
384
- else if (argc > 1)
385
- {
386
- raise_ChannelType_error(argv[argc-1]);
387
- }
388
-
389
- expression = StringValuePtr(argv[0]);
390
-
391
- images = images_from_imagelist(self);
392
- exception = AcquireExceptionInfo();
393
- new_image = FxImageChannel(images, channels, expression, exception);
394
456
  rm_split(images);
395
457
  rm_check_exception(exception, new_image, DestroyOnError);
396
- (void) DestroyExceptionInfo(exception);
397
-
398
- rm_ensure_result(new_image);
458
+ DestroyExceptionInfo(exception);
399
459
 
400
460
  return rm_image_new(new_image);
401
461
  }
402
462
 
403
463
 
404
464
  /**
405
- * Call MapImages.
406
- *
407
- * Ruby usage:
408
- * - @verbatim ImageList#map(reference) @endverbatim
409
- * - @verbatim ImageList#map(reference, dither) @endverbatim
410
- *
411
- * Notes:
412
- * - Default dither is false
413
- * - Sets \@scene to self.scene
414
- *
415
- * @param argc number of input arguments
416
- * @param argv array of input arguments
417
- * @param self this object
418
- * @return a new ImageList with mapped images.
419
- */
420
- VALUE
421
- ImageList_map(int argc, VALUE *argv, VALUE self)
422
- {
423
- Image *images, *new_images = NULL;
424
- Image *map;
425
- unsigned int dither = MagickFalse;
426
- VALUE scene, new_imagelist, t;
427
- ExceptionInfo *exception;
428
-
429
- #if defined(HAVE_REMAPIMAGES)
430
- QuantizeInfo quantize_info;
431
- rb_warning("ImageList#map is deprecated. Use ImageList#remap instead.");
432
- #endif
433
-
434
- switch (argc)
435
- {
436
- case 2:
437
- dither = RTEST(argv[1]);
438
- case 1:
439
- t = rm_cur_image(argv[0]);
440
- map = rm_check_destroyed(t);
441
- break;
442
- default:
443
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
444
- break;
445
- }
446
-
447
-
448
- // Convert image array to image sequence, clone image sequence.
449
- exception = AcquireExceptionInfo();
450
-
451
- images = images_from_imagelist(self);
452
- new_images = CloneImageList(images, exception);
453
- rm_split(images);
454
- rm_check_exception(exception, new_images, DestroyOnError);
455
- (void) DestroyExceptionInfo(exception);
456
-
457
- rm_ensure_result(new_images);
458
-
459
- // Call ImageMagick
460
- #if defined(HAVE_REMAPIMAGES)
461
- GetQuantizeInfo(&quantize_info);
462
- quantize_info.dither = dither;
463
- (void) RemapImages(&quantize_info, new_images, map);
464
- #else
465
- (void) MapImages(new_images, map, dither);
466
- #endif
467
- rm_check_image_exception(new_images, DestroyOnError);
468
-
469
- // Set @scene in new ImageList object to same value as in self.
470
- new_imagelist = rm_imagelist_from_images(new_images);
471
- scene = rb_iv_get(self, "@scene");
472
- (void) imagelist_scene_eq(new_imagelist, scene);
473
-
474
- RB_GC_GUARD(scene);
475
- RB_GC_GUARD(new_imagelist);
476
- RB_GC_GUARD(t);
477
-
478
- return new_imagelist;
479
- }
480
-
481
-
482
- /**
483
- * Call MontageImages.
465
+ * Tile one or more thumbnails across an image canvas.
484
466
  *
485
- * Ruby usage:
486
- * - @verbatim ImageList#montage <{parm block}> @endverbatim
467
+ * @overload montage
487
468
  *
488
- * Notes:
489
- * - Creates Montage object, yields to block if present in Montage object's
490
- * scope.
469
+ * @overload montage
470
+ * Creates {Magick::ImageList::Montage} object, yields to block
471
+ * if present in {Magick::ImageList::Montage} object's scope.
472
+ * @yield [Magick::ImageList::Montage]
491
473
  *
492
- * @param self this object
493
- * @return a new image list
474
+ * @return [Magick::ImageList] a new image list
494
475
  */
495
476
  VALUE
496
477
  ImageList_montage(VALUE self)
@@ -500,38 +481,37 @@ ImageList_montage(VALUE self)
500
481
  Image *new_images, *images;
501
482
  ExceptionInfo *exception;
502
483
 
503
- // Create a new instance of the Magick::Montage class
484
+ // Create a new instance of the Magick::ImageList::Montage class
504
485
  montage_obj = rm_montage_new();
505
486
  if (rb_block_given_p())
506
487
  {
507
- // Run the block in the instance's context, allowing the app to modify the
508
- // object's attributes.
509
- (void) rb_obj_instance_eval(0, NULL, montage_obj);
488
+ rb_yield(montage_obj);
510
489
  }
511
490
 
512
- Data_Get_Struct(montage_obj, Montage, montage);
491
+ TypedData_Get_Struct(montage_obj, Montage, &rm_montage_data_type, montage);
513
492
 
514
493
  images = images_from_imagelist(self);
515
494
 
516
- // If app specified a non-default composition operator, use it for all images.
517
- if (montage->compose != UndefinedCompositeOp)
495
+ for (Image *image = images; image; image = GetNextImageInList(image))
518
496
  {
519
- Image *i;
520
- for (i = images; i; i = GetNextImageInList(i))
497
+ if (montage->compose != UndefinedCompositeOp)
521
498
  {
522
- i->compose = montage->compose;
499
+ image->compose = montage->compose;
523
500
  }
501
+ image->background_color = montage->info->background_color;
502
+ image->border_color = montage->info->border_color;
503
+ image->matte_color = montage->info->matte_color;
504
+ image->gravity = montage->info->gravity;
524
505
  }
525
506
 
526
507
  exception = AcquireExceptionInfo();
527
508
 
528
509
  // MontageImage can return more than one image.
529
- new_images = MontageImages(images, montage->info, exception);
510
+ GVL_STRUCT_TYPE(MontageImages) args = { images, montage->info, exception };
511
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MontageImages), &args);
530
512
  rm_split(images);
531
513
  rm_check_exception(exception, new_images, DestroyOnError);
532
- (void) DestroyExceptionInfo(exception);
533
-
534
- rm_ensure_result(new_images);
514
+ DestroyExceptionInfo(exception);
535
515
 
536
516
  RB_GC_GUARD(montage_obj);
537
517
 
@@ -541,17 +521,11 @@ ImageList_montage(VALUE self)
541
521
 
542
522
  /**
543
523
  * Requires a minimum of two images. The first image is transformed into the
544
- * second by a number of intervening images as specified by "number_images".
524
+ * second by a number of intervening images as specified by "nimages".
545
525
  *
546
- * Ruby usage:
547
- * - @verbatim ImageList#morph(number_images) @endverbatim
548
- *
549
- * Notes:
550
- * - Sets \@scenes to 0
551
- *
552
- * @param self this object
553
- * @param nimages the number of images
554
- * @return a new image list with the images array set to the morph sequence.
526
+ * @note Sets +@scenes+ to 0
527
+ * @param nimages [Numeric] the number of images
528
+ * @return [Magick::ImageList] a new image list with the images array set to the morph sequence.
555
529
  */
556
530
  VALUE
557
531
  ImageList_morph(VALUE self, VALUE nimages)
@@ -568,14 +542,13 @@ ImageList_morph(VALUE self, VALUE nimages)
568
542
  rb_raise(rb_eArgError, "number of intervening images must be > 0");
569
543
  }
570
544
 
571
- exception = AcquireExceptionInfo();
572
545
  images = images_from_imagelist(self);
573
- new_images = MorphImages(images, (unsigned long)number_images, exception);
546
+ exception = AcquireExceptionInfo();
547
+ GVL_STRUCT_TYPE(MorphImages) args = { images, number_images, exception };
548
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MorphImages), &args);
574
549
  rm_split(images);
575
550
  rm_check_exception(exception, new_images, DestroyOnError);
576
- (void) DestroyExceptionInfo(exception);
577
-
578
- rm_ensure_result(new_images);
551
+ DestroyExceptionInfo(exception);
579
552
 
580
553
  return rm_imagelist_from_images(new_images);
581
554
  }
@@ -584,11 +557,7 @@ ImageList_morph(VALUE self, VALUE nimages)
584
557
  /**
585
558
  * Merge all the images into a single image.
586
559
  *
587
- * Ruby usage:
588
- * - @verbatim ImageList#mosaic @endverbatim
589
- *
590
- * @param self this object
591
- * @return the new image
560
+ * @return [Magick::Image] the new image
592
561
  */
593
562
  VALUE
594
563
  ImageList_mosaic(VALUE self)
@@ -596,139 +565,169 @@ ImageList_mosaic(VALUE self)
596
565
  Image *images, *new_image;
597
566
  ExceptionInfo *exception;
598
567
 
599
- exception = AcquireExceptionInfo();
600
568
  images = images_from_imagelist(self);
601
569
 
602
- #if defined(HAVE_ENUM_MOSAICLAYER)
603
- new_image = MergeImageLayers(images, MosaicLayer, exception);
604
- #else
605
- new_image = MosaicImages(images, exception);
606
- #endif
570
+ exception = AcquireExceptionInfo();
571
+ GVL_STRUCT_TYPE(MergeImageLayers) args = { images, MosaicLayer, exception };
572
+ new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
607
573
 
608
574
  rm_split(images);
609
575
  rm_check_exception(exception, new_image, DestroyOnError);
610
- (void) DestroyExceptionInfo(exception);
611
-
612
- rm_ensure_result(new_image);
576
+ DestroyExceptionInfo(exception);
613
577
 
614
578
  return rm_image_new(new_image);
615
579
  }
616
580
 
617
581
 
618
582
  /**
619
- * Equivalent to -layers option in ImageMagick 6.2.6.
620
- *
621
- * Ruby usage:
622
- * - @verbatim ImageList#optimize_layers(method) @endverbatim
583
+ * Optimizes or compares the images in the list.
584
+ * Equivalent to the -layers option in ImageMagick's mogrify command.
623
585
  *
624
- * @param self this object
625
- * @param method the method to use
626
- * @return a new imagelist
586
+ * @param method [Magick::LayerMethod] the method to use
587
+ * @return [Magick::ImageList] a new imagelist
627
588
  */
628
589
  VALUE
629
590
  ImageList_optimize_layers(VALUE self, VALUE method)
630
591
  {
631
592
  Image *images, *new_images, *new_images2;
632
- LAYERMETHODTYPE mthd;
593
+ LayerMethod mthd;
633
594
  ExceptionInfo *exception;
634
595
  QuantizeInfo quantize_info;
635
596
 
636
597
  new_images2 = NULL; // defeat "unused variable" message
637
598
 
638
- exception = AcquireExceptionInfo();
639
- #if defined(HAVE_TYPE_IMAGELAYERMETHOD)
640
- VALUE_TO_ENUM(method, mthd, ImageLayerMethod);
641
- #else
642
- VALUE_TO_ENUM(method, mthd, MagickLayerMethod);
643
- #endif
599
+ VALUE_TO_ENUM(method, mthd, LayerMethod);
644
600
  images = images_from_imagelist(self);
645
601
 
602
+ exception = AcquireExceptionInfo();
646
603
  switch (mthd)
647
604
  {
648
605
  case CoalesceLayer:
649
- new_images = CoalesceImages(images, exception);
606
+ {
607
+ GVL_STRUCT_TYPE(CoalesceImages) args = { images, exception };
608
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CoalesceImages), &args);
609
+ }
650
610
  break;
651
611
  case DisposeLayer:
652
- new_images = DisposeImages(images, exception);
612
+ {
613
+ GVL_STRUCT_TYPE(DisposeImages) args = { images, exception };
614
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(DisposeImages), &args);
615
+ }
653
616
  break;
654
617
  case OptimizeTransLayer:
655
- new_images = clone_imagelist(images);
656
- OptimizeImageTransparency(new_images, exception);
618
+ {
619
+ new_images = clone_imagelist(images);
620
+ GVL_STRUCT_TYPE(OptimizeImageTransparency) args = { new_images, exception };
621
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(OptimizeImageTransparency), &args);
622
+ }
657
623
  break;
658
624
  case RemoveDupsLayer:
659
- new_images = clone_imagelist(images);
660
- RemoveDuplicateLayers(&new_images, exception);
625
+ {
626
+ new_images = clone_imagelist(images);
627
+ GVL_STRUCT_TYPE(RemoveDuplicateLayers) args = { &new_images, exception };
628
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(RemoveDuplicateLayers), &args);
629
+ }
661
630
  break;
662
631
  case RemoveZeroLayer:
663
- new_images = clone_imagelist(images);
664
- RemoveZeroDelayLayers(&new_images, exception);
632
+ {
633
+ new_images = clone_imagelist(images);
634
+ GVL_STRUCT_TYPE(RemoveZeroDelayLayers) args = { &new_images, exception };
635
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(RemoveZeroDelayLayers), &args);
636
+ }
665
637
  break;
666
638
  case CompositeLayer:
667
639
  rm_split(images);
640
+ DestroyExceptionInfo(exception);
668
641
  rb_raise(rb_eNotImpError, "Magick::CompositeLayer is not supported. Use the composite_layers method instead.");
669
642
  break;
670
643
  // In 6.3.4-ish, OptimizeImageLayer replaced OptimizeLayer
671
644
  case OptimizeImageLayer:
672
- new_images = OptimizeImageLayers(images, exception);
645
+ {
646
+ GVL_STRUCT_TYPE(OptimizeImageLayers) args = { images, exception };
647
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(OptimizeImageLayers), &args);
648
+ }
673
649
  break;
674
650
  // and OptimizeLayer became a "General Purpose, GIF Animation Optimizer" (ref. mogrify.c)
675
651
  case OptimizeLayer:
676
- new_images = CoalesceImages(images, exception);
677
- rm_split(images);
678
- rm_check_exception(exception, new_images, DestroyOnError);
679
- new_images2 = OptimizeImageLayers(new_images, exception);
680
- DestroyImageList(new_images);
681
- rm_check_exception(exception, new_images2, DestroyOnError);
682
- new_images = new_images2;
683
- OptimizeImageTransparency(new_images, exception);
684
- rm_check_exception(exception, new_images, DestroyOnError);
685
- // mogrify supports -dither here. We don't.
686
- #if defined(HAVE_REMAPIMAGE)
687
- GetQuantizeInfo(&quantize_info);
688
- (void) RemapImages(&quantize_info, new_images, NULL);
652
+ {
653
+ GVL_STRUCT_TYPE(CoalesceImages) args_CoalesceImages = { images, exception };
654
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CoalesceImages), &args_CoalesceImages);
655
+ rm_split(images);
656
+ rm_check_exception(exception, new_images, DestroyOnError);
657
+
658
+ GVL_STRUCT_TYPE(OptimizeImageLayers) args_OptimizeImageLayers = { new_images, exception };
659
+ new_images2 = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(OptimizeImageLayers), &args_OptimizeImageLayers);
660
+ DestroyImageList(new_images);
661
+ rm_check_exception(exception, new_images2, DestroyOnError);
662
+
663
+ new_images = new_images2;
664
+ GVL_STRUCT_TYPE(OptimizeImageTransparency) args_OptimizeImageTransparency = { new_images, exception };
665
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(OptimizeImageTransparency), &args_OptimizeImageTransparency);
666
+ rm_check_exception(exception, new_images, DestroyOnError);
667
+ // mogrify supports -dither here. We don't.
668
+ GetQuantizeInfo(&quantize_info);
669
+ #if defined(IMAGEMAGICK_7)
670
+ GVL_STRUCT_TYPE(RemapImages) args_RemapImages = { &quantize_info, new_images, NULL, exception };
689
671
  #else
690
- (void) MapImages(new_images, NULL, 0);
672
+ GVL_STRUCT_TYPE(RemapImages) args_RemapImages = { &quantize_info, new_images, NULL };
691
673
  #endif
674
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(RemapImages), &args_RemapImages);
675
+
676
+ }
692
677
  break;
693
678
  case OptimizePlusLayer:
694
- new_images = OptimizePlusImageLayers(images, exception);
679
+ {
680
+ GVL_STRUCT_TYPE(OptimizePlusImageLayers) args = { images, exception };
681
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(OptimizePlusImageLayers), &args);
682
+ }
695
683
  break;
696
684
  case CompareAnyLayer:
697
685
  case CompareClearLayer:
698
686
  case CompareOverlayLayer:
699
- new_images = CompareImageLayers(images, mthd, exception);
687
+ {
688
+ #if defined(IMAGEMAGICK_7)
689
+ GVL_STRUCT_TYPE(CompareImagesLayers) args = { images, mthd, exception };
690
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CompareImagesLayers), &args);
691
+ #else
692
+ GVL_STRUCT_TYPE(CompareImageLayers) args = { images, mthd, exception };
693
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CompareImageLayers), &args);
694
+ #endif
695
+ }
700
696
  break;
701
- #if defined(HAVE_ENUM_MOSAICLAYER)
702
697
  case MosaicLayer:
703
- new_images = MergeImageLayers(images, mthd, exception);
698
+ {
699
+ GVL_STRUCT_TYPE(MergeImageLayers) args = { images, mthd, exception };
700
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
701
+ }
704
702
  break;
705
- #endif
706
- #if defined(HAVE_ENUM_FLATTENLAYER)
707
703
  case FlattenLayer:
708
- new_images = MergeImageLayers(images, mthd, exception);
704
+ {
705
+ GVL_STRUCT_TYPE(MergeImageLayers) args = { images, mthd, exception };
706
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
707
+ }
709
708
  break;
710
- #endif
711
- #if defined(HAVE_ENUM_MERGELAYER)
712
709
  case MergeLayer:
713
- new_images = MergeImageLayers(images, mthd, exception);
710
+ {
711
+ GVL_STRUCT_TYPE(MergeImageLayers) args = { images, mthd, exception };
712
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
713
+ }
714
714
  break;
715
- #endif
716
- #if defined(HAVE_ENUM_TRIMBOUNDSLAYER)
717
715
  case TrimBoundsLayer:
718
- new_images = MergeImageLayers(images, mthd, exception);
716
+ {
717
+ GVL_STRUCT_TYPE(MergeImageLayers) args = { images, mthd, exception };
718
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
719
+ }
719
720
  break;
720
- #endif
721
721
  default:
722
722
  rm_split(images);
723
+ DestroyExceptionInfo(exception);
723
724
  rb_raise(rb_eArgError, "undefined layer method");
724
725
  break;
725
726
  }
726
727
 
727
728
  rm_split(images);
728
729
  rm_check_exception(exception, new_images, DestroyOnError);
729
- (void) DestroyExceptionInfo(exception);
730
-
731
- rm_ensure_result(new_images);
730
+ DestroyExceptionInfo(exception);
732
731
 
733
732
  return rm_imagelist_from_images(new_images);
734
733
  }
@@ -767,22 +766,20 @@ VALUE
767
766
  rm_imagelist_from_images(Image *images)
768
767
  {
769
768
  VALUE new_imagelist;
770
- Image *image;
771
769
 
772
- if (!images)
773
- {
774
- rb_bug("rm_imagelist_from_images called with NULL argument");
775
- }
770
+ rm_ensure_result(images);
776
771
 
777
772
  new_imagelist = ImageList_new();
778
773
 
779
774
  while (images)
780
775
  {
776
+ Image *image;
777
+
781
778
  image = RemoveFirstImageFromList(&images);
782
779
  imagelist_push(new_imagelist, rm_image_new(image));
783
780
  }
784
781
 
785
- (void) rb_iv_set(new_imagelist, "@scene", INT2FIX(0));
782
+ rb_iv_set(new_imagelist, "@scene", INT2FIX(0));
786
783
 
787
784
  RB_GC_GUARD(new_imagelist);
788
785
 
@@ -820,6 +817,9 @@ images_from_imagelist(VALUE imagelist)
820
817
  if (head == image || GetPreviousImageInList(image) != NULL)
821
818
  {
822
819
  image = rm_clone_image(image);
820
+
821
+ // Wrap raw ImageMagick object by Ruby object to destroy using Ruby's GC.
822
+ rm_image_new(image);
823
823
  }
824
824
  AppendImageToList(&head, image);
825
825
  }
@@ -831,24 +831,6 @@ images_from_imagelist(VALUE imagelist)
831
831
  }
832
832
 
833
833
 
834
- /**
835
- * \@scene attribute writer.
836
- *
837
- * No Ruby usage (internal function)
838
- *
839
- * @param imagelist the imagelist
840
- * @param scene the scene
841
- * @return the scene
842
- */
843
- static VALUE
844
- imagelist_scene_eq(VALUE imagelist, VALUE scene)
845
- {
846
- rb_check_frozen(imagelist);
847
- (void) rb_iv_set(imagelist, "@scene", scene);
848
- return scene;
849
- }
850
-
851
-
852
834
  /**
853
835
  * return the # of images in an imagelist.
854
836
  *
@@ -861,6 +843,10 @@ static long
861
843
  imagelist_length(VALUE imagelist)
862
844
  {
863
845
  VALUE images = rb_iv_get(imagelist, "@images");
846
+ if (!RB_TYPE_P(images, T_ARRAY))
847
+ {
848
+ rb_raise(Class_ImageMagickError, "@images is not of type Array");
849
+ }
864
850
 
865
851
  RB_GC_GUARD(images);
866
852
 
@@ -903,7 +889,7 @@ static void
903
889
  imagelist_push(VALUE imagelist, VALUE image)
904
890
  {
905
891
  rb_check_frozen(imagelist);
906
- (void) rb_funcall(imagelist, rm_ID_push, 1, image);
892
+ rb_funcall(imagelist, rm_ID_push, 1, image);
907
893
  }
908
894
 
909
895
 
@@ -918,7 +904,7 @@ imagelist_push(VALUE imagelist, VALUE image)
918
904
  static Image *
919
905
  clone_imagelist(Image *images)
920
906
  {
921
- Image *new_imagelist = NULL, *image, *clone;
907
+ Image *new_imagelist = NULL, *image;
922
908
  ExceptionInfo *exception;
923
909
 
924
910
  exception = AcquireExceptionInfo();
@@ -926,40 +912,32 @@ clone_imagelist(Image *images)
926
912
  image = GetFirstImageInList(images);
927
913
  while (image)
928
914
  {
929
- clone = CloneImage(image, 0, 0, MagickTrue, exception);
915
+ Image *clone;
916
+
917
+ GVL_STRUCT_TYPE(CloneImage) args = { image, 0, 0, MagickTrue, exception };
918
+ clone = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CloneImage), &args);
930
919
  rm_check_exception(exception, new_imagelist, DestroyOnError);
931
920
  AppendImageToList(&new_imagelist, clone);
932
921
  image = GetNextImageInList(image);
933
922
  }
934
923
 
935
- (void) DestroyExceptionInfo(exception);
924
+ DestroyExceptionInfo(exception);
936
925
  return new_imagelist;
937
926
  }
938
927
 
939
928
 
940
929
  /**
941
- * Call QuantizeImages.
942
- *
943
- * Ruby usage:
944
- * - @verbatim ImageList#quantize @endverbatim
945
- * - @verbatim ImageList#quantize(number_colors) @endverbatim
946
- * - @verbatim ImageList#quantize(number_colors, colorspace) @endverbatim
947
- * - @verbatim ImageList#quantize(number_colors, colorspace, dither) @endverbatim
948
- * - @verbatim ImageList#quantize(number_colors, colorspace, dither, tree_depth) @endverbatim
949
- * - @verbatim ImageList#quantize(number_colors, colorspace, dither, tree_depth, measure_error) @endverbatim
950
- *
951
- * Notes:
952
- * - Default number_colors is 256
953
- * - Default coorspace is Magick::RGBColorsapce
954
- * - Default dither is true
955
- * - Default tree_depth is 0
956
- * - Default measure_error is false
957
- * - Sets \@scene to the same value as self.scene
958
- *
959
- * @param argc number of input arguments
960
- * @param argv array of input arguments
961
- * @param self this object
962
- * @return a new ImageList with quantized images
930
+ * Analyzes the colors within a set of reference images and chooses a fixed number of colors to represent the set.
931
+ * The goal of the algorithm is to minimize the difference between the input and output images while minimizing the processing time.
932
+ *
933
+ * @overload quantize(number_colors = 256, colorspace = Magick::RGBColorsapce, dither = true, tree_depth = 0, measure_error = false)
934
+ * @param number_colors [Numeric] the maximum number of colors to use in the output images.
935
+ * @param colorspace [Magick::ColorspaceType] the colorspace to quantize in.
936
+ * @param dither [Magick::DitherMethod, Boolean] a DitherMethod value or true if you want apply dither.
937
+ * @param tree_depth [Numeric] specify the tree depth to use while quantizing.
938
+ * @param measure_error [Boolean] calculate quantization errors when quantizing the image.
939
+ * @return [Magick::ImageList] a new ImageList with quantized images
940
+ * @note Sets +@scene+ to the same value as +self.scene+
963
941
  */
964
942
  VALUE
965
943
  ImageList_quantize(int argc, VALUE *argv, VALUE self)
@@ -979,14 +957,25 @@ ImageList_quantize(int argc, VALUE *argv, VALUE self)
979
957
  case 4:
980
958
  quantize_info.tree_depth = (unsigned long)NUM2INT(argv[3]);
981
959
  case 3:
982
- #if defined(HAVE_TYPE_DITHERMETHOD) && defined(HAVE_ENUM_NODITHERMETHOD)
960
+ #if defined(IMAGEMAGICK_7)
983
961
  if (rb_obj_is_kind_of(argv[2], Class_DitherMethod))
984
962
  {
985
963
  VALUE_TO_ENUM(argv[2], quantize_info.dither_method, DitherMethod);
986
- quantize_info.dither = quantize_info.dither_method != NoDitherMethod;
964
+ }
965
+ else
966
+ {
967
+ quantize_info.dither_method = RTEST(argv[2]) ? UndefinedDitherMethod : NoDitherMethod;
987
968
  }
988
969
  #else
989
- quantize_info.dither = (MagickBooleanType) RTEST(argv[2]);
970
+ if (rb_obj_is_kind_of(argv[2], Class_DitherMethod))
971
+ {
972
+ VALUE_TO_ENUM(argv[2], quantize_info.dither_method, DitherMethod);
973
+ quantize_info.dither = quantize_info.dither_method != NoDitherMethod;
974
+ }
975
+ else
976
+ {
977
+ quantize_info.dither = (MagickBooleanType) RTEST(argv[2]);
978
+ }
990
979
  #endif
991
980
  case 2:
992
981
  VALUE_TO_ENUM(argv[1], quantize_info.colorspace, ColorspaceType);
@@ -1001,18 +990,23 @@ ImageList_quantize(int argc, VALUE *argv, VALUE self)
1001
990
 
1002
991
 
1003
992
  // Convert image array to image sequence, clone image sequence.
1004
- exception = AcquireExceptionInfo();
1005
993
  images = images_from_imagelist(self);
1006
- new_images = CloneImageList(images, exception);
994
+ exception = AcquireExceptionInfo();
995
+ GVL_STRUCT_TYPE(CloneImageList) args_CloneImageList = { images, exception };
996
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CloneImageList), &args_CloneImageList);
1007
997
  rm_split(images);
1008
998
  rm_check_exception(exception, new_images, DestroyOnError);
1009
999
 
1010
1000
  rm_ensure_result(new_images);
1011
1001
 
1012
-
1013
- (void) QuantizeImages(&quantize_info, new_images);
1002
+ #if defined(IMAGEMAGICK_7)
1003
+ GVL_STRUCT_TYPE(QuantizeImages) args_QuantizeImages = { &quantize_info, new_images, exception };
1004
+ #else
1005
+ GVL_STRUCT_TYPE(QuantizeImages) args_QuantizeImages = { &quantize_info, new_images };
1006
+ #endif
1007
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(QuantizeImages), &args_QuantizeImages);
1014
1008
  rm_check_exception(exception, new_images, DestroyOnError);
1015
- (void) DestroyExceptionInfo(exception);
1009
+ DestroyExceptionInfo(exception);
1016
1010
 
1017
1011
  // Create new ImageList object, convert mapped image sequence to images,
1018
1012
  // append to images array.
@@ -1024,7 +1018,7 @@ ImageList_quantize(int argc, VALUE *argv, VALUE self)
1024
1018
 
1025
1019
  // Set @scene in new ImageList object to same value as in self.
1026
1020
  scene = rb_iv_get(self, "@scene");
1027
- (void) rb_iv_set(new_imagelist, "@scene", scene);
1021
+ rb_iv_set(new_imagelist, "@scene", scene);
1028
1022
 
1029
1023
  RB_GC_GUARD(new_imagelist);
1030
1024
  RB_GC_GUARD(scene);
@@ -1034,30 +1028,23 @@ ImageList_quantize(int argc, VALUE *argv, VALUE self)
1034
1028
 
1035
1029
 
1036
1030
  /**
1037
- * Call RemapImages.
1038
- *
1039
- * Ruby usage:
1040
- * - @verbatim ImageList#remap @endverbatim
1041
- * - @verbatim ImageList#remap(remap_image) @endverbatim
1042
- * - @verbatim ImageList#remap(remap_image, dither_method) @endverbatim
1043
- *
1044
- * Notes:
1045
- * - Default remap_image is nil
1046
- * - Default dither_method is RiemersmaDitherMethod
1047
- * - Modifies images in-place.
1048
- *
1049
- * @param argc number of input arguments
1050
- * @param argv array of input arguments
1051
- * @param self this object
1052
- * @see Image_remap
1031
+ * Reduce the colors used in the image list to the set of colors in +remap_image+.
1032
+ *
1033
+ * @overload remap(remap_image = nil, dither_method = Magick::RiemersmaDitherMethod)
1034
+ * @param remap_image [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
1035
+ * imagelist, uses the current image.
1036
+ * @param dither_method [Magick::DitherMethod] a DitherMethod value.
1037
+ * @return [Magick::ImageList] self
1038
+ * @note Modifies images in-place.
1053
1039
  */
1054
1040
  VALUE
1055
1041
  ImageList_remap(int argc, VALUE *argv, VALUE self)
1056
1042
  {
1057
- #if defined(HAVE_REMAPIMAGES) || defined(HAVE_AFFINITYIMAGES)
1058
1043
  Image *images, *remap_image = NULL;
1059
1044
  QuantizeInfo quantize_info;
1060
-
1045
+ #if defined(IMAGEMAGICK_7)
1046
+ ExceptionInfo *exception;
1047
+ #endif
1061
1048
 
1062
1049
  if (argc > 0 && argv[0] != Qnil)
1063
1050
  {
@@ -1071,7 +1058,9 @@ ImageList_remap(int argc, VALUE *argv, VALUE self)
1071
1058
  if (argc > 1)
1072
1059
  {
1073
1060
  VALUE_TO_ENUM(argv[1], quantize_info.dither_method, DitherMethod);
1061
+ #if defined(IMAGEMAGICK_6)
1074
1062
  quantize_info.dither = MagickTrue;
1063
+ #endif
1075
1064
  }
1076
1065
  if (argc > 2)
1077
1066
  {
@@ -1080,37 +1069,34 @@ ImageList_remap(int argc, VALUE *argv, VALUE self)
1080
1069
 
1081
1070
  images = images_from_imagelist(self);
1082
1071
 
1083
- #if defined(HAVE_REMAPIMAGE)
1084
- (void) RemapImages(&quantize_info, images, remap_image);
1072
+ #if defined(IMAGEMAGICK_7)
1073
+ exception = AcquireExceptionInfo();
1074
+ GVL_STRUCT_TYPE(RemapImages) args = { &quantize_info, images, remap_image, exception };
1075
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(RemapImages), &args);
1076
+ rm_split(images);
1077
+ CHECK_EXCEPTION();
1078
+ DestroyExceptionInfo(exception);
1085
1079
  #else
1086
- (void) AffinityImages(&quantize_info, images, remap_image);
1087
- #endif
1088
- rm_check_image_exception(images, RetainOnError);
1080
+ GVL_STRUCT_TYPE(RemapImages) args = { &quantize_info, images, remap_image };
1081
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(RemapImages), &args);
1089
1082
  rm_split(images);
1083
+ rm_check_image_exception(images, RetainOnError);
1084
+ #endif
1090
1085
 
1091
1086
  return self;
1092
- #else
1093
- self = self;
1094
- argc = argc;
1095
- argv = argv;
1096
- rm_not_implemented();
1097
- return(VALUE)0;
1098
- #endif
1099
1087
  }
1100
1088
 
1101
1089
 
1102
1090
  /**
1103
1091
  * Return the imagelist as a blob (a String).
1104
1092
  *
1105
- * Ruby usage:
1106
- * - @verbatim ImageList#to_blob @endverbatim
1093
+ * @overload to_blob
1107
1094
  *
1108
- * Notes:
1109
- * - Runs an info parm block if present - the user can specify the image
1110
- * format and depth
1095
+ * @overload to_blob
1096
+ * Runs an info parm block if present - the user can specify the image format and depth
1097
+ * @yield [Magick::Image::Info]
1111
1098
  *
1112
- * @param self this object
1113
- * @return the blob
1099
+ * @return [String] the blob
1114
1100
  */
1115
1101
  VALUE
1116
1102
  ImageList_to_blob(VALUE self)
@@ -1124,13 +1110,13 @@ ImageList_to_blob(VALUE self)
1124
1110
  ExceptionInfo *exception;
1125
1111
 
1126
1112
  info_obj = rm_info_new();
1127
- Data_Get_Struct(info_obj, Info, info);
1113
+ TypedData_Get_Struct(info_obj, Info, &rm_info_data_type, info);
1128
1114
 
1129
1115
  // Convert the images array to an images sequence.
1130
1116
  images = images_from_imagelist(self);
1131
1117
 
1132
1118
  exception = AcquireExceptionInfo();
1133
- (void) SetImageInfo(info, MagickTrue, exception);
1119
+ SetImageInfo(info, MagickTrue, exception);
1134
1120
  rm_check_exception(exception, images, RetainOnError);
1135
1121
 
1136
1122
  if (*info->magick != '\0')
@@ -1138,7 +1124,7 @@ ImageList_to_blob(VALUE self)
1138
1124
  Image *img;
1139
1125
  for (img = images; img; img = GetNextImageInList(img))
1140
1126
  {
1141
- strncpy(img->magick, info->magick, sizeof(info->magick)-1);
1127
+ strlcpy(img->magick, info->magick, sizeof(img->magick));
1142
1128
  }
1143
1129
  }
1144
1130
 
@@ -1151,7 +1137,8 @@ ImageList_to_blob(VALUE self)
1151
1137
  // can happen is that there's only one image or the format
1152
1138
  // doesn't support multi-image files.
1153
1139
  info->adjoin = MagickTrue;
1154
- blob = ImagesToBlob(info, images, &length, exception);
1140
+ GVL_STRUCT_TYPE(ImagesToBlob) args = { info, images, &length, exception };
1141
+ blob = CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ImagesToBlob), &args);
1155
1142
  if (blob && exception->severity >= ErrorException)
1156
1143
  {
1157
1144
  magick_free((void*)blob);
@@ -1159,8 +1146,8 @@ ImageList_to_blob(VALUE self)
1159
1146
  length = 0;
1160
1147
  }
1161
1148
  rm_split(images);
1162
- CHECK_EXCEPTION()
1163
- (void) DestroyExceptionInfo(exception);
1149
+ CHECK_EXCEPTION();
1150
+ DestroyExceptionInfo(exception);
1164
1151
 
1165
1152
 
1166
1153
  if (length == 0 || !blob)
@@ -1184,12 +1171,7 @@ ImageList_to_blob(VALUE self)
1184
1171
  * the images will be written as a single multi-image file. Otherwise each image
1185
1172
  * will be written to a separate file.
1186
1173
  *
1187
- * Ruby usage:
1188
- * - @verbatim ImageList#write(file) @endverbatim
1189
- *
1190
- * @param self this object
1191
- * @param file the file
1192
- * @return self
1174
+ * @param file [File, String] the file
1193
1175
  */
1194
1176
  VALUE
1195
1177
  ImageList_write(VALUE self, VALUE file)
@@ -1202,12 +1184,12 @@ ImageList_write(VALUE self, VALUE file)
1202
1184
  ExceptionInfo *exception;
1203
1185
 
1204
1186
  info_obj = rm_info_new();
1205
- Data_Get_Struct(info_obj, Info, info);
1187
+ TypedData_Get_Struct(info_obj, Info, &rm_info_data_type, info);
1206
1188
 
1207
1189
 
1208
1190
  if (TYPE(file) == T_FILE)
1209
1191
  {
1210
- OpenFile *fptr;
1192
+ rb_io_t *fptr;
1211
1193
 
1212
1194
  // Ensure file is open - raise error if not
1213
1195
  GetOpenFile(file, fptr);
@@ -1215,7 +1197,7 @@ ImageList_write(VALUE self, VALUE file)
1215
1197
  add_format_prefix(info, fptr->pathv);
1216
1198
  SetImageInfoFile(info, NULL);
1217
1199
  #else
1218
- SetImageInfoFile(info, GetReadFile(fptr));
1200
+ SetImageInfoFile(info, rb_io_stdio_file(fptr));
1219
1201
  #endif
1220
1202
  }
1221
1203
  else
@@ -1232,20 +1214,22 @@ ImageList_write(VALUE self, VALUE file)
1232
1214
  for (scene = 0, img = images; img; img = GetNextImageInList(img))
1233
1215
  {
1234
1216
  img->scene = scene++;
1235
- strcpy(img->filename, info->filename);
1217
+ strlcpy(img->filename, info->filename, sizeof(img->filename));
1236
1218
  }
1237
1219
 
1238
1220
  // Find out if the format supports multi-images files.
1239
1221
  exception = AcquireExceptionInfo();
1240
- (void) SetImageInfo(info, MagickTrue, exception);
1222
+ SetImageInfo(info, MagickTrue, exception);
1241
1223
  rm_check_exception(exception, images, RetainOnError);
1242
1224
 
1243
1225
  m = GetMagickInfo(info->magick, exception);
1244
1226
  rm_check_exception(exception, images, RetainOnError);
1245
- (void) DestroyExceptionInfo(exception);
1227
+ #if defined(IMAGEMAGICK_6)
1228
+ DestroyExceptionInfo(exception);
1229
+ #endif
1246
1230
 
1247
1231
  // Tell WriteImage if we want a multi-images file.
1248
- if (imagelist_length(self) > 1L && m->adjoin)
1232
+ if (imagelist_length(self) > 1L && GetMagickAdjoin(m))
1249
1233
  {
1250
1234
  info->adjoin = MagickTrue;
1251
1235
  }
@@ -1253,15 +1237,26 @@ ImageList_write(VALUE self, VALUE file)
1253
1237
  for (img = images; img; img = GetNextImageInList(img))
1254
1238
  {
1255
1239
  rm_sync_image_options(img, info);
1256
- (void) WriteImage(info, img);
1240
+ #if defined(IMAGEMAGICK_7)
1241
+ GVL_STRUCT_TYPE(WriteImage) args = { info, img, exception };
1242
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(WriteImage), &args);
1243
+ rm_check_exception(exception, img, RetainOnError);
1244
+ #else
1245
+ GVL_STRUCT_TYPE(WriteImage) args = { info, img };
1246
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(WriteImage), &args);
1257
1247
  // images will be split before raising an exception
1258
1248
  rm_check_image_exception(images, RetainOnError);
1249
+ #endif
1259
1250
  if (info->adjoin)
1260
1251
  {
1261
1252
  break;
1262
1253
  }
1263
1254
  }
1264
1255
 
1256
+ #if defined(IMAGEMAGICK_7)
1257
+ DestroyExceptionInfo(exception);
1258
+ #endif
1259
+
1265
1260
  rm_split(images);
1266
1261
 
1267
1262
  RB_GC_GUARD(info_obj);