rdp-rmagick 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }