rmagick 2.16.0 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (404) hide show
  1. checksums.yaml +5 -5
  2. data/.devcontainer/Dockerfile +14 -0
  3. data/.devcontainer/ImageMagick6/devcontainer.json +11 -0
  4. data/.devcontainer/devcontainer.json +11 -0
  5. data/.devcontainer/setup-repo.sh +10 -0
  6. data/.devcontainer/setup-user.sh +45 -0
  7. data/.editorconfig +3 -0
  8. data/.github/ISSUE_TEMPLATE.md +17 -0
  9. data/.github/workflows/ci.yml +138 -0
  10. data/.gitignore +7 -1
  11. data/.rspec +1 -0
  12. data/.rubocop.yml +37 -340
  13. data/.rubocop_todo.yml +448 -0
  14. data/.yardopts +5 -0
  15. data/CHANGELOG.md +455 -0
  16. data/CODE_OF_CONDUCT.md +122 -7
  17. data/CONTRIBUTING.md +37 -6
  18. data/Gemfile +0 -6
  19. data/README.md +316 -0
  20. data/Rakefile +74 -100
  21. data/before_install_linux.sh +65 -28
  22. data/before_install_osx.sh +58 -2
  23. data/ext/RMagick/extconf.rb +287 -393
  24. data/ext/RMagick/rmagick.c +106 -111
  25. data/ext/RMagick/rmagick.h +235 -331
  26. data/ext/RMagick/rmagick_gvl.h +224 -0
  27. data/ext/RMagick/rmdraw.c +516 -843
  28. data/ext/RMagick/rmenum.c +316 -755
  29. data/ext/RMagick/rmfill.c +281 -191
  30. data/ext/RMagick/rmilist.c +451 -456
  31. data/ext/RMagick/rmimage.c +6250 -5290
  32. data/ext/RMagick/rminfo.c +721 -894
  33. data/ext/RMagick/rmkinfo.c +228 -0
  34. data/ext/RMagick/rmmain.c +735 -521
  35. data/ext/RMagick/rmmontage.c +127 -172
  36. data/ext/RMagick/rmpixel.c +638 -431
  37. data/ext/RMagick/rmstruct.c +102 -282
  38. data/ext/RMagick/rmutil.c +450 -363
  39. data/lib/rmagick/version.rb +5 -4
  40. data/lib/rmagick.rb +2 -0
  41. data/lib/rmagick_internal.rb +349 -413
  42. data/lib/rvg/clippath.rb +3 -4
  43. data/lib/rvg/container.rb +30 -22
  44. data/lib/rvg/deep_equal.rb +11 -11
  45. data/lib/rvg/describable.rb +2 -2
  46. data/lib/rvg/embellishable.rb +63 -68
  47. data/lib/rvg/misc.rb +136 -139
  48. data/lib/rvg/paint.rb +2 -1
  49. data/lib/rvg/pathdata.rb +7 -8
  50. data/lib/rvg/rvg.rb +47 -46
  51. data/lib/rvg/stretchable.rb +22 -28
  52. data/lib/rvg/stylable.rb +12 -10
  53. data/lib/rvg/text.rb +169 -165
  54. data/lib/rvg/transformable.rb +17 -16
  55. data/lib/rvg/units.rb +5 -5
  56. data/rmagick.gemspec +16 -39
  57. metadata +114 -392
  58. data/.hound.yml +0 -2
  59. data/.simplecov +0 -27
  60. data/.travis.yml +0 -74
  61. data/Doxyfile +0 -1514
  62. data/README.textile +0 -251
  63. data/deprecated/RMagick.rb +0 -6
  64. data/doc/.cvsignore +0 -1
  65. data/doc/comtasks.html +0 -287
  66. data/doc/constants.html +0 -1581
  67. data/doc/css/doc.css +0 -299
  68. data/doc/css/popup.css +0 -34
  69. data/doc/css/ref.css +0 -67
  70. data/doc/draw.html +0 -3272
  71. data/doc/ex/InitialCoords.rb +0 -22
  72. data/doc/ex/NewCoordSys.rb +0 -30
  73. data/doc/ex/OrigCoordSys.rb +0 -16
  74. data/doc/ex/PreserveAspectRatio.rb +0 -204
  75. data/doc/ex/RotateScale.rb +0 -36
  76. data/doc/ex/Skew.rb +0 -38
  77. data/doc/ex/Use01.rb +0 -15
  78. data/doc/ex/Use02.rb +0 -20
  79. data/doc/ex/Use03.rb +0 -16
  80. data/doc/ex/ViewBox.rb +0 -31
  81. data/doc/ex/adaptive_threshold.rb +0 -9
  82. data/doc/ex/add_noise.rb +0 -16
  83. data/doc/ex/affine.rb +0 -48
  84. data/doc/ex/affine_transform.rb +0 -20
  85. data/doc/ex/arc.rb +0 -49
  86. data/doc/ex/arcpath.rb +0 -32
  87. data/doc/ex/arcs01.rb +0 -28
  88. data/doc/ex/arcs02.rb +0 -59
  89. data/doc/ex/average.rb +0 -15
  90. data/doc/ex/axes.rb +0 -64
  91. data/doc/ex/baseline_shift01.rb +0 -17
  92. data/doc/ex/bilevel_channel.rb +0 -8
  93. data/doc/ex/blur_image.rb +0 -12
  94. data/doc/ex/border.rb +0 -10
  95. data/doc/ex/bounding_box.rb +0 -42
  96. data/doc/ex/cbezier1.rb +0 -41
  97. data/doc/ex/cbezier2.rb +0 -41
  98. data/doc/ex/cbezier3.rb +0 -41
  99. data/doc/ex/cbezier4.rb +0 -42
  100. data/doc/ex/cbezier5.rb +0 -42
  101. data/doc/ex/cbezier6.rb +0 -53
  102. data/doc/ex/channel.rb +0 -25
  103. data/doc/ex/charcoal.rb +0 -12
  104. data/doc/ex/chop.rb +0 -29
  105. data/doc/ex/circle.rb +0 -33
  106. data/doc/ex/circle01.rb +0 -16
  107. data/doc/ex/clip_path.rb +0 -60
  108. data/doc/ex/coalesce.rb +0 -57
  109. data/doc/ex/color_fill_to_border.rb +0 -29
  110. data/doc/ex/color_floodfill.rb +0 -28
  111. data/doc/ex/color_histogram.rb +0 -47
  112. data/doc/ex/color_reset.rb +0 -11
  113. data/doc/ex/colorize.rb +0 -16
  114. data/doc/ex/colors.rb +0 -64
  115. data/doc/ex/compose_mask.rb +0 -22
  116. data/doc/ex/composite.rb +0 -133
  117. data/doc/ex/composite_layers.rb +0 -53
  118. data/doc/ex/composite_tiled.rb +0 -21
  119. data/doc/ex/contrast.rb +0 -36
  120. data/doc/ex/crop.rb +0 -31
  121. data/doc/ex/crop_with_gravity.rb +0 -42
  122. data/doc/ex/cubic01.rb +0 -43
  123. data/doc/ex/cubic02.rb +0 -91
  124. data/doc/ex/cycle_colormap.rb +0 -21
  125. data/doc/ex/dissolve.rb +0 -12
  126. data/doc/ex/drawcomp.rb +0 -42
  127. data/doc/ex/drop_shadow.rb +0 -60
  128. data/doc/ex/edge.rb +0 -11
  129. data/doc/ex/ellipse.rb +0 -45
  130. data/doc/ex/ellipse01.rb +0 -21
  131. data/doc/ex/emboss.rb +0 -11
  132. data/doc/ex/enhance.rb +0 -28
  133. data/doc/ex/equalize.rb +0 -11
  134. data/doc/ex/evenodd.rb +0 -42
  135. data/doc/ex/fill_pattern.rb +0 -23
  136. data/doc/ex/flatten_images.rb +0 -36
  137. data/doc/ex/flip.rb +0 -11
  138. data/doc/ex/flop.rb +0 -11
  139. data/doc/ex/font_styles.rb +0 -32
  140. data/doc/ex/fonts.rb +0 -20
  141. data/doc/ex/frame.rb +0 -12
  142. data/doc/ex/gaussian_blur.rb +0 -11
  143. data/doc/ex/get_multiline_type_metrics.rb +0 -41
  144. data/doc/ex/get_pixels.rb +0 -47
  145. data/doc/ex/get_type_metrics.rb +0 -141
  146. data/doc/ex/gradientfill.rb +0 -27
  147. data/doc/ex/grav.rb +0 -45
  148. data/doc/ex/gravity.rb +0 -80
  149. data/doc/ex/group.rb +0 -26
  150. data/doc/ex/hatchfill.rb +0 -27
  151. data/doc/ex/image.rb +0 -44
  152. data/doc/ex/images/Apple.miff +0 -0
  153. data/doc/ex/images/Ballerina.jpg +0 -0
  154. data/doc/ex/images/Ballerina3.jpg +0 -0
  155. data/doc/ex/images/Button_0.gif +0 -0
  156. data/doc/ex/images/Button_1.gif +0 -0
  157. data/doc/ex/images/Button_2.gif +0 -0
  158. data/doc/ex/images/Button_3.gif +0 -0
  159. data/doc/ex/images/Button_4.gif +0 -0
  160. data/doc/ex/images/Button_5.gif +0 -0
  161. data/doc/ex/images/Button_6.gif +0 -0
  162. data/doc/ex/images/Button_7.gif +0 -0
  163. data/doc/ex/images/Button_8.gif +0 -0
  164. data/doc/ex/images/Button_9.gif +0 -0
  165. data/doc/ex/images/Button_A.gif +0 -0
  166. data/doc/ex/images/Button_B.gif +0 -0
  167. data/doc/ex/images/Button_C.gif +0 -0
  168. data/doc/ex/images/Button_D.gif +0 -0
  169. data/doc/ex/images/Button_E.gif +0 -0
  170. data/doc/ex/images/Button_F.gif +0 -0
  171. data/doc/ex/images/Button_G.gif +0 -0
  172. data/doc/ex/images/Button_H.gif +0 -0
  173. data/doc/ex/images/Button_I.gif +0 -0
  174. data/doc/ex/images/Button_J.gif +0 -0
  175. data/doc/ex/images/Button_K.gif +0 -0
  176. data/doc/ex/images/Button_L.gif +0 -0
  177. data/doc/ex/images/Button_M.gif +0 -0
  178. data/doc/ex/images/Button_N.gif +0 -0
  179. data/doc/ex/images/Button_O.gif +0 -0
  180. data/doc/ex/images/Button_P.gif +0 -0
  181. data/doc/ex/images/Button_Q.gif +0 -0
  182. data/doc/ex/images/Button_R.gif +0 -0
  183. data/doc/ex/images/Button_S.gif +0 -0
  184. data/doc/ex/images/Button_T.gif +0 -0
  185. data/doc/ex/images/Button_U.gif +0 -0
  186. data/doc/ex/images/Button_V.gif +0 -0
  187. data/doc/ex/images/Button_W.gif +0 -0
  188. data/doc/ex/images/Button_X.gif +0 -0
  189. data/doc/ex/images/Button_Y.gif +0 -0
  190. data/doc/ex/images/Button_Z.gif +0 -0
  191. data/doc/ex/images/Cheetah.jpg +0 -0
  192. data/doc/ex/images/Coffee.wmf +0 -0
  193. data/doc/ex/images/Flower_Hat.jpg +0 -0
  194. data/doc/ex/images/Gold_Statue.jpg +0 -0
  195. data/doc/ex/images/Hot_Air_Balloons.jpg +0 -0
  196. data/doc/ex/images/Hot_Air_Balloons_H.jpg +0 -0
  197. data/doc/ex/images/Leaf.miff +0 -0
  198. data/doc/ex/images/No.wmf +0 -0
  199. data/doc/ex/images/Polynesia.jpg +0 -0
  200. data/doc/ex/images/Red_Rocks.jpg +0 -0
  201. data/doc/ex/images/Rocks_On_Beach.miff +0 -0
  202. data/doc/ex/images/Shorts.jpg +0 -0
  203. data/doc/ex/images/Snake.wmf +0 -0
  204. data/doc/ex/images/Violin.jpg +0 -0
  205. data/doc/ex/images/Yellow_Rose.miff +0 -0
  206. data/doc/ex/images/big-duck.gif +0 -0
  207. data/doc/ex/images/duck.gif +0 -0
  208. data/doc/ex/images/duck0.gif +0 -0
  209. data/doc/ex/images/duck1.gif +0 -0
  210. data/doc/ex/images/duck10.gif +0 -0
  211. data/doc/ex/images/duck11.gif +0 -0
  212. data/doc/ex/images/duck12.gif +0 -0
  213. data/doc/ex/images/duck13.gif +0 -0
  214. data/doc/ex/images/duck14.gif +0 -0
  215. data/doc/ex/images/duck15.gif +0 -0
  216. data/doc/ex/images/duck2.gif +0 -0
  217. data/doc/ex/images/duck3.gif +0 -0
  218. data/doc/ex/images/duck4.gif +0 -0
  219. data/doc/ex/images/duck5.gif +0 -0
  220. data/doc/ex/images/duck6.gif +0 -0
  221. data/doc/ex/images/duck7.gif +0 -0
  222. data/doc/ex/images/duck8.gif +0 -0
  223. data/doc/ex/images/duck9.gif +0 -0
  224. data/doc/ex/images/graydient230x6.gif +0 -0
  225. data/doc/ex/images/image_with_profile.jpg +0 -0
  226. data/doc/ex/images/logo400x83.gif +0 -0
  227. data/doc/ex/images/model.miff +0 -0
  228. data/doc/ex/images/notimplemented.gif +0 -0
  229. data/doc/ex/images/smile.miff +0 -0
  230. data/doc/ex/images/spin.gif +0 -0
  231. data/doc/ex/implode.rb +0 -34
  232. data/doc/ex/level.rb +0 -11
  233. data/doc/ex/level_colors.rb +0 -11
  234. data/doc/ex/line.rb +0 -41
  235. data/doc/ex/line01.rb +0 -21
  236. data/doc/ex/mask.rb +0 -35
  237. data/doc/ex/matte_fill_to_border.rb +0 -39
  238. data/doc/ex/matte_floodfill.rb +0 -32
  239. data/doc/ex/matte_replace.rb +0 -39
  240. data/doc/ex/median_filter.rb +0 -28
  241. data/doc/ex/modulate.rb +0 -11
  242. data/doc/ex/mono.rb +0 -23
  243. data/doc/ex/morph.rb +0 -25
  244. data/doc/ex/mosaic.rb +0 -35
  245. data/doc/ex/motion_blur.rb +0 -11
  246. data/doc/ex/negate.rb +0 -11
  247. data/doc/ex/negate_channel.rb +0 -9
  248. data/doc/ex/nested_rvg.rb +0 -21
  249. data/doc/ex/nonzero.rb +0 -42
  250. data/doc/ex/normalize.rb +0 -11
  251. data/doc/ex/oil_paint.rb +0 -11
  252. data/doc/ex/opacity.rb +0 -37
  253. data/doc/ex/ordered_dither.rb +0 -11
  254. data/doc/ex/path.rb +0 -63
  255. data/doc/ex/pattern1.rb +0 -25
  256. data/doc/ex/pattern2.rb +0 -26
  257. data/doc/ex/polaroid.rb +0 -27
  258. data/doc/ex/polygon.rb +0 -23
  259. data/doc/ex/polygon01.rb +0 -21
  260. data/doc/ex/polyline.rb +0 -22
  261. data/doc/ex/polyline01.rb +0 -21
  262. data/doc/ex/posterize.rb +0 -8
  263. data/doc/ex/preview.rb +0 -8
  264. data/doc/ex/qbezierpath.rb +0 -52
  265. data/doc/ex/quad01.rb +0 -34
  266. data/doc/ex/quantize-m.rb +0 -25
  267. data/doc/ex/radial_blur.rb +0 -9
  268. data/doc/ex/raise.rb +0 -8
  269. data/doc/ex/random_threshold_channel.rb +0 -13
  270. data/doc/ex/rect01.rb +0 -14
  271. data/doc/ex/rect02.rb +0 -20
  272. data/doc/ex/rectangle.rb +0 -34
  273. data/doc/ex/reduce_noise.rb +0 -28
  274. data/doc/ex/remap.rb +0 -11
  275. data/doc/ex/remap_images.rb +0 -19
  276. data/doc/ex/resize_to_fill.rb +0 -8
  277. data/doc/ex/resize_to_fit.rb +0 -8
  278. data/doc/ex/roll.rb +0 -9
  279. data/doc/ex/rotate.rb +0 -44
  280. data/doc/ex/rotate_f.rb +0 -14
  281. data/doc/ex/roundrect.rb +0 -33
  282. data/doc/ex/rubyname.rb +0 -30
  283. data/doc/ex/rvg_clippath.rb +0 -12
  284. data/doc/ex/rvg_linecap.rb +0 -42
  285. data/doc/ex/rvg_linejoin.rb +0 -40
  286. data/doc/ex/rvg_opacity.rb +0 -18
  287. data/doc/ex/rvg_pattern.rb +0 -26
  288. data/doc/ex/rvg_stroke_dasharray.rb +0 -11
  289. data/doc/ex/segment.rb +0 -11
  290. data/doc/ex/sepiatone.rb +0 -7
  291. data/doc/ex/shade.rb +0 -11
  292. data/doc/ex/shadow.rb +0 -30
  293. data/doc/ex/shave.rb +0 -15
  294. data/doc/ex/shear.rb +0 -10
  295. data/doc/ex/sketch.rb +0 -17
  296. data/doc/ex/skewx.rb +0 -51
  297. data/doc/ex/skewy.rb +0 -47
  298. data/doc/ex/smile.rb +0 -125
  299. data/doc/ex/solarize.rb +0 -11
  300. data/doc/ex/sparse_color.rb +0 -54
  301. data/doc/ex/splice.rb +0 -8
  302. data/doc/ex/spread.rb +0 -11
  303. data/doc/ex/stegano.rb +0 -55
  304. data/doc/ex/stroke_dasharray.rb +0 -42
  305. data/doc/ex/stroke_fill.rb +0 -10
  306. data/doc/ex/stroke_linecap.rb +0 -44
  307. data/doc/ex/stroke_linejoin.rb +0 -48
  308. data/doc/ex/stroke_width.rb +0 -49
  309. data/doc/ex/swirl.rb +0 -17
  310. data/doc/ex/text.rb +0 -37
  311. data/doc/ex/text01.rb +0 -16
  312. data/doc/ex/text_align.rb +0 -36
  313. data/doc/ex/text_antialias.rb +0 -37
  314. data/doc/ex/text_styles.rb +0 -19
  315. data/doc/ex/text_undercolor.rb +0 -28
  316. data/doc/ex/texture_fill_to_border.rb +0 -34
  317. data/doc/ex/texture_floodfill.rb +0 -32
  318. data/doc/ex/texturefill.rb +0 -24
  319. data/doc/ex/threshold.rb +0 -13
  320. data/doc/ex/to_blob.rb +0 -13
  321. data/doc/ex/translate.rb +0 -39
  322. data/doc/ex/transparent.rb +0 -38
  323. data/doc/ex/transpose.rb +0 -9
  324. data/doc/ex/transverse.rb +0 -9
  325. data/doc/ex/tref01.rb +0 -24
  326. data/doc/ex/triangle01.rb +0 -15
  327. data/doc/ex/trim.rb +0 -23
  328. data/doc/ex/tspan01.rb +0 -17
  329. data/doc/ex/tspan02.rb +0 -17
  330. data/doc/ex/tspan03.rb +0 -19
  331. data/doc/ex/unsharp_mask.rb +0 -28
  332. data/doc/ex/viewex.rb +0 -33
  333. data/doc/ex/vignette.rb +0 -12
  334. data/doc/ex/watermark.rb +0 -27
  335. data/doc/ex/wave.rb +0 -9
  336. data/doc/ex/wet_floor.rb +0 -58
  337. data/doc/ex/writing_mode01.rb +0 -26
  338. data/doc/ex/writing_mode02.rb +0 -26
  339. data/doc/ilist.html +0 -2056
  340. data/doc/image1.html +0 -4680
  341. data/doc/image2.html +0 -3665
  342. data/doc/image3.html +0 -4522
  343. data/doc/imageattrs.html +0 -1638
  344. data/doc/imusage.html +0 -514
  345. data/doc/index.html +0 -416
  346. data/doc/info.html +0 -1499
  347. data/doc/magick.html +0 -565
  348. data/doc/optequiv.html +0 -2435
  349. data/doc/rvg.html +0 -975
  350. data/doc/rvgclip.html +0 -248
  351. data/doc/rvggroup.html +0 -305
  352. data/doc/rvgimage.html +0 -289
  353. data/doc/rvgpattern.html +0 -475
  354. data/doc/rvgshape.html +0 -406
  355. data/doc/rvgstyle.html +0 -270
  356. data/doc/rvgtext.html +0 -465
  357. data/doc/rvgtspan.html +0 -238
  358. data/doc/rvgtut.html +0 -530
  359. data/doc/rvguse.html +0 -145
  360. data/doc/rvgxform.html +0 -294
  361. data/doc/scripts/doc.js +0 -22
  362. data/doc/scripts/stripeTables.js +0 -23
  363. data/doc/struct.html +0 -1339
  364. data/doc/usage.html +0 -1621
  365. data/examples/constitute.rb +0 -7
  366. data/examples/crop_with_gravity.rb +0 -42
  367. data/examples/demo.rb +0 -324
  368. data/examples/describe.rb +0 -43
  369. data/examples/find_similar_region.rb +0 -34
  370. data/examples/histogram.rb +0 -321
  371. data/examples/identify.rb +0 -185
  372. data/examples/image_opacity.rb +0 -29
  373. data/examples/import_export.rb +0 -31
  374. data/examples/pattern_fill.rb +0 -38
  375. data/examples/rotating_text.rb +0 -44
  376. data/examples/spinner.rb +0 -49
  377. data/examples/thumbnail.rb +0 -64
  378. data/examples/vignette.rb +0 -78
  379. data/spec/rmagick/ImageList1_spec.rb +0 -24
  380. data/spec/rmagick/draw_spec.rb +0 -156
  381. data/spec/rmagick/image/blue_shift_spec.rb +0 -16
  382. data/spec/rmagick/image/composite_spec.rb +0 -140
  383. data/spec/rmagick/image/constitute_spec.rb +0 -15
  384. data/spec/rmagick/image/dispatch_spec.rb +0 -18
  385. data/spec/rmagick/image/from_blob_spec.rb +0 -14
  386. data/spec/rmagick/image/ping_spec.rb +0 -14
  387. data/spec/rmagick/image/properties_spec.rb +0 -29
  388. data/spec/spec_helper.rb +0 -4
  389. data/test/Image1.rb +0 -565
  390. data/test/Image2.rb +0 -1304
  391. data/test/Image3.rb +0 -1030
  392. data/test/ImageList1.rb +0 -806
  393. data/test/ImageList2.rb +0 -385
  394. data/test/Image_attributes.rb +0 -697
  395. data/test/Import_Export.rb +0 -121
  396. data/test/Info.rb +0 -345
  397. data/test/Magick.rb +0 -321
  398. data/test/Pixel.rb +0 -116
  399. data/test/Preview.rb +0 -57
  400. data/test/cmyk.icm +0 -0
  401. data/test/srgb.icm +0 -0
  402. data/test/test_all_basic.rb +0 -38
  403. data/test/tmpnam_test.rb +0 -50
  404. data/wercker.yml +0 -10
