rdp-rmagick 0.0.0

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