data/ext/RMagick/rmutil.c CHANGED
@@ -12,10 +12,19 @@
12
12
 
13
13
  #include "rmagick.h"
14
14
  #include <errno.h>
15
+ #if defined(_WIN32)
16
+ #include <Windows.h>
17
+ #else
18
+ #include <pthread.h>
19
+ #endif
15
20
 
21
+ static VALUE rescue_not_str(VALUE, VALUE ATTRIBUTE_UNUSED) ATTRIBUTE_NORETURN;
16
22
  static void handle_exception(ExceptionInfo *, Image *, ErrorRetention);
17
23
 
18
24
 
25
+ DEFINE_GVL_STUB5(CloneImage, const Image *, const size_t, const size_t, const MagickBooleanType, ExceptionInfo *);
26
+
27
+
19
28
  /**
20
29
  * ImageMagick safe version of malloc.
21
30
  *
@@ -78,7 +87,7 @@ magick_malloc(const size_t size)
78
87
  void
79
88
  magick_free(void *ptr)
80
89
  {
81
- (void) RelinquishMagickMemory(ptr);
90
+ RelinquishMagickMemory(ptr);
82
91
  }
83
92
 
84
93
 
@@ -112,28 +121,6 @@ magick_safe_realloc(void *memory, const size_t count, const size_t quantum)
112
121
  }
113
122
 
114
123
 
115
- /**
116
- * ImageMagick version of realloc.
117
- *
118
- * No Ruby usage (internal function)
119
- *
120
- * @param ptr pointer to the existing block of memory
121
- * @param size the new size of memory to allocate
122
- * @return pointer to a block of memory
123
- */
124
- void *
125
- magick_realloc(void *ptr, const size_t size)
126
- {
127
- void *v;
128
- v = ResizeMagickMemory(ptr, size);
129
- if (!v)
130
- {
131
- rb_raise(rb_eNoMemError, "not enough memory to continue");
132
- }
133
- return v;
134
- }
135
-
136
-
137
124
  /**
138
125
  * Make a copy of a string in malloc'd memory.
139
126
  *
@@ -149,7 +136,7 @@ magick_realloc(void *ptr, const size_t size)
149
136
  void
150
137
  magick_clone_string(char **new_str, const char *str)
151
138
  {
152
- (void) CloneString(new_str, str);
139
+ CloneString(new_str, str);
153
140
  }
154
141
 
155
142
 
@@ -208,6 +195,28 @@ rm_strncasecmp(const char *s1, const char *s2, size_t n)
208
195
  }
209
196
 
210
197
 
198
+ /**
199
+ * Get string length.
200
+ *
201
+ * No Ruby usage (internal function)
202
+ *
203
+ * @param str the string
204
+ * @param strsz the maximum number of characters
205
+ * @return same as strnlen_s()
206
+ */
207
+ size_t
208
+ rm_strnlen_s(const char *str, size_t strsz)
209
+ {
210
+ size_t length = 0;
211
+ while(*str && length < strsz)
212
+ {
213
+ str++;
214
+ length++;
215
+ }
216
+ return length;
217
+ }
218
+
219
+
211
220
  /**
212
221
  * Raise exception if array too short.
213
222
  *
@@ -228,6 +237,27 @@ rm_check_ary_len(VALUE ary, long len)
228
237
  }
229
238
 
230
239
 
240
+ /**
241
+ * Raise exception if ary argument was invalid type
242
+ *
243
+ * No Ruby usage (internal function)
244
+ *
245
+ * @param ary the array
246
+ * @return the array that is converted type of argument object if needed
247
+ * @throw TypeError
248
+ */
249
+ VALUE
250
+ rm_check_ary_type(VALUE ary)
251
+ {
252
+ VALUE checked = rb_check_array_type(ary);
253
+ if (NIL_P(checked))
254
+ {
255
+ rb_raise(rb_eTypeError, "wrong argument type %"RMIsVALUE" was given. (must respond to :to_ary)", rb_obj_class(ary));
256
+ }
257
+ return checked;
258
+ }
259
+
260
+
231
261
  /**
232
262
  * Raise an error if the image has been destroyed.
233
263
  *
@@ -242,7 +272,7 @@ rm_check_destroyed(VALUE obj)
242
272
  {
243
273
  Image *image;
244
274
 
245
- Data_Get_Struct(obj, Image, image);
275
+ TypedData_Get_Struct(obj, Image, &rm_image_data_type, image);
246
276
  if (!image)
247
277
  {
248
278
  rb_raise(Class_DestroyedImageError, "destroyed image");
@@ -274,35 +304,12 @@ rm_check_frozen(VALUE obj)
274
304
  *
275
305
  * No Ruby usage (internal function)
276
306
  *
277
- * @param obj the object of the class to override
278
- * @return 0
279
- * @throw TypeError
307
+ * @raise [TypeError]
280
308
  */
281
309
  VALUE
282
310
  rm_no_freeze(VALUE obj)
283
311
  {
284
312
  rb_raise(rb_eTypeError, "can't freeze %s", rb_class2name(CLASS_OF(obj)));
285
- return (VALUE)0;
286
- }
287
-
288
-
289
- /**
290
- * Return obj.to_s, or obj if obj is already a string.
291
- *
292
- * No Ruby usage (internal function)
293
- *
294
- * @param obj a Ruby object
295
- * @return a String representation of obj
296
- */
297
- VALUE
298
- rm_to_s(VALUE obj)
299
- {
300
-
301
- if (TYPE(obj) != T_STRING)
302
- {
303
- return rb_funcall(obj, rm_ID_to_s, 0);
304
- }
305
- return obj;
306
313
  }
307
314
 
308
315
 
@@ -327,24 +334,6 @@ rm_str2cstr(VALUE str, long *len)
327
334
  }
328
335
 
329
336
 
330
- /**
331
- * Try to convert the argument to a double, raise an exception if fail.
332
- *
333
- * No Ruby usage (internal function)
334
- *
335
- * @param arg the argument
336
- * @return arg
337
- */
338
- static VALUE
339
- arg_is_number(VALUE arg)
340
- {
341
- double d;
342
- d = NUM2DBL(arg);
343
- d = d; // satisfy icc
344
- return arg;
345
- }
346
-
347
-
348
337
  /**
349
338
  * Called when `rb_str_to_str' raises an exception.
350
339
  *
@@ -355,11 +344,10 @@ arg_is_number(VALUE arg)
355
344
  * @throw TypeError
356
345
  */
357
346
  static VALUE
358
- rescue_not_str(VALUE arg)
347
+ rescue_not_str(VALUE arg, VALUE raised_exc ATTRIBUTE_UNUSED)
359
348
  {
360
349
  rb_raise(rb_eTypeError, "argument must be a number or a string in the form 'NN%%' (%s given)",
361
350
  rb_class2name(CLASS_OF(arg)));
362
- return (VALUE)0;
363
351
  }
364
352
 
365
353
 
@@ -378,17 +366,15 @@ double
378
366
  rm_percentage(VALUE arg, double max)
379
367
  {
380
368
  double pct;
381
- long pct_long;
382
- char *pct_str, *end;
383
- int not_num;
384
-
385
- // Try to convert the argument to a number. If failure, sets not_num to non-zero.
386
- (void) rb_protect(arg_is_number, arg, &not_num);
369
+ char *end;
387
370
 
388
- if (not_num)
371
+ if (!rm_check_num2dbl(arg))
389
372
  {
373
+ char *pct_str;
374
+ long pct_long;
375
+
390
376
  arg = rb_rescue(rb_str_to_str, arg, rescue_not_str, arg);
391
- pct_str = StringValuePtr(arg);
377
+ pct_str = StringValueCStr(arg);
392
378
  errno = 0;
393
379
  pct_long = strtol(pct_str, &end, 10);
394
380
  if (errno == ERANGE)
@@ -437,7 +423,7 @@ rm_percentage(VALUE arg, double max)
437
423
  static VALUE
438
424
  check_num2dbl(VALUE obj)
439
425
  {
440
- (void) rb_num2dbl(obj);
426
+ rb_num2dbl(obj);
441
427
  return INT2FIX(1);
442
428
  }
443
429
 
@@ -451,9 +437,8 @@ check_num2dbl(VALUE obj)
451
437
  * @return 0
452
438
  */
453
439
  static VALUE
454
- rescue_not_dbl(VALUE ignored)
440
+ rescue_not_dbl(VALUE ignored ATTRIBUTE_UNUSED, VALUE raised_exc ATTRIBUTE_UNUSED)
455
441
  {
456
- ignored = ignored; // defeat gcc message
457
442
  return INT2FIX(0);
458
443
  }
459
444
 
@@ -488,7 +473,7 @@ rm_str_to_pct(VALUE str)
488
473
  char *pct_str, *end;
489
474
 
490
475
  str = rb_rescue(rb_str_to_str, str, rescue_not_str, str);
491
- pct_str = StringValuePtr(str);
476
+ pct_str = StringValueCStr(str);
492
477
  errno = 0;
493
478
  pct = strtol(pct_str, &end, 10);
494
479
 
@@ -524,17 +509,15 @@ double
524
509
  rm_fuzz_to_dbl(VALUE fuzz_arg)
525
510
  {
526
511
  double fuzz;
527
- char *fuzz_str, *end;
528
- int not_num;
512
+ char *end;
529
513
 
530
- // Try to convert the argument to a number. If failure, sets not_num to non-zero.
531
- (void) rb_protect(arg_is_number, fuzz_arg, &not_num);
532
-
533
- if (not_num)
514
+ if (!rm_check_num2dbl(fuzz_arg))
534
515
  {
516
+ char *fuzz_str;
517
+
535
518
  // Convert to string, issue error message if failure.
536
519
  fuzz_arg = rb_rescue(rb_str_to_str, fuzz_arg, rescue_not_str, fuzz_arg);
537
- fuzz_str = StringValuePtr(fuzz_arg);
520
+ fuzz_str = StringValueCStr(fuzz_arg);
538
521
  errno = 0;
539
522
  fuzz = strtod(fuzz_str, &end);
540
523
  if (errno == ERANGE)
@@ -589,15 +572,39 @@ rm_app2quantum(VALUE obj)
589
572
 
590
573
  if (TYPE(obj) == T_FLOAT)
591
574
  {
592
- v = rb_funcall(obj, rm_ID_to_i, 0);
575
+ v = rb_Integer(obj);
593
576
  }
594
577
 
595
- RB_GC_GUARD(v);
596
-
597
578
  return NUM2QUANTUM(v);
598
579
  }
599
580
 
600
581
 
582
+ /**
583
+ * Returns a pointer to an image structure initialized to default values
584
+ *
585
+ * No Ruby usage (internal function)
586
+ *
587
+ * @param info the info
588
+ * @return the created image
589
+ */
590
+ Image *
591
+ rm_acquire_image(ImageInfo *info)
592
+ {
593
+ #if defined(IMAGEMAGICK_7)
594
+ Image *new_image;
595
+ ExceptionInfo *exception;
596
+
597
+ exception = AcquireExceptionInfo();
598
+ new_image = AcquireImage(info, exception);
599
+ CHECK_EXCEPTION();
600
+ DestroyExceptionInfo(exception);
601
+ return new_image;
602
+ #else
603
+ return AcquireImage(info);
604
+ #endif
605
+ }
606
+
607
+
601
608
  /**
602
609
  * Send the "cur_image" method to the object. If 'img' is an ImageList, then
603
610
  * cur_image is self[\@scene]. If 'img' is an image, then cur_image is simply
@@ -621,21 +628,28 @@ rm_cur_image(VALUE img)
621
628
  * No Ruby usage (internal function)
622
629
  *
623
630
  * @param image the image
624
- * @param color the color intensity as a PixelPacket
631
+ * @param color the color intensity as a PixelColor
625
632
  * @return the named color as a String
626
- * @see rm_pixelpacket_to_color_name_info
633
+ * @see rm_pixelcolor_to_color_name_info
627
634
  */
628
635
  VALUE
629
- rm_pixelpacket_to_color_name(Image *image, PixelPacket *color)
636
+ rm_pixelcolor_to_color_name(Image *image, PixelColor *color)
630
637
  {
638
+ PixelColor pp;
631
639
  char name[MaxTextExtent];
632
640
  ExceptionInfo *exception;
633
641
 
634
642
  exception = AcquireExceptionInfo();
635
643
 
636
- (void) QueryColorname(image, color, X11Compliance, name, exception);
637
- CHECK_EXCEPTION()
638
- (void) DestroyExceptionInfo(exception);
644
+ pp = *color;
645
+ #if defined(IMAGEMAGICK_7)
646
+ pp.depth = MAGICKCORE_QUANTUM_DEPTH;
647
+ pp.colorspace = image->colorspace;
648
+ #endif
649
+
650
+ QueryColorname(image, &pp, X11Compliance, name, exception);
651
+ CHECK_EXCEPTION();
652
+ DestroyExceptionInfo(exception);
639
653
 
640
654
  return rb_str_new2(name);
641
655
  }
@@ -649,38 +663,80 @@ rm_pixelpacket_to_color_name(Image *image, PixelPacket *color)
649
663
  * Notes:
650
664
  * - Simply create an Image from the Info, call QueryColorname, and then
651
665
  * destroy the Image.
652
- * - If the Info structure is NULL, creates a new one.
653
666
  * - The default depth is always used, and the matte value is set to False,
654
667
  * which means "don't use the alpha channel".
655
668
  *
656
669
  * @param info the info
657
- * @param color the color intensity as a PixelPacket
670
+ * @param color the color intensity as a PixelColor
658
671
  * @return the named color as a String
659
- * @see rm_pixelpacket_to_color_name
672
+ * @see rm_pixelcolor_to_color_name
660
673
  */
661
674
  VALUE
662
- rm_pixelpacket_to_color_name_info(Info *info, PixelPacket *color)
675
+ rm_pixelcolor_to_color_name_info(Info *info, PixelColor *color)
663
676
  {
664
677
  Image *image;
665
- Info *my_info;
666
678
  VALUE color_name;
667
679
 
668
- my_info = info ? info : CloneImageInfo(NULL);
669
-
670
- image = AcquireImage(info);
671
- image->matte = MagickFalse;
672
- color_name = rm_pixelpacket_to_color_name(image, color);
673
- (void) DestroyImage(image);
674
- if (!info)
680
+ image = rm_acquire_image(info);
681
+ if (!image)
675
682
  {
676
- (void) DestroyImageInfo(my_info);
683
+ rb_raise(rb_eNoMemError, "not enough memory to continue.");
677
684
  }
678
685
 
679
- RB_GC_GUARD(color_name);
686
+ #if defined(IMAGEMAGICK_7)
687
+ image->alpha_trait = UndefinedPixelTrait;
688
+ #else
689
+ image->matte = MagickFalse;
690
+ #endif
691
+
692
+ color_name = rm_pixelcolor_to_color_name(image, color);
693
+ DestroyImage(image);
680
694
 
681
695
  return color_name;
682
696
  }
683
697
 
698
+ /**
699
+ * Initializes the MagickPixel structure.
700
+ *
701
+ * No Ruby usage (internal function)
702
+ *
703
+ * @param image the image
704
+ * @param pp the MagickPixel
705
+ */
706
+ void
707
+ rm_init_magickpixel(const Image *image, MagickPixel *pp)
708
+ {
709
+ #if defined(IMAGEMAGICK_7)
710
+ GetPixelInfo(image, pp);
711
+ #else
712
+ GetMagickPixelPacket(image, pp);
713
+ #endif
714
+ }
715
+
716
+ /**
717
+ * Initializes the MagickPixel structure to the specified color.
718
+ *
719
+ * No Ruby usage (internal function)
720
+ *
721
+ * @param pp the MagickPixel
722
+ * @param color the color
723
+ */
724
+ void
725
+ rm_set_magickpixel(MagickPixel *pp, const char *color)
726
+ {
727
+ ExceptionInfo *exception;
728
+
729
+ exception = AcquireExceptionInfo();
730
+
731
+ #if defined(IMAGEMAGICK_7)
732
+ QueryColorCompliance(color, AllCompliance, pp, exception);
733
+ #else
734
+ QueryMagickColor(color, pp, exception);
735
+ #endif
736
+ // This exception is ignored because the color comes from places where we control
737
+ // the value and it is very unlikely that an exception will be thrown.
738
+ DestroyExceptionInfo(exception);
739
+ }
684
740
 
685
741
  /**
686
742
  * Write a temporary copy of the image to the IM registry.
@@ -693,10 +749,11 @@ rm_pixelpacket_to_color_name_info(Info *info, PixelPacket *color)
693
749
  *
694
750
  * @param image the image
695
751
  * @param temp_name the temporary name to use
752
+ * @param temp_name_l the length of temp_name
696
753
  * @return the "filename" of the registered image
697
754
  */
698
755
  void
699
- rm_write_temp_image(Image *image, char *temp_name)
756
+ rm_write_temp_image(Image *image, char *temp_name, size_t temp_name_l)
700
757
  {
701
758
 
702
759
  #define TMPNAM_CLASS_VAR "@@_tmpnam_"
@@ -723,11 +780,11 @@ rm_write_temp_image(Image *image, char *temp_name)
723
780
 
724
781
  id += 1;
725
782
  rb_cv_set(Module_Magick, TMPNAM_CLASS_VAR, INT2FIX(id));
726
- sprintf(temp_name, "mpri:%d", id);
783
+ snprintf(temp_name, temp_name_l, "mpri:%d", id);
727
784
 
728
785
  // Omit "mpri:" from filename to form the key
729
- okay = SetImageRegistry(ImageRegistryType, temp_name+5, image, exception);
730
- CHECK_EXCEPTION()
786
+ okay = (MagickBooleanType)SetImageRegistry(ImageRegistryType, temp_name+5, image, exception);
787
+ CHECK_EXCEPTION();
731
788
  DestroyExceptionInfo(exception);
732
789
  if (!okay)
733
790
  {
@@ -773,7 +830,7 @@ rm_not_implemented(void)
773
830
  {
774
831
 
775
832
  rb_raise(rb_eNotImpError, "the `%s' method is not supported by ImageMagick "
776
- MagickLibVersionText, rb_id2name(THIS_FUNC()));
833
+ MagickLibVersionText, rb_id2name(rb_frame_this_func()));
777
834
  }
778
835
 
779
836
 
@@ -787,42 +844,51 @@ rm_not_implemented(void)
787
844
  * the ImageMagickError object in both 1.6.8 and 1.8.0.
788
845
  *
789
846
  * @param msg the error mesage
790
- * @param loc the location of the error
791
847
  * @throw ImageMagickError
792
848
  * @see www.ruby_talk.org/36408.
793
849
  */
794
850
  void
795
- rm_magick_error(const char *msg, const char *loc)
851
+ rm_magick_error(const char *msg)
796
852
  {
797
- VALUE exc, mesg, extra;
853
+ VALUE exc, mesg;
798
854
 
799
855
  mesg = rb_str_new2(msg);
800
- extra = loc ? rb_str_new2(loc) : Qnil;
801
856
 
802
- exc = rb_funcall(Class_ImageMagickError, rm_ID_new, 2, mesg, extra);
803
- (void) rb_funcall(rb_cObject, rb_intern("raise"), 1, exc);
857
+ exc = rb_funcall(Class_ImageMagickError, rm_ID_new, 2, mesg, Qnil);
858
+ rb_funcall(rb_cObject, rb_intern("raise"), 1, exc);
804
859
 
805
860
  RB_GC_GUARD(exc);
806
861
  RB_GC_GUARD(mesg);
807
- RB_GC_GUARD(extra);
808
862
  }
809
863
 
810
-
864
+ #if defined(IMAGEMAGICK_7)
811
865
  /**
812
- * Initialize a new ImageMagickError object - store the "loc" string in the
813
- * \@magick_location instance variable.
866
+ * Sets the alpha channel of a pixel color
814
867
  *
815
- * Ruby usage:
816
- * - @verbatim ImageMagickError#initialize(msg) @endverbatim
817
- * - @verbatim ImageMagickError#initialize(msg, loc) @endverbatim
868
+ * No Ruby usage (internal function)
818
869
  *
819
- * Notes:
820
- * - Default loc is nil
870
+ * @param pixel the Pixel
871
+ * @param value the value
872
+ */
873
+ void
874
+ rm_set_pixelinfo_alpha(PixelInfo *pixel, const MagickRealType value)
875
+ {
876
+ pixel->alpha = value;
877
+ if (value != (MagickRealType) OpaqueAlpha)
878
+ {
879
+ pixel->alpha_trait = BlendPixelTrait;
880
+ }
881
+ }
882
+ #endif
883
+
884
+ /**
885
+ * Initialize a new ImageMagickError object - store the "loc" string in the
886
+ * magick_location instance variable.
821
887
  *
822
- * @param argc number of input arguments
823
- * @param argv array of input arguments
824
- * @param self this object
825
- * @return self
888
+ * @overload initialize(msg, loc = nil)
889
+ * @param msg [String] the exception message
890
+ * @param loc [String] the location stored in the magick_location instance variable
891
+ * @return [Magick::ImageMagickError] self
826
892
  */
827
893
  VALUE
828
894
  ImageMagickError_initialize(int argc, VALUE *argv, VALUE self)
@@ -844,8 +910,8 @@ ImageMagickError_initialize(int argc, VALUE *argv, VALUE self)
844
910
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 2)", argc);
845
911
  }
846
912
 
847
- (void) rb_call_super(super_argc, (const VALUE *)super_argv);
848
- (void) rb_iv_set(self, "@"MAGICK_LOC, extra);
913
+ rb_call_super(super_argc, (const VALUE *)super_argv);
914
+ rb_iv_set(self, "@"MAGICK_LOC, extra);
849
915
 
850
916
  RB_GC_GUARD(extra);
851
917
 
@@ -865,7 +931,18 @@ ImageMagickError_initialize(int argc, VALUE *argv, VALUE self)
865
931
  const char *
866
932
  rm_get_property(const Image *img, const char *property)
867
933
  {
934
+ #if defined(IMAGEMAGICK_7)
935
+ const char *result;
936
+ ExceptionInfo *exception;
937
+
938
+ exception = AcquireExceptionInfo();
939
+ result = GetImageProperty(img, property, exception);
940
+ CHECK_EXCEPTION();
941
+ DestroyExceptionInfo(exception);
942
+ return result;
943
+ #else
868
944
  return GetImageProperty(img, property);
945
+ #endif
869
946
  }
870
947
 
871
948
 
@@ -875,14 +952,25 @@ rm_get_property(const Image *img, const char *property)
875
952
  * No Ruby usage (internal function)
876
953
  *
877
954
  * @param image the image
878
- * @param property the property name
955
+ * @param property the property name
879
956
  * @param value the property value
880
957
  * @return true if successful, otherwise false
881
958
  */
882
959
  MagickBooleanType
883
960
  rm_set_property(Image *image, const char *property, const char *value)
884
961
  {
962
+ #if defined(IMAGEMAGICK_7)
963
+ ExceptionInfo *exception;
964
+ MagickBooleanType okay;
965
+
966
+ exception = AcquireExceptionInfo();
967
+ okay = SetImageProperty(image, property, value, exception);
968
+ CHECK_EXCEPTION();
969
+ DestroyExceptionInfo(exception);
970
+ return okay;
971
+ #else
885
972
  return SetImageProperty(image, property, value);
973
+ #endif
886
974
  }
887
975
 
888
976
 
@@ -897,24 +985,20 @@ rm_set_property(Image *image, const char *property, const char *value)
897
985
  */
898
986
  void rm_set_user_artifact(Image *images, Info *info)
899
987
  {
900
- #if defined(HAVE_SETIMAGEARTIFACT)
901
- Image *image;
902
988
  const char *value;
903
989
 
904
990
  value = GetImageOption(info, "user");
905
991
  if (value)
906
992
  {
993
+ Image *image;
994
+
907
995
  image = GetFirstImageInList(images);
908
996
  while (image)
909
997
  {
910
- (void) SetImageArtifact(image, "user", value);
998
+ SetImageArtifact(image, "user", value);
911
999
  image = GetNextImageInList(image);
912
1000
  }
913
1001
  }
914
- #else
915
- images = images;
916
- info = info;
917
- #endif
918
1002
  }
919
1003
 
920
1004
 
@@ -943,7 +1027,8 @@ rm_get_optional_arguments(VALUE img)
943
1027
  optional_method_arguments = rb_const_get_from(Module_Magick, rb_intern("OptionalMethodArguments"));
944
1028
  argv[0] = img;
945
1029
  opt_args = rb_class_new_instance(1, argv, optional_method_arguments);
946
- (void) rb_obj_instance_eval(0, NULL, opt_args);
1030
+
1031
+ rb_yield(opt_args);
947
1032
  }
948
1033
 
949
1034
  RB_GC_GUARD(optional_method_arguments);
@@ -953,7 +1038,6 @@ rm_get_optional_arguments(VALUE img)
953
1038
  }
954
1039
 
955
1040
 
956
- #if defined(HAVE_SETIMAGEARTIFACT)
957
1041
  /**
958
1042
  * Copy image options from the Info structure to the Image structure.
959
1043
  *
@@ -965,21 +1049,21 @@ rm_get_optional_arguments(VALUE img)
965
1049
  static void copy_options(Image *image, Info *info)
966
1050
  {
967
1051
  char property[MaxTextExtent];
968
- const char *value, *option;
1052
+ const char *option;
969
1053
 
970
1054
  ResetImageOptionIterator(info);
971
1055
  for (option = GetNextImageOption(info); option; option = GetNextImageOption(info))
972
1056
  {
973
- value = GetImageOption(info,option);
1057
+ const char *value;
1058
+
1059
+ value = GetImageOption(info, option);
974
1060
  if (value)
975
1061
  {
976
- strncpy(property, value, MaxTextExtent);
977
- property[MaxTextExtent-1] = '\0';
978
- (void) SetImageArtifact(image, property, value);
1062
+ strlcpy(property, value, sizeof(property));
1063
+ SetImageArtifact(image, property, value);
979
1064
  }
980
1065
  }
981
1066
  }
982
- #endif
983
1067
 
984
1068
 
985
1069
  /**
@@ -996,16 +1080,19 @@ void rm_sync_image_options(Image *image, Info *info)
996
1080
  MagickStatusType flags;
997
1081
  GeometryInfo geometry_info;
998
1082
  const char *option;
1083
+ #if defined(IMAGEMAGICK_7)
1084
+ ExceptionInfo *exception;
1085
+ #endif
999
1086
 
1000
1087
  // The option strings will be set only when their attribute values were
1001
1088
  // set in the optional argument block.
1002
- option = GetImageOption(info,"background");
1089
+ option = GetImageOption(info, "background");
1003
1090
  if (option)
1004
1091
  {
1005
1092
  image->background_color = info->background_color;
1006
1093
  }
1007
1094
 
1008
- option = GetImageOption(info,"bordercolor");
1095
+ option = GetImageOption(info, "bordercolor");
1009
1096
  if (option)
1010
1097
  {
1011
1098
  image->border_color = info->border_color;
@@ -1013,7 +1100,16 @@ void rm_sync_image_options(Image *image, Info *info)
1013
1100
 
1014
1101
  if (info->colorspace != UndefinedColorspace)
1015
1102
  {
1016
- image->colorspace = info->colorspace;
1103
+ #if defined(IMAGEMAGICK_7)
1104
+ exception = AcquireExceptionInfo();
1105
+ SetImageColorspace(image, info->colorspace, exception);
1106
+ // We should not throw an exception in this method because we will
1107
+ // leak memory in the place where this method is called. And that is
1108
+ // why the exception is being ignored here.
1109
+ DestroyExceptionInfo(exception);
1110
+ #else
1111
+ SetImageColorspace(image, info->colorspace);
1112
+ #endif
1017
1113
  }
1018
1114
 
1019
1115
  if (info->compression != UndefinedCompression)
@@ -1030,11 +1126,20 @@ void rm_sync_image_options(Image *image, Info *info)
1030
1126
  if (info->density)
1031
1127
  {
1032
1128
  flags = ParseGeometry(info->density, &geometry_info);
1129
+ #if defined(IMAGEMAGICK_7)
1130
+ image->resolution.x = geometry_info.rho;
1131
+ image->resolution.y = geometry_info.sigma;
1132
+ #else
1033
1133
  image->x_resolution = geometry_info.rho;
1034
1134
  image->y_resolution = geometry_info.sigma;
1135
+ #endif
1035
1136
  if ((flags & SigmaValue) == 0)
1036
1137
  {
1138
+ #if defined(IMAGEMAGICK_7)
1139
+ image->resolution.y = image->resolution.x;
1140
+ #else
1037
1141
  image->y_resolution = image->x_resolution;
1142
+ #endif
1038
1143
  }
1039
1144
  }
1040
1145
 
@@ -1070,7 +1175,7 @@ void rm_sync_image_options(Image *image, Info *info)
1070
1175
  image->interlace = info->interlace;
1071
1176
  }
1072
1177
 
1073
- option = GetImageOption(info,"mattecolor");
1178
+ option = GetImageOption(info, "mattecolor");
1074
1179
  if (option)
1075
1180
  {
1076
1181
  image->matte_color = info->matte_color;
@@ -1083,7 +1188,7 @@ void rm_sync_image_options(Image *image, Info *info)
1083
1188
 
1084
1189
  if (info->page)
1085
1190
  {
1086
- (void)ParseAbsoluteGeometry(info->page, &image->page);
1191
+ ParseAbsoluteGeometry(info->page, &image->page);
1087
1192
  }
1088
1193
 
1089
1194
  if (info->quality != 0UL)
@@ -1100,7 +1205,7 @@ void rm_sync_image_options(Image *image, Info *info)
1100
1205
  option = GetImageOption(info, "tile-offset");
1101
1206
  if (option)
1102
1207
  {
1103
- (void)ParseAbsoluteGeometry(option, &image->tile_offset);
1208
+ ParseAbsoluteGeometry(option, &image->tile_offset);
1104
1209
  }
1105
1210
 
1106
1211
  option = GetImageOption(info, "transparent");
@@ -1109,12 +1214,10 @@ void rm_sync_image_options(Image *image, Info *info)
1109
1214
  image->transparent_color = info->transparent_color;
1110
1215
  }
1111
1216
 
1112
- #if defined(HAVE_ST_TYPE)
1113
1217
  if (info->type != UndefinedType)
1114
1218
  {
1115
1219
  image->type = info->type;
1116
1220
  }
1117
- #endif
1118
1221
 
1119
1222
  if (info->units != UndefinedResolution)
1120
1223
  {
@@ -1126,8 +1229,13 @@ void rm_sync_image_options(Image *image, Info *info)
1126
1229
  {
1127
1230
  if (info->units == PixelsPerCentimeterResolution)
1128
1231
  {
1232
+ #if defined(IMAGEMAGICK_7)
1233
+ image->resolution.x /= 2.54;
1234
+ image->resolution.y /= 2.54;
1235
+ #else
1129
1236
  image->x_resolution /= 2.54;
1130
1237
  image->y_resolution /= 2.54;
1238
+ #endif
1131
1239
  }
1132
1240
  break;
1133
1241
  }
@@ -1135,8 +1243,13 @@ void rm_sync_image_options(Image *image, Info *info)
1135
1243
  {
1136
1244
  if (info->units == PixelsPerInchResolution)
1137
1245
  {
1246
+ #if defined(IMAGEMAGICK_7)
1247
+ image->resolution.x *= 2.54;
1248
+ image->resolution.y *= 2.54;
1249
+ #else
1138
1250
  image->x_resolution *= 2.54;
1139
1251
  image->y_resolution *= 2.54;
1252
+ #endif
1140
1253
  }
1141
1254
  break;
1142
1255
  }
@@ -1148,16 +1261,14 @@ void rm_sync_image_options(Image *image, Info *info)
1148
1261
  image->units = info->units;
1149
1262
  }
1150
1263
 
1151
- #if defined(HAVE_SETIMAGEARTIFACT)
1152
1264
  copy_options(image, info);
1153
- #endif
1154
1265
  }
1155
1266
 
1156
1267
 
1157
1268
  /**
1158
1269
  * Replicate old (ImageMagick < 6.3.2) EXIF:* functionality using
1159
1270
  * GetImageProperty by returning the exif entries as a single string, separated
1160
- * by \n's. Do this so that RMagick.rb works no matter which version of
1271
+ * by \n's. Do this so that RMagick works no matter which version of
1161
1272
  * ImageMagick is in use.
1162
1273
  *
1163
1274
  * No Ruby usage (internal function)
@@ -1173,8 +1284,16 @@ rm_exif_by_entry(Image *image)
1173
1284
  char *str;
1174
1285
  size_t len = 0, property_l, value_l;
1175
1286
  VALUE v;
1287
+ #if defined(IMAGEMAGICK_7)
1288
+ ExceptionInfo *exception;
1289
+
1290
+ exception = AcquireExceptionInfo();
1291
+ GetImageProperty(image, "exif:*", exception);
1292
+ CHECK_EXCEPTION();
1293
+ #else
1294
+ GetImageProperty(image, "exif:*");
1295
+ #endif
1176
1296
 
1177
- (void) GetImageProperty(image, "exif:*");
1178
1297
  ResetImagePropertyIterator(image);
1179
1298
  property = GetNextImageProperty(image);
1180
1299
 
@@ -1182,7 +1301,7 @@ rm_exif_by_entry(Image *image)
1182
1301
  while (property)
1183
1302
  {
1184
1303
  // ignore properties that don't start with "exif:"
1185
- property_l = strlen(property);
1304
+ property_l = rm_strnlen_s(property, MaxTextExtent);
1186
1305
  if (property_l > 5 && rm_strncasecmp(property, "exif:", 5) == 0)
1187
1306
  {
1188
1307
  if (len > 0)
@@ -1190,11 +1309,16 @@ rm_exif_by_entry(Image *image)
1190
1309
  len += 1; // there will be a \n between property=value entries
1191
1310
  }
1192
1311
  len += property_l - 5;
1193
- value = GetImageProperty(image,property);
1312
+ #if defined(IMAGEMAGICK_7)
1313
+ value = GetImageProperty(image, property, exception);
1314
+ CHECK_EXCEPTION();
1315
+ #else
1316
+ value = GetImageProperty(image, property);
1317
+ #endif
1194
1318
  if (value)
1195
1319
  {
1196
1320
  // add 1 for the = between property and value
1197
- len += 1 + strlen(value);
1321
+ len += 1 + rm_strnlen_s(value, MaxTextExtent);
1198
1322
  }
1199
1323
  }
1200
1324
  property = GetNextImageProperty(image);
@@ -1202,8 +1326,12 @@ rm_exif_by_entry(Image *image)
1202
1326
 
1203
1327
  if (len == 0)
1204
1328
  {
1329
+ #if defined(IMAGEMAGICK_7)
1330
+ DestroyExceptionInfo(exception);
1331
+ #endif
1205
1332
  return Qnil;
1206
1333
  }
1334
+
1207
1335
  str = xmalloc(len);
1208
1336
  len = 0;
1209
1337
 
@@ -1213,7 +1341,7 @@ rm_exif_by_entry(Image *image)
1213
1341
 
1214
1342
  while (property)
1215
1343
  {
1216
- property_l = strlen(property);
1344
+ property_l = rm_strnlen_s(property, MaxTextExtent);
1217
1345
  if (property_l > 5 && rm_strncasecmp(property, "exif:", 5) == 0)
1218
1346
  {
1219
1347
  if (len > 0)
@@ -1222,10 +1350,19 @@ rm_exif_by_entry(Image *image)
1222
1350
  }
1223
1351
  memcpy(str+len, property+5, property_l-5);
1224
1352
  len += property_l - 5;
1225
- value = GetImageProperty(image,property);
1353
+ #if defined(IMAGEMAGICK_7)
1354
+ value = GetImageProperty(image, property, exception);
1355
+ if (rm_should_raise_exception(exception, RetainExceptionRetention))
1356
+ {
1357
+ xfree(str);
1358
+ rm_raise_exception(exception);
1359
+ }
1360
+ #else
1361
+ value = GetImageProperty(image, property);
1362
+ #endif
1226
1363
  if (value)
1227
1364
  {
1228
- value_l = strlen(value);
1365
+ value_l = rm_strnlen_s(value, MaxTextExtent);
1229
1366
  str[len++] = '=';
1230
1367
  memcpy(str+len, value, value_l);
1231
1368
  len += value_l;
@@ -1234,6 +1371,10 @@ rm_exif_by_entry(Image *image)
1234
1371
  property = GetNextImageProperty(image);
1235
1372
  }
1236
1373
 
1374
+ #if defined(IMAGEMAGICK_7)
1375
+ DestroyExceptionInfo(exception);
1376
+ #endif
1377
+
1237
1378
  v = rb_str_new(str, len);
1238
1379
  xfree(str);
1239
1380
 
@@ -1246,7 +1387,7 @@ rm_exif_by_entry(Image *image)
1246
1387
  /**
1247
1388
  * Replicate old (ImageMagick < 6.3.2) EXIF:! functionality using
1248
1389
  * GetImageProperty by returning the exif entries as a single string, separated
1249
- * by \n's. Do this so that RMagick.rb works no matter which version of
1390
+ * by \n's. Do this so that RMagick works no matter which version of
1250
1391
  * ImageMagick is in use.
1251
1392
  *
1252
1393
  * No Ruby usage (internal function)
@@ -1262,8 +1403,15 @@ rm_exif_by_number(Image *image)
1262
1403
  char *str;
1263
1404
  size_t len = 0, property_l, value_l;
1264
1405
  VALUE v;
1406
+ #if defined(IMAGEMAGICK_7)
1407
+ ExceptionInfo *exception;
1265
1408
 
1266
- (void) GetImageProperty(image, "exif:!");
1409
+ exception = AcquireExceptionInfo();
1410
+ GetImageProperty(image, "exif:!", exception);
1411
+ CHECK_EXCEPTION();
1412
+ #else
1413
+ GetImageProperty(image, "exif:!");
1414
+ #endif
1267
1415
  ResetImagePropertyIterator(image);
1268
1416
  property = GetNextImageProperty(image);
1269
1417
 
@@ -1271,7 +1419,7 @@ rm_exif_by_number(Image *image)
1271
1419
  while (property)
1272
1420
  {
1273
1421
  // ignore properties that don't start with "#"
1274
- property_l = strlen(property);
1422
+ property_l = rm_strnlen_s(property, MaxTextExtent);
1275
1423
  if (property_l > 1 && property[0] == '#')
1276
1424
  {
1277
1425
  if (len > 0)
@@ -1279,11 +1427,16 @@ rm_exif_by_number(Image *image)
1279
1427
  len += 1; // there will be a \n between property=value entries
1280
1428
  }
1281
1429
  len += property_l;
1282
- value = GetImageProperty(image,property);
1430
+ #if defined(IMAGEMAGICK_7)
1431
+ value = GetImageProperty(image, property, exception);
1432
+ CHECK_EXCEPTION();
1433
+ #else
1434
+ value = GetImageProperty(image, property);
1435
+ #endif
1283
1436
  if (value)
1284
1437
  {
1285
1438
  // add 1 for the = between property and value
1286
- len += 1 + strlen(value);
1439
+ len += 1 + rm_strnlen_s(value, MaxTextExtent);
1287
1440
  }
1288
1441
  }
1289
1442
  property = GetNextImageProperty(image);
@@ -1291,8 +1444,12 @@ rm_exif_by_number(Image *image)
1291
1444
 
1292
1445
  if (len == 0)
1293
1446
  {
1447
+ #if defined(IMAGEMAGICK_7)
1448
+ DestroyExceptionInfo(exception);
1449
+ #endif
1294
1450
  return Qnil;
1295
1451
  }
1452
+
1296
1453
  str = xmalloc(len);
1297
1454
  len = 0;
1298
1455
 
@@ -1302,7 +1459,7 @@ rm_exif_by_number(Image *image)
1302
1459
 
1303
1460
  while (property)
1304
1461
  {
1305
- property_l = strlen(property);
1462
+ property_l = rm_strnlen_s(property, MaxTextExtent);
1306
1463
  if (property_l > 1 && property[0] == '#')
1307
1464
  {
1308
1465
  if (len > 0)
@@ -1311,10 +1468,19 @@ rm_exif_by_number(Image *image)
1311
1468
  }
1312
1469
  memcpy(str+len, property, property_l);
1313
1470
  len += property_l;
1314
- value = GetImageProperty(image,property);
1471
+ #if defined(IMAGEMAGICK_7)
1472
+ value = GetImageProperty(image, property, exception);
1473
+ if (rm_should_raise_exception(exception, RetainExceptionRetention))
1474
+ {
1475
+ xfree(str);
1476
+ rm_raise_exception(exception);
1477
+ }
1478
+ #else
1479
+ value = GetImageProperty(image, property);
1480
+ #endif
1315
1481
  if (value)
1316
1482
  {
1317
- value_l = strlen(value);
1483
+ value_l = rm_strnlen_s(value, MaxTextExtent);
1318
1484
  str[len++] = '=';
1319
1485
  memcpy(str+len, value, value_l);
1320
1486
  len += value_l;
@@ -1323,6 +1489,10 @@ rm_exif_by_number(Image *image)
1323
1489
  property = GetNextImageProperty(image);
1324
1490
  }
1325
1491
 
1492
+ #if defined(IMAGEMAGICK_7)
1493
+ DestroyExceptionInfo(exception);
1494
+ #endif
1495
+
1326
1496
  v = rb_str_new(str, len);
1327
1497
  xfree(str);
1328
1498
 
@@ -1332,66 +1502,6 @@ rm_exif_by_number(Image *image)
1332
1502
  }
1333
1503
 
1334
1504
 
1335
- /**
1336
- * Get the values from a Geometry object and return them in C variables.
1337
- *
1338
- * No Ruby usage (internal function)
1339
- *
1340
- * Notes:
1341
- * - No return value: modifies x, y, width, height, and flag
1342
- *
1343
- * @param geom the Geometry object
1344
- * @param x pointer to the x position of the start of the rectangle
1345
- * @param y pointer to the y position of the start of the rectangle
1346
- * @param width pointer to the width of the rectangle
1347
- * @param height pointer to the height of the rectangle
1348
- * @param flag pointer to the Geometry's flag
1349
- */
1350
- void
1351
- rm_get_geometry(
1352
- VALUE geom,
1353
- long *x,
1354
- long *y,
1355
- unsigned long *width,
1356
- unsigned long *height,
1357
- int *flag)
1358
- {
1359
- VALUE v;
1360
-
1361
- v = rb_funcall(geom, rm_ID_x, 0);
1362
- *x = NUM2LONG(v);
1363
- v = rb_funcall(geom, rm_ID_y, 0);
1364
- *y = NUM2LONG(v);
1365
- v = rb_funcall(geom, rm_ID_width, 0);
1366
- *width = NUM2ULONG(v);
1367
- v = rb_funcall(geom, rm_ID_height, 0);
1368
- *height = NUM2ULONG(v);
1369
-
1370
- // Getting the flag field is a bit more difficult since it's
1371
- // supposed to be an instance of the GeometryValue Enum class. We
1372
- // may not know the VALUE for the GeometryValue class, and we
1373
- // need to check that the flag field is an instance of that class.
1374
- if (flag)
1375
- {
1376
- MagickEnum *magick_enum;
1377
-
1378
- v = rb_funcall(geom, rm_ID_flag, 0);
1379
- if (!Class_GeometryValue)
1380
- {
1381
- Class_GeometryValue = rb_const_get(Module_Magick, rm_ID_GeometryValue);
1382
- }
1383
- if (CLASS_OF(v) != Class_GeometryValue)
1384
- {
1385
- rb_raise(rb_eTypeError, "wrong enumeration type - expected %s, got %s"
1386
- , rb_class2name(Class_GeometryValue),rb_class2name(CLASS_OF(v)));
1387
- }
1388
- Data_Get_Struct(v, MagickEnum, magick_enum);
1389
- *flag = magick_enum->val;
1390
- }
1391
-
1392
- }
1393
-
1394
-
1395
1505
  /**
1396
1506
  * Clone an image, handle errors.
1397
1507
  *
@@ -1411,66 +1521,19 @@ rm_clone_image(Image *image)
1411
1521
  ExceptionInfo *exception;
1412
1522
 
1413
1523
  exception = AcquireExceptionInfo();
1414
- clone = CloneImage(image, 0, 0, MagickTrue, exception);
1524
+ GVL_STRUCT_TYPE(CloneImage) args = { image, 0, 0, MagickTrue, exception };
1525
+ clone = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CloneImage), &args);
1415
1526
  if (!clone)
1416
1527
  {
1417
1528
  rb_raise(rb_eNoMemError, "not enough memory to continue");
1418
1529
  }
1419
1530
  rm_check_exception(exception, clone, DestroyOnError);
1420
- (void) DestroyExceptionInfo(exception);
1531
+ DestroyExceptionInfo(exception);
1421
1532
 
1422
1533
  return clone;
1423
1534
  }
1424
1535
 
1425
1536
 
1426
- /**
1427
- * SetImage(Info)ProgressMonitor exit.
1428
- *
1429
- * No Ruby usage (internal function)
1430
- *
1431
- * Notes:
1432
- * - ImageMagick's "tag" argument is unused. We pass along the method name
1433
- * instead.
1434
- *
1435
- * @param tag ImageMagick argument (unused)
1436
- * @param of the offset type
1437
- * @param sp the size type
1438
- * @param client_data pointer to the progress method to call
1439
- * @return true if calling client_data returns a non-nil value, otherwise false
1440
- */
1441
- MagickBooleanType
1442
- rm_progress_monitor(
1443
- const char *tag,
1444
- const MagickOffsetType of,
1445
- const MagickSizeType sp,
1446
- void *client_data)
1447
- {
1448
- VALUE rval;
1449
- VALUE method, offset, span;
1450
-
1451
- tag = tag; // defeat gcc message
1452
-
1453
- #if defined(HAVE_LONG_LONG) // defined in Ruby's defines.h
1454
- offset = rb_ll2inum(of);
1455
- span = rb_ull2inum(sp);
1456
- #else
1457
- offset = rb_int2big((long)of);
1458
- span = rb_uint2big((unsigned long)sp);
1459
- #endif
1460
-
1461
- method = rb_str_new2(rb_id2name(THIS_FUNC()));
1462
-
1463
- rval = rb_funcall((VALUE)client_data, rm_ID_call, 3, method, offset, span);
1464
-
1465
- RB_GC_GUARD(rval);
1466
- RB_GC_GUARD(method);
1467
- RB_GC_GUARD(offset);
1468
- RB_GC_GUARD(span);
1469
-
1470
- return RTEST(rval) ? MagickTrue : MagickFalse;
1471
- }
1472
-
1473
-
1474
1537
  /**
1475
1538
  * Remove the ImageMagick links between images in an scene sequence.
1476
1539
  *
@@ -1491,11 +1554,12 @@ rm_split(Image *image)
1491
1554
  }
1492
1555
  while (image)
1493
1556
  {
1494
- (void) RemoveFirstImageFromList(&image);
1557
+ RemoveFirstImageFromList(&image);
1495
1558
  }
1496
1559
  }
1497
1560
 
1498
1561
 
1562
+ #if defined(IMAGEMAGICK_6)
1499
1563
  /**
1500
1564
  * If an ExceptionInfo struct in a list of images indicates a warning, issue a
1501
1565
  * warning message. If an ExceptionInfo struct indicates an error, raise an
@@ -1543,7 +1607,34 @@ rm_check_image_exception(Image *imglist, ErrorRetention retention)
1543
1607
  rm_check_exception(exception, imglist, retention);
1544
1608
  }
1545
1609
 
1546
- (void) DestroyExceptionInfo(exception);
1610
+ DestroyExceptionInfo(exception);
1611
+ }
1612
+ #endif
1613
+
1614
+
1615
+ #define ERROR_MSG_SIZE 1024
1616
+ /**
1617
+ * Formats the exception into the message buffer
1618
+ *
1619
+ * No Ruby usage (internal function)
1620
+ *
1621
+ * @param severity information about the severity of the error
1622
+ * @param reason the reason for the error
1623
+ * @param description description of the error
1624
+ * @param msg the buffer where the exception message should be formated in
1625
+ */
1626
+ static void
1627
+ format_exception(const ExceptionType severity, const char *reason, const char *description, char *msg)
1628
+ {
1629
+ int len;
1630
+ memset(msg, 0, ERROR_MSG_SIZE);
1631
+
1632
+ len = snprintf(msg, ERROR_MSG_SIZE, "%s%s%s",
1633
+ GetLocaleExceptionMessage(severity, reason),
1634
+ description ? ": " : "",
1635
+ description ? GetLocaleExceptionMessage(severity, description) : "");
1636
+
1637
+ msg[len] = '\0';
1547
1638
  }
1548
1639
 
1549
1640
 
@@ -1582,11 +1673,10 @@ rm_check_exception(ExceptionInfo *exception, Image *imglist, ErrorRetention rete
1582
1673
  void
1583
1674
  rm_warning_handler(const ExceptionType severity, const char *reason, const char *description)
1584
1675
  {
1585
- ExceptionType dummy;
1586
-
1587
- rb_warning("RMagick: %s: `%s'", reason, description);
1588
- dummy = severity;
1589
- dummy = dummy;
1676
+ rb_warning("RMagick: %s%s%s",
1677
+ GetLocaleExceptionMessage(severity, reason),
1678
+ description ? ": " : "",
1679
+ description ? GetLocaleExceptionMessage(severity, description) : "");
1590
1680
  }
1591
1681
 
1592
1682
 
@@ -1595,28 +1685,18 @@ rm_warning_handler(const ExceptionType severity, const char *reason, const char
1595
1685
  *
1596
1686
  * No Ruby usage (internal function)
1597
1687
  *
1598
- * @param severity information about the severity of the error (ignored)
1688
+ * @param severity information about the severity of the error
1599
1689
  * @param reason the reason for the error
1600
1690
  * @param description description of the error
1601
1691
  */
1602
1692
  void
1603
1693
  rm_error_handler(const ExceptionType severity, const char *reason, const char *description)
1604
1694
  {
1605
- char msg[500];
1606
- int len;
1607
- ExceptionType dummy;
1695
+ char msg[ERROR_MSG_SIZE];
1608
1696
 
1609
- memset(msg, 0, sizeof(msg));
1610
- #if defined(HAVE_SNPRINTF)
1611
- len = snprintf(msg, sizeof(msg), "%s: `%s'", reason, description);
1612
- #else
1613
- len = sprintf(msg, "%.250s: `%.240s'", reason, description);
1614
- #endif
1615
- msg[len] = '\0';
1697
+ format_exception(severity, reason, description, msg);
1616
1698
 
1617
- rm_magick_error(msg, NULL);
1618
- dummy = severity;
1619
- dummy = dummy;
1699
+ rm_magick_error(msg);
1620
1700
  }
1621
1701
 
1622
1702
 
@@ -1627,14 +1707,16 @@ rm_error_handler(const ExceptionType severity, const char *reason, const char *d
1627
1707
  *
1628
1708
  * @param severity information about the severity of the error
1629
1709
  * @param reason the reason for the error
1630
- * @param description description of the error (ignored)
1710
+ * @param description description of the error
1631
1711
  * @throw FatalImageMagickError
1632
1712
  */
1633
1713
  void
1634
1714
  rm_fatal_error_handler(const ExceptionType severity, const char *reason, const char *description)
1635
1715
  {
1636
- rb_raise(Class_FatalImageMagickError, "%s", GetLocaleExceptionMessage(severity, reason));
1637
- description = description;
1716
+ rb_raise(Class_FatalImageMagickError, "%s%s%s",
1717
+ GetLocaleExceptionMessage(severity, reason),
1718
+ description ? ": " : "",
1719
+ description ? GetLocaleExceptionMessage(severity, description) : "");
1638
1720
  }
1639
1721
 
1640
1722
 
@@ -1653,27 +1735,12 @@ rm_fatal_error_handler(const ExceptionType severity, const char *reason, const c
1653
1735
  static void
1654
1736
  handle_exception(ExceptionInfo *exception, Image *imglist, ErrorRetention retention)
1655
1737
  {
1656
-
1657
- char reason[500];
1658
- char desc[500];
1659
- char msg[sizeof(reason)+sizeof(desc)+20];
1660
-
1661
- memset(msg, 0, sizeof(msg));
1662
-
1738
+ char msg[ERROR_MSG_SIZE];
1663
1739
 
1664
1740
  // Handle simple warning
1665
1741
  if (exception->severity < ErrorException)
1666
1742
  {
1667
- #if defined(HAVE_SNPRINTF)
1668
- snprintf(msg, sizeof(msg)-1, "RMagick: %s%s%s",
1669
- #else
1670
- sprintf(msg, "RMagick: %.500s%s%.500s",
1671
- #endif
1672
- GetLocaleExceptionMessage(exception->severity, exception->reason),
1673
- exception->description ? ": " : "",
1674
- exception->description ? GetLocaleExceptionMessage(exception->severity, exception->description) : "");
1675
- msg[sizeof(msg)-1] = '\0';
1676
- rb_warning("%s", msg);
1743
+ rm_warning_handler(exception->severity, exception->reason, exception->description);
1677
1744
 
1678
1745
  // Caller deletes ExceptionInfo...
1679
1746
 
@@ -1689,7 +1756,7 @@ handle_exception(ExceptionInfo *exception, Image *imglist, ErrorRetention retent
1689
1756
  {
1690
1757
  if (retention == DestroyOnError)
1691
1758
  {
1692
- (void) DestroyImageList(imglist);
1759
+ DestroyImageList(imglist);
1693
1760
  imglist = NULL;
1694
1761
  }
1695
1762
  else
@@ -1698,40 +1765,11 @@ handle_exception(ExceptionInfo *exception, Image *imglist, ErrorRetention retent
1698
1765
  }
1699
1766
  }
1700
1767
 
1768
+ format_exception(exception->severity, exception->reason, exception->description, msg);
1701
1769
 
1702
- // Clone the ExceptionInfo with all arguments on the stack.
1703
- memset(reason, 0, sizeof(reason));
1704
- memset(desc, 0, sizeof(desc));
1705
-
1706
- if (exception->reason)
1707
- {
1708
- strncpy(reason, exception->reason, sizeof(reason)-1);
1709
- reason[sizeof(reason)-1] = '\0';
1710
- }
1711
- if (exception->description)
1712
- {
1713
- strncpy(desc, exception->description, sizeof(desc)-1);
1714
- desc[sizeof(desc)-1] = '\0';
1715
- }
1716
-
1717
-
1718
- #if defined(HAVE_SNPRINTF)
1719
- snprintf(msg, sizeof(msg)-1, "%s%s%s",
1720
- GetLocaleExceptionMessage(exception->severity, reason),
1721
- desc[0] ? ": " : "",
1722
- desc[0] ? GetLocaleExceptionMessage(exception->severity, desc) : "");
1723
- #else
1724
- sprintf(msg, "%.*s%s%.*s",
1725
- sizeof(reason)-1, GetLocaleExceptionMessage(exception->severity, reason),
1726
- desc[0] ? ": " : "",
1727
- sizeof(desc)-1, desc[0] ? GetLocaleExceptionMessage(exception->severity, desc) : "");
1728
- #endif
1729
-
1730
- msg[sizeof(msg)-1] = '\0';
1731
-
1732
- (void) DestroyExceptionInfo(exception);
1733
- rm_magick_error(msg, NULL);
1770
+ DestroyExceptionInfo(exception);
1734
1771
 
1772
+ rm_magick_error(msg);
1735
1773
  }
1736
1774
 
1737
1775
 
@@ -1752,3 +1790,52 @@ rm_ensure_result(Image *image)
1752
1790
  }
1753
1791
  }
1754
1792
 
1793
+
1794
+ /**
1795
+ * Checks if an error should be raised for the exception.
1796
+ *
1797
+ * No Ruby usage (internal function)
1798
+ *
1799
+ * @param exception information about the exception
1800
+ * @param retention retention strategy for the exception in case there was no error
1801
+ */
1802
+ MagickBooleanType
1803
+ rm_should_raise_exception(ExceptionInfo *exception, const ExceptionRetention retention)
1804
+ {
1805
+ if (exception->severity < ErrorException)
1806
+ {
1807
+ if (exception->severity != UndefinedException)
1808
+ {
1809
+ rm_warning_handler(exception->severity, exception->reason, exception->description);
1810
+ }
1811
+
1812
+ if (retention == DestroyExceptionRetention)
1813
+ {
1814
+ DestroyExceptionInfo(exception);
1815
+ }
1816
+
1817
+ return MagickFalse;
1818
+ }
1819
+
1820
+ return MagickTrue;
1821
+ }
1822
+
1823
+
1824
+ /**
1825
+ * Raises an exception.
1826
+ *
1827
+ * No Ruby usage (internal function)
1828
+ *
1829
+ * @param exception information about the exception
1830
+ */
1831
+ void
1832
+ rm_raise_exception(ExceptionInfo *exception)
1833
+ {
1834
+ char msg[ERROR_MSG_SIZE];
1835
+
1836
+ format_exception(exception->severity, exception->reason, exception->description, msg);
1837
+
1838
+ DestroyExceptionInfo(exception);
1839
+
1840
+ rm_magick_error(msg);
1841
+ }