rmagick 1.15.17 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rmagick might be problematic. Click here for more details.

Files changed (108) hide show
  1. data/ChangeLog +78 -25
  2. data/README.html +117 -188
  3. data/README.txt +116 -181
  4. data/build_tarball.rake +205 -0
  5. data/doc/comtasks.html +2 -2
  6. data/doc/constants.html +118 -44
  7. data/doc/draw.html +57 -99
  8. data/doc/ex/adaptive_threshold.rb +1 -10
  9. data/doc/ex/add_noise.rb +4 -5
  10. data/doc/ex/axes.rb +1 -1
  11. data/doc/ex/bilevel_channel.rb +2 -13
  12. data/doc/ex/bounding_box.rb +3 -4
  13. data/doc/ex/channel.rb +6 -7
  14. data/doc/ex/clip_path.rb +11 -5
  15. data/doc/ex/color_histogram.rb +8 -20
  16. data/doc/ex/composite_layers.rb +53 -0
  17. data/doc/ex/fill_pattern.rb +26 -0
  18. data/doc/ex/get_multiline_type_metrics.rb +26 -37
  19. data/doc/ex/get_type_metrics.rb +25 -25
  20. data/doc/ex/images/notimplemented.gif +0 -0
  21. data/doc/ex/level.rb +1 -1
  22. data/doc/ex/matte_floodfill.rb +5 -6
  23. data/doc/ex/matte_replace.rb +5 -6
  24. data/doc/ex/negate_channel.rb +0 -10
  25. data/doc/ex/opacity.rb +3 -5
  26. data/doc/ex/polaroid.rb +4 -1
  27. data/doc/ex/posterize.rb +1 -12
  28. data/doc/ex/preview.rb +1 -8
  29. data/doc/ex/radial_blur.rb +1 -11
  30. data/doc/ex/raise.rb +1 -4
  31. data/doc/ex/random_threshold_channel.rb +4 -9
  32. data/doc/ex/sepiatone.rb +2 -9
  33. data/doc/ex/shadow.rb +12 -18
  34. data/doc/ex/sketch.rb +2 -9
  35. data/doc/ex/smile.rb +7 -7
  36. data/doc/ex/splice.rb +3 -10
  37. data/doc/ex/stegano.rb +5 -0
  38. data/doc/ex/threshold.rb +2 -2
  39. data/doc/ex/transpose.rb +1 -8
  40. data/doc/ex/transverse.rb +1 -8
  41. data/doc/ex/trim.rb +1 -2
  42. data/doc/ex/viewex.rb +4 -5
  43. data/doc/ex/vignette.rb +1 -8
  44. data/doc/ex/watermark.rb +1 -0
  45. data/doc/ex/wet_floor.rb +8 -14
  46. data/doc/ilist.html +301 -110
  47. data/doc/image1.html +362 -258
  48. data/doc/image2.html +429 -286
  49. data/doc/image3.html +418 -192
  50. data/doc/imageattrs.html +100 -39
  51. data/doc/imusage.html +26 -21
  52. data/doc/index.html +52 -93
  53. data/doc/info.html +160 -64
  54. data/doc/magick.html +37 -71
  55. data/doc/optequiv.html +155 -61
  56. data/doc/rvg.html +3 -3
  57. data/doc/rvgclip.html +2 -2
  58. data/doc/rvggroup.html +2 -2
  59. data/doc/rvgimage.html +3 -3
  60. data/doc/rvgpattern.html +3 -3
  61. data/doc/rvgshape.html +2 -2
  62. data/doc/rvgstyle.html +2 -2
  63. data/doc/rvgtext.html +2 -2
  64. data/doc/rvgtspan.html +4 -4
  65. data/doc/rvgtut.html +4 -4
  66. data/doc/rvguse.html +3 -3
  67. data/doc/rvgxform.html +2 -2
  68. data/doc/struct.html +26 -29
  69. data/doc/usage.html +99 -48
  70. data/examples/crop_with_gravity.rb +46 -0
  71. data/examples/demo.rb +2 -2
  72. data/examples/histogram.rb +11 -11
  73. data/examples/identify.rb +45 -45
  74. data/examples/spinner.rb +3 -2
  75. data/ext/RMagick/MANIFEST +7 -8
  76. data/ext/RMagick/extconf.rb +242 -0
  77. data/ext/RMagick/rmagick.h +136 -222
  78. data/ext/RMagick/rmdraw.c +226 -229
  79. data/ext/RMagick/rmfill.c +69 -118
  80. data/ext/RMagick/rmilist.c +234 -94
  81. data/ext/RMagick/rmimage.c +1719 -2564
  82. data/ext/RMagick/rminfo.c +433 -619
  83. data/ext/RMagick/rmmain.c +249 -487
  84. data/ext/RMagick/rmutil.c +344 -563
  85. data/lib/RMagick.rb +414 -358
  86. data/lib/rvg/clippath.rb +2 -2
  87. data/lib/rvg/container.rb +2 -2
  88. data/lib/rvg/describable.rb +2 -2
  89. data/lib/rvg/embellishable.rb +2 -2
  90. data/lib/rvg/misc.rb +3 -3
  91. data/lib/rvg/paint.rb +2 -7
  92. data/lib/rvg/pathdata.rb +2 -2
  93. data/lib/rvg/rvg.rb +2 -2
  94. data/lib/rvg/stretchable.rb +2 -14
  95. data/lib/rvg/stylable.rb +2 -2
  96. data/lib/rvg/text.rb +2 -2
  97. data/lib/rvg/transformable.rb +2 -2
  98. data/lib/rvg/units.rb +2 -2
  99. data/{metaconfig.in → metaconfig} +0 -1
  100. data/post-setup.rb +1 -1
  101. data/rmagick.gemspec +6 -9
  102. metadata +41 -49
  103. data/Makefile.in +0 -42
  104. data/configure +0 -12358
  105. data/configure.ac +0 -791
  106. data/ext/RMagick/extconf.rb.in +0 -25
  107. data/ext/RMagick/rmagick_config.h.in +0 -285
  108. data/gem_extconf.rb +0 -42
@@ -1,6 +1,6 @@
1
- /* $Id: rmfill.c,v 1.17.2.1.2.1 2008/02/24 23:25:40 rmagick Exp $ */
1
+ /* $Id: rmfill.c,v 1.25 2007/10/28 23:43:24 rmagick Exp $ */
2
2
  /*============================================================================\
3
- | Copyright (C) 2008 by Timothy P. Hunter
3
+ | Copyright (C) 2007 by Timothy P. Hunter
4
4
  | Name: rmfill.c
5
5
  | Author: Tim Hunter
6
6
  | Purpose: GradientFill, TextureFill class definitions for RMagick
@@ -31,41 +31,9 @@ static void free_Fill(void *fill)
31
31
  }
32
32
 
33
33
  /*
34
- Extern: GradientFill.new(x1, y1, x2, y2, start_color, stop_color)
34
+ Extern: GradientFill.allocate(x1, y1, x2, y2, start_color, stop_color)
35
35
  Purpose: Create new GradientFill object
36
36
  */
37
- #if !defined(HAVE_RB_DEFINE_ALLOC_FUNC)
38
- VALUE
39
- GradientFill_new(
40
- VALUE class,
41
- VALUE x1,
42
- VALUE y1,
43
- VALUE x2,
44
- VALUE y2,
45
- VALUE start_color,
46
- VALUE stop_color)
47
- {
48
- rm_GradientFill *fill;
49
- volatile VALUE new_fill;
50
- VALUE argv[6];
51
-
52
- argv[0] = x1;
53
- argv[1] = y1;
54
- argv[2] = x2;
55
- argv[3] = y2;
56
- argv[4] = start_color;
57
- argv[5] = stop_color;
58
-
59
- new_fill = Data_Make_Struct(class
60
- , rm_GradientFill
61
- , NULL
62
- , free_Fill
63
- , fill);
64
-
65
- rb_obj_call_init((VALUE)new_fill, 6, argv);
66
- return new_fill;
67
- }
68
- #else
69
37
  VALUE
70
38
  GradientFill_alloc(VALUE class)
71
39
  {
@@ -73,7 +41,7 @@ GradientFill_alloc(VALUE class)
73
41
 
74
42
  return Data_Make_Struct(class, rm_GradientFill, NULL, free_Fill, fill);
75
43
  }
76
- #endif
44
+
77
45
 
78
46
  /*
79
47
  Extern: GradientFill#initialize(start_color, stop_color)
@@ -81,13 +49,13 @@ GradientFill_alloc(VALUE class)
81
49
  */
82
50
  VALUE
83
51
  GradientFill_initialize(
84
- VALUE self,
85
- VALUE x1,
86
- VALUE y1,
87
- VALUE x2,
88
- VALUE y2,
89
- VALUE start_color,
90
- VALUE stop_color)
52
+ VALUE self,
53
+ VALUE x1,
54
+ VALUE y1,
55
+ VALUE x2,
56
+ VALUE y2,
57
+ VALUE start_color,
58
+ VALUE stop_color)
91
59
  {
92
60
  rm_GradientFill *fill;
93
61
 
@@ -109,21 +77,22 @@ GradientFill_initialize(
109
77
  */
110
78
  static void
111
79
  point_fill(
112
- Image *image,
113
- double x0,
114
- double y0,
115
- PixelPacket *start_color,
116
- PixelPacket *stop_color)
80
+ Image *image,
81
+ double x0,
82
+ double y0,
83
+ PixelPacket *start_color,
84
+ PixelPacket *stop_color)
117
85
  {
118
86
  double steps, distance;
119
87
  unsigned long x, y;
120
- double red_step, green_step, blue_step;
88
+ MagickRealType red_step, green_step, blue_step;
121
89
 
122
90
  steps = sqrt((double)((image->columns-x0)*(image->columns-x0)
123
- + (image->rows-y0)*(image->rows-y0)));
124
- red_step = ((double)(stop_color->red - start_color->red)) / steps;
125
- green_step = ((double)(stop_color->green - start_color->green)) / steps;
126
- blue_step = ((double)(stop_color->blue - start_color->blue)) / steps;
91
+ + (image->rows-y0)*(image->rows-y0)));
92
+
93
+ red_step = ((MagickRealType)stop_color->red - (MagickRealType)start_color->red) / steps;
94
+ green_step = ((MagickRealType)stop_color->green - (MagickRealType)start_color->green) / steps;
95
+ blue_step = ((MagickRealType)stop_color->blue - (MagickRealType)start_color->blue) / steps;
127
96
 
128
97
  for (y = 0; y < image->rows; y++)
129
98
  {
@@ -155,15 +124,15 @@ point_fill(
155
124
  */
156
125
  static void
157
126
  vertical_fill(
158
- Image *image,
159
- double x1,
160
- PixelPacket *start_color,
161
- PixelPacket *stop_color)
127
+ Image *image,
128
+ double x1,
129
+ PixelPacket *start_color,
130
+ PixelPacket *stop_color)
162
131
  {
163
132
  double steps;
164
133
  unsigned long x, y;
165
134
  volatile PixelPacket *master;
166
- double red_step, green_step, blue_step;
135
+ MagickRealType red_step, green_step, blue_step;
167
136
 
168
137
  // Keep in mind that x1 could be < 0 or > image->columns. If steps
169
138
  // is negative, swap the start and end colors and use the absolute
@@ -185,9 +154,9 @@ vertical_fill(
185
154
  steps -= x1;
186
155
  }
187
156
 
188
- red_step = (stop_color->red - start_color->red) / steps;
189
- green_step = (stop_color->green - start_color->green) / steps;
190
- blue_step = (stop_color->blue - start_color->blue) / steps;
157
+ red_step = ((MagickRealType)stop_color->red - (MagickRealType)start_color->red) / steps;
158
+ green_step = ((MagickRealType)stop_color->green - (MagickRealType)start_color->green) / steps;
159
+ blue_step = ((MagickRealType)stop_color->blue - (MagickRealType)start_color->blue) / steps;
191
160
 
192
161
  // All the rows are the same. Make a "master row" and simply copy
193
162
  // it to each actual row.
@@ -228,15 +197,15 @@ vertical_fill(
228
197
  */
229
198
  static void
230
199
  horizontal_fill(
231
- Image *image,
232
- double y1,
233
- PixelPacket *start_color,
234
- PixelPacket *stop_color)
200
+ Image *image,
201
+ double y1,
202
+ PixelPacket *start_color,
203
+ PixelPacket *stop_color)
235
204
  {
236
205
  double steps;
237
206
  unsigned long x, y;
238
207
  volatile PixelPacket *master;
239
- double red_step, green_step, blue_step;
208
+ MagickRealType red_step, green_step, blue_step;
240
209
 
241
210
  // Bear in mind that y1 could be < 0 or > image->rows. If steps is
242
211
  // negative, swap the start and end colors and use the absolute value.
@@ -256,9 +225,9 @@ horizontal_fill(
256
225
  steps -= y1;
257
226
  }
258
227
 
259
- red_step = (stop_color->red - start_color->red) / steps;
260
- green_step = (stop_color->green - start_color->green) / steps;
261
- blue_step = (stop_color->blue - start_color->blue) / steps;
228
+ red_step = ((MagickRealType)stop_color->red - (MagickRealType)start_color->red) / steps;
229
+ green_step = ((MagickRealType)stop_color->green - (MagickRealType)start_color->green) / steps;
230
+ blue_step = ((MagickRealType)stop_color->blue - (MagickRealType)start_color->blue) / steps;
262
231
 
263
232
  // All the columns are the same, so make a master column and copy it to
264
233
  // each of the "real" columns.
@@ -298,16 +267,16 @@ horizontal_fill(
298
267
  */
299
268
  static void
300
269
  v_diagonal_fill(
301
- Image *image,
302
- double x1,
303
- double y1,
304
- double x2,
305
- double y2,
306
- PixelPacket *start_color,
307
- PixelPacket *stop_color)
270
+ Image *image,
271
+ double x1,
272
+ double y1,
273
+ double x2,
274
+ double y2,
275
+ PixelPacket *start_color,
276
+ PixelPacket *stop_color)
308
277
  {
309
278
  unsigned long x, y;
310
- double red_step, green_step, blue_step;
279
+ MagickRealType red_step, green_step, blue_step;
311
280
  double m, b, steps = 0.0;
312
281
  double d1, d2;
313
282
 
@@ -343,9 +312,9 @@ v_diagonal_fill(
343
312
  steps = -steps;
344
313
  }
345
314
 
346
- red_step = (stop_color->red - start_color->red) / steps;
347
- green_step = (stop_color->green - start_color->green) / steps;
348
- blue_step = (stop_color->blue - start_color->blue) / steps;
315
+ red_step = ((MagickRealType)stop_color->red - (MagickRealType)start_color->red) / steps;
316
+ green_step = ((MagickRealType)stop_color->green - (MagickRealType)start_color->green) / steps;
317
+ blue_step = ((MagickRealType)stop_color->blue - (MagickRealType)start_color->blue) / steps;
349
318
 
350
319
  for (y = 0; y < image->rows; y++)
351
320
  {
@@ -377,17 +346,17 @@ v_diagonal_fill(
377
346
  */
378
347
  static void
379
348
  h_diagonal_fill(
380
- Image *image,
381
- double x1,
382
- double y1,
383
- double x2,
384
- double y2,
385
- PixelPacket *start_color,
386
- PixelPacket *stop_color)
349
+ Image *image,
350
+ double x1,
351
+ double y1,
352
+ double x2,
353
+ double y2,
354
+ PixelPacket *start_color,
355
+ PixelPacket *stop_color)
387
356
  {
388
357
  unsigned long x, y;
389
358
  double m, b, steps = 0.0;
390
- double red_step, green_step, blue_step;
359
+ MagickRealType red_step, green_step, blue_step;
391
360
  double d1, d2;
392
361
 
393
362
  // Compute the equation of the line: y=mx+b
@@ -424,9 +393,9 @@ h_diagonal_fill(
424
393
  steps = -steps;
425
394
  }
426
395
 
427
- red_step = (stop_color->red - start_color->red) / steps;
428
- green_step = (stop_color->green - start_color->green) / steps;
429
- blue_step = (stop_color->blue - start_color->blue) / steps;
396
+ red_step = ((MagickRealType)stop_color->red - (MagickRealType)start_color->red) / steps;
397
+ green_step = ((MagickRealType)stop_color->green - (MagickRealType)start_color->green) / steps;
398
+ blue_step = ((MagickRealType)stop_color->blue - (MagickRealType)start_color->blue) / steps;
430
399
 
431
400
  for (y = 0; y < image->rows; y++)
432
401
  {
@@ -466,7 +435,7 @@ GradientFill_fill(VALUE self, VALUE image_obj)
466
435
  double x1, y1, x2, y2; // points on the line
467
436
 
468
437
  Data_Get_Struct(self, rm_GradientFill, fill);
469
- Data_Get_Struct(image_obj, Image, image);
438
+ image = rm_check_destroyed(image_obj);
470
439
 
471
440
  x1 = fill->x1;
472
441
  y1 = fill->y1;
@@ -529,44 +498,26 @@ free_TextureFill(void *fill_obj)
529
498
  {
530
499
  rm_TextureFill *fill = (rm_TextureFill *)fill_obj;
531
500
 
501
+ // Do not trace destruction
532
502
  (void) DestroyImage(fill->texture);
533
503
  xfree(fill);
534
504
  }
535
505
 
536
506
  /*
537
- Extern: TextureFill.new(texture)
507
+ Extern: TextureFill.allocate(texture)
538
508
  Purpose: Create new TextureFill object
539
509
  Notes: the texture is an Image or Image *object
540
510
  */
541
- #if !defined(HAVE_RB_DEFINE_ALLOC_FUNC)
542
- VALUE
543
- TextureFill_new(VALUE class, VALUE texture)
544
- {
545
- rm_TextureFill *fill;
546
- VALUE argv[1];
547
- volatile VALUE new_fill;
548
-
549
- new_fill = Data_Make_Struct(class
550
- , rm_TextureFill
551
- , NULL
552
- , free_TextureFill
553
- , fill);
554
- argv[0] = texture;
555
- rb_obj_call_init((VALUE)new_fill, 1, argv);
556
- return new_fill;
557
- }
558
- #else
559
511
  VALUE
560
512
  TextureFill_alloc(VALUE class)
561
513
  {
562
514
  rm_TextureFill *fill;
563
515
  return Data_Make_Struct(class
564
- , rm_TextureFill
565
- , NULL
566
- , free_TextureFill
567
- , fill);
516
+ , rm_TextureFill
517
+ , NULL
518
+ , free_TextureFill
519
+ , fill);
568
520
  }
569
- #endif
570
521
 
571
522
  /*
572
523
  Extern: TextureFill#initialize
@@ -584,7 +535,7 @@ TextureFill_initialize(VALUE self, VALUE texture_arg)
584
535
  texture_image = ImageList_cur_image(texture_arg);
585
536
 
586
537
  // Bump the reference count on the texture image.
587
- Data_Get_Struct(texture_image, Image, texture);
538
+ texture = rm_check_destroyed(texture_image);
588
539
  (void) ReferenceImage(texture);
589
540
 
590
541
  fill->texture = texture;
@@ -601,7 +552,7 @@ TextureFill_fill(VALUE self, VALUE image_obj)
601
552
  rm_TextureFill *fill;
602
553
  Image *image;
603
554
 
604
- Data_Get_Struct(image_obj, Image, image);
555
+ image = rm_check_destroyed(image_obj);
605
556
  Data_Get_Struct(self, rm_TextureFill, fill);
606
557
 
607
558
  (void) TextureImage(image, fill->texture);
@@ -1,6 +1,6 @@
1
- /* $Id: rmilist.c,v 1.46.2.1.2.3 2008/09/10 23:25:13 rmagick Exp $ */
1
+ /* $Id: rmilist.c,v 1.65 2007/12/26 21:41:24 rmagick Exp $ */
2
2
  /*============================================================================\
3
- | Copyright (C) 2008 by Timothy P. Hunter
3
+ | Copyright (C) 2007 by Timothy P. Hunter
4
4
  | Name: rmilist.c
5
5
  | Author: Tim Hunter
6
6
  | Purpose: ImageList class method definitions for RMagick
@@ -8,6 +8,13 @@
8
8
 
9
9
  #include "rmagick.h"
10
10
 
11
+ static Image *clone_imagelist(Image *);
12
+ static Image *images_from_imagelist(VALUE);
13
+ static long imagelist_length(VALUE);
14
+ static VALUE imagelist_scene_eq(VALUE, VALUE);
15
+ static void imagelist_push(VALUE, VALUE);
16
+ static VALUE ImageList_new(void);
17
+
11
18
 
12
19
  /*
13
20
  Method: ImageList#animate(<delay>)
@@ -29,7 +36,7 @@ ImageList_animate(int argc, VALUE *argv, VALUE self)
29
36
  }
30
37
 
31
38
  // Convert the images array to an images sequence.
32
- images = rm_images_from_imagelist(self);
39
+ images = images_from_imagelist(self);
33
40
 
34
41
  if (argc == 1)
35
42
  {
@@ -68,7 +75,7 @@ ImageList_append(VALUE self, VALUE stack_arg)
68
75
  ExceptionInfo exception;
69
76
 
70
77
  // Convert the image array to an image sequence.
71
- images = rm_images_from_imagelist(self);
78
+ images = images_from_imagelist(self);
72
79
 
73
80
  // If stack == true, stack rectangular images top-to-bottom,
74
81
  // otherwise left-to-right.
@@ -97,7 +104,7 @@ ImageList_average(VALUE self)
97
104
  ExceptionInfo exception;
98
105
 
99
106
  // Convert the images array to an images sequence.
100
- images = rm_images_from_imagelist(self);
107
+ images = images_from_imagelist(self);
101
108
 
102
109
  GetExceptionInfo(&exception);
103
110
  new_image = AverageImages(images, &exception);
@@ -125,7 +132,7 @@ ImageList_coalesce(VALUE self)
125
132
  ExceptionInfo exception;
126
133
 
127
134
  // Convert the image array to an image sequence.
128
- images = rm_images_from_imagelist(self);
135
+ images = images_from_imagelist(self);
129
136
 
130
137
  GetExceptionInfo(&exception);
131
138
  new_images = CoalesceImages(images, &exception);
@@ -139,6 +146,69 @@ ImageList_coalesce(VALUE self)
139
146
  }
140
147
 
141
148
 
149
+ /*
150
+ Method: ImageList#composite_layers
151
+ Purpose: Equivalent to convert's -layers composite option
152
+ Notes: see mogrify.c
153
+ */
154
+ VALUE
155
+ ImageList_composite_layers(int argc, VALUE *argv, VALUE self)
156
+ {
157
+ #if defined(HAVE_COMPOSITELAYERS)
158
+ volatile VALUE source_images;
159
+ Image *dest, *source, *new_images;
160
+ RectangleInfo geometry;
161
+ CompositeOperator operator = OverCompositeOp;
162
+ ExceptionInfo exception;
163
+
164
+ switch (argc)
165
+ {
166
+ case 2:
167
+ VALUE_TO_ENUM(argv[1], operator, CompositeOperator);
168
+ case 1:
169
+ source_images = argv[0];
170
+ break;
171
+ default:
172
+ rb_raise(rb_eArgError, "wrong number of arguments (expected 1 or 2, got %d)", argc);
173
+ break;
174
+ }
175
+
176
+ // Convert ImageLists to image sequences.
177
+ dest = images_from_imagelist(self);
178
+ new_images = clone_imagelist(dest);
179
+ rm_split(dest);
180
+
181
+ source = images_from_imagelist(source_images);
182
+
183
+ SetGeometry(new_images,&geometry);
184
+ (void) ParseAbsoluteGeometry(new_images->geometry, &geometry);
185
+
186
+ geometry.width = source->page.width != 0 ? source->page.width : source->columns;
187
+ geometry.height = source->page.height != 0 ? source->page.height : source->rows;
188
+ GravityAdjustGeometry(new_images->page.width != 0 ? new_images->page.width : new_images->columns
189
+ , new_images->page.height != 0 ? new_images->page.height : new_images->rows
190
+ , new_images->gravity, &geometry);
191
+
192
+ GetExceptionInfo(&exception);
193
+ CompositeLayers(new_images, operator, source, geometry.x, geometry.y, &exception);
194
+ rm_split(source);
195
+ rm_check_exception(&exception, new_images, DestroyOnError);
196
+ (void) DestroyExceptionInfo(&exception);
197
+
198
+ return rm_imagelist_from_images(new_images);
199
+
200
+ #else
201
+
202
+ self = self;
203
+ argc = argc;
204
+ argv = argv;
205
+ rm_not_implemented();
206
+ return (VALUE)0;
207
+
208
+ #endif
209
+ }
210
+
211
+
142
212
  /*
143
213
  Method: ImageList#deconstruct
144
214
  Purpose: compares each image with the next in a sequence and returns
@@ -152,7 +222,7 @@ ImageList_deconstruct(VALUE self)
152
222
  Image *new_images, *images;
153
223
  ExceptionInfo exception;
154
224
 
155
- images = rm_images_from_imagelist(self);
225
+ images = images_from_imagelist(self);
156
226
  GetExceptionInfo(&exception);
157
227
  new_images = DeconstructImages(images, &exception);
158
228
  rm_split(images);
@@ -180,7 +250,7 @@ ImageList_display(VALUE self)
180
250
  Data_Get_Struct(info_obj, Info, info);
181
251
 
182
252
  // Convert the images array to an images sequence.
183
- images = rm_images_from_imagelist(self);
253
+ images = images_from_imagelist(self);
184
254
 
185
255
  (void) DisplayImages(info, images);
186
256
  rm_split(images);
@@ -201,9 +271,15 @@ ImageList_flatten_images(VALUE self)
201
271
  Image *images, *new_image;
202
272
  ExceptionInfo exception;
203
273
 
204
- images = rm_images_from_imagelist(self);
274
+ images = images_from_imagelist(self);
205
275
  GetExceptionInfo(&exception);
276
+
277
+ #if defined(HAVE_ENUM_FLATTENLAYER)
278
+ new_image = MergeImageLayers(images, FlattenLayer, &exception);
279
+ #else
206
280
  new_image = FlattenImages(images, &exception);
281
+ #endif
282
+
207
283
  rm_split(images);
208
284
  rm_check_exception(&exception, new_image, DestroyOnError);
209
285
  (void) DestroyExceptionInfo(&exception);
@@ -220,7 +296,6 @@ ImageList_flatten_images(VALUE self)
220
296
  VALUE
221
297
  ImageList_fx(int argc, VALUE *argv, VALUE self)
222
298
  {
223
- #if defined(HAVE_FXIMAGECHANNEL)
224
299
  Image *images, *new_image;
225
300
  char *expression;
226
301
  ChannelType channels;
@@ -239,9 +314,9 @@ ImageList_fx(int argc, VALUE *argv, VALUE self)
239
314
  raise_ChannelType_error(argv[argc-1]);
240
315
  }
241
316
 
242
- expression = STRING_PTR(argv[0]);
317
+ expression = StringValuePtr(argv[0]);
243
318
 
244
- images = rm_images_from_imagelist(self);
319
+ images = images_from_imagelist(self);
245
320
  GetExceptionInfo(&exception);
246
321
  new_image = FxImageChannel(images, channels, expression, &exception);
247
322
  rm_split(images);
@@ -251,10 +326,6 @@ ImageList_fx(int argc, VALUE *argv, VALUE self)
251
326
  rm_ensure_result(new_image);
252
327
 
253
328
  return rm_image_new(new_image);
254
- #else
255
- rm_not_implemented();
256
- return (VALUE)0;
257
- #endif
258
329
  }
259
330
 
260
331
 
@@ -270,7 +341,7 @@ ImageList_map(int argc, VALUE *argv, VALUE self)
270
341
  Image *images, *new_images = NULL;
271
342
  Image *map;
272
343
  unsigned int dither = False;
273
- volatile VALUE scene, new_imagelist;
344
+ volatile VALUE scene, new_imagelist, t;
274
345
  ExceptionInfo exception;
275
346
 
276
347
  switch (argc)
@@ -278,7 +349,8 @@ ImageList_map(int argc, VALUE *argv, VALUE self)
278
349
  case 2:
279
350
  dither = RTEST(argv[1]);
280
351
  case 1:
281
- Data_Get_Struct(ImageList_cur_image(argv[0]), Image, map);
352
+ t = ImageList_cur_image(argv[0]);
353
+ map = rm_check_destroyed(t);
282
354
  break;
283
355
  default:
284
356
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
@@ -286,7 +358,7 @@ ImageList_map(int argc, VALUE *argv, VALUE self)
286
358
  }
287
359
 
288
360
 
289
- if (rm_imagelist_length(self) == 0)
361
+ if (imagelist_length(self) == 0L)
290
362
  {
291
363
  rb_raise(rb_eArgError, "no images in this image list");
292
364
  }
@@ -294,7 +366,7 @@ ImageList_map(int argc, VALUE *argv, VALUE self)
294
366
  // Convert image array to image sequence, clone image sequence.
295
367
  GetExceptionInfo(&exception);
296
368
 
297
- images = rm_images_from_imagelist(self);
369
+ images = images_from_imagelist(self);
298
370
  new_images = CloneImageList(images, &exception);
299
371
  rm_split(images);
300
372
  rm_check_exception(&exception, new_images, DestroyOnError);
@@ -309,7 +381,7 @@ ImageList_map(int argc, VALUE *argv, VALUE self)
309
381
  // Set @scene in new ImageList object to same value as in self.
310
382
  new_imagelist = rm_imagelist_from_images(new_images);
311
383
  scene = rb_iv_get(self, "@scene");
312
- (void) rm_imagelist_scene_eq(new_imagelist, scene);
384
+ (void) imagelist_scene_eq(new_imagelist, scene);
313
385
 
314
386
  return new_imagelist;
315
387
  }
@@ -339,7 +411,7 @@ ImageList_montage(VALUE self)
339
411
 
340
412
  Data_Get_Struct(montage_obj, Montage, montage);
341
413
 
342
- images = rm_images_from_imagelist(self);
414
+ images = images_from_imagelist(self);
343
415
 
344
416
  // If app specified a non-default composition operator, use it for all images.
345
417
  if (montage->compose != UndefinedCompositeOp)
@@ -379,7 +451,7 @@ ImageList_morph(VALUE self, VALUE nimages)
379
451
  ExceptionInfo exception;
380
452
  long number_images;
381
453
 
382
- if (rm_imagelist_length(self) < 1)
454
+ if (imagelist_length(self) < 1L)
383
455
  {
384
456
  rb_raise(rb_eArgError, "no images in this image list");
385
457
  }
@@ -392,7 +464,7 @@ ImageList_morph(VALUE self, VALUE nimages)
392
464
  }
393
465
 
394
466
  GetExceptionInfo(&exception);
395
- images = rm_images_from_imagelist(self);
467
+ images = images_from_imagelist(self);
396
468
  new_images = MorphImages(images, (unsigned long)number_images, &exception);
397
469
  rm_split(images);
398
470
  rm_check_exception(&exception, new_images, DestroyOnError);
@@ -415,8 +487,14 @@ ImageList_mosaic(VALUE self)
415
487
  ExceptionInfo exception;
416
488
 
417
489
  GetExceptionInfo(&exception);
418
- images = rm_images_from_imagelist(self);
490
+ images = images_from_imagelist(self);
491
+
492
+ #if defined(HAVE_ENUM_MOSAICLAYER)
493
+ new_image = MergeImageLayers(images, MosaicLayer, &exception);
494
+ #else
419
495
  new_image = MosaicImages(images, &exception);
496
+ #endif
497
+
420
498
  rm_split(images);
421
499
  rm_check_exception(&exception, new_image, DestroyOnError);
422
500
  (void) DestroyExceptionInfo(&exception);
@@ -435,28 +513,75 @@ ImageList_mosaic(VALUE self)
435
513
  VALUE
436
514
  ImageList_optimize_layers(VALUE self, VALUE method)
437
515
  {
438
- #if defined(HAVE_COMPAREIMAGELAYERS)
439
- Image *images, *new_images;
440
- MagickLayerMethod mthd;
516
+ Image *images, *new_images, *new_images2;
517
+ LAYERMETHODTYPE mthd;
441
518
  ExceptionInfo exception;
442
519
 
520
+ new_images2 = NULL; // defeat "unused variable" message
521
+
443
522
  GetExceptionInfo(&exception);
523
+ #if defined(HAVE_TYPE_IMAGELAYERMETHOD)
524
+ VALUE_TO_ENUM(method, mthd, ImageLayerMethod);
525
+ #else
444
526
  VALUE_TO_ENUM(method, mthd, MagickLayerMethod);
445
- images = rm_images_from_imagelist(self);
527
+ #endif
528
+ images = images_from_imagelist(self);
446
529
 
447
530
  switch (mthd)
448
531
  {
449
- #if defined(HAVE_COALESCELAYER)
450
532
  case CoalesceLayer:
451
533
  new_images = CoalesceImages(images, &exception);
452
534
  break;
453
535
  case DisposeLayer:
454
536
  new_images = DisposeImages(images, &exception);
455
537
  break;
538
+ #if defined(HAVE_ENUM_OPTIMIZETRANSLAYER)
539
+ case OptimizeTransLayer:
540
+ new_images = clone_imagelist(images);
541
+ OptimizeImageTransparency(new_images, &exception);
542
+ break;
543
+ #endif
544
+ #if defined(HAVE_ENUM_REMOVEDUPSLAYER)
545
+ case RemoveDupsLayer:
546
+ new_images = clone_imagelist(images);
547
+ RemoveDuplicateLayers(&new_images, &exception);
548
+ break;
456
549
  #endif
550
+ #if defined(HAVE_ENUM_REMOVEZEROLAYER)
551
+ case RemoveZeroLayer:
552
+ new_images = clone_imagelist(images);
553
+ RemoveZeroDelayLayers(&new_images, &exception);
554
+ break;
555
+ #endif
556
+ #if defined(HAVE_ENUM_COMPOSITELAYER)
557
+ case CompositeLayer:
558
+ rb_raise(rb_eNotImpError, "Magick::CompositeLayer is not yet supported.");
559
+ break;
560
+ #endif
561
+ #if defined(HAVE_ENUM_OPTIMIZEIMAGELAYER)
562
+ // In 6.3.4-ish, OptimizeImageLayer replaced OptimizeLayer
563
+ case OptimizeImageLayer:
564
+ new_images = OptimizeImageLayers(images, &exception);
565
+ break;
566
+ // and OptimizeLayer became a "General Purpose, GIF Animation Optimizer" (ref. mogrify.c)
567
+ case OptimizeLayer:
568
+ new_images = CoalesceImages(images, &exception);
569
+ rm_split(images);
570
+ rm_check_exception(&exception, new_images, DestroyOnError);
571
+ new_images2 = OptimizeImageLayers(new_images, &exception);
572
+ DestroyImageList(new_images);
573
+ rm_check_exception(&exception, new_images2, DestroyOnError);
574
+ new_images = new_images2;
575
+ OptimizeImageTransparency(new_images, &exception);
576
+ rm_check_exception(&exception, new_images, DestroyOnError);
577
+ // mogrify supports -dither here. We don't.
578
+ (void) MapImages(new_images, NULL, 0);
579
+ break;
580
+ #else
457
581
  case OptimizeLayer:
458
582
  new_images = OptimizeImageLayers(images, &exception);
459
583
  break;
584
+ #endif
460
585
  case OptimizePlusLayer:
461
586
  new_images = OptimizePlusImageLayers(images, &exception);
462
587
  break;
@@ -477,27 +602,21 @@ ImageList_optimize_layers(VALUE self, VALUE method)
477
602
  rm_ensure_result(new_images);
478
603
 
479
604
  return rm_imagelist_from_images(new_images);
480
-
481
- #else
482
- rm_not_implemented();
483
- return (VALUE)0;
484
- #endif
485
605
  }
486
606
 
487
607
 
488
608
  /*
489
- External: rm_imagelist_new
609
+ Static: ImageList_new
490
610
  Purpose: create a new ImageList object with no images
491
611
  Notes: this simply calls ImageList.new() in RMagick.rb
492
612
  */
493
- VALUE
494
- rm_imagelist_new(void)
613
+ static VALUE
614
+ ImageList_new()
495
615
  {
496
616
  return rb_funcall(Class_ImageList, rm_ID_new, 0);
497
617
  }
498
618
 
499
619
 
500
-
501
620
  /*
502
621
  Extern: rm_imagelist_from_images
503
622
  Purpose: Construct a new imagelist object from a list of images
@@ -506,51 +625,53 @@ rm_imagelist_new(void)
506
625
  VALUE
507
626
  rm_imagelist_from_images(Image *images)
508
627
  {
509
- volatile VALUE new_imagelist;
510
- Image *image;
628
+ volatile VALUE new_imagelist;
629
+ Image *image;
511
630
 
512
- if (!images)
513
- {
514
- rb_bug("rm_imagelist_from_images called with NULL argument");
515
- }
631
+ if (!images)
632
+ {
633
+ rb_bug("rm_imagelist_from_images called with NULL argument");
634
+ }
516
635
 
517
- new_imagelist = rm_imagelist_new();
636
+ new_imagelist = ImageList_new();
518
637
 
519
- while (images)
520
- {
521
- image = RemoveFirstImageFromList(&images);
522
- rm_imagelist_push(new_imagelist, rm_image_new(image));
523
- }
638
+ while (images)
639
+ {
640
+ image = RemoveFirstImageFromList(&images);
641
+ imagelist_push(new_imagelist, rm_image_new(image));
642
+ }
524
643
 
525
- (void) rb_iv_set(new_imagelist, "@scene", INT2FIX(0));
526
- return new_imagelist;
644
+ (void) rb_iv_set(new_imagelist, "@scene", INT2FIX(0));
645
+ return new_imagelist;
527
646
  }
528
647
 
529
648
 
530
649
  /*
531
- Extern: rm_images_from_imagelist
650
+ Extern: images_from_imagelist
532
651
  Purpose: Convert an array of Image *s to an ImageMagick scene
533
652
  sequence (i.e. a doubly-linked list of Images)
534
653
  Returns: a pointer to the head of the scene sequence list
535
654
  */
536
- Image *
537
- rm_images_from_imagelist(VALUE imagelist)
655
+ static Image *
656
+ images_from_imagelist(VALUE imagelist)
538
657
  {
539
658
  long x, len;
540
659
  Image *head = NULL;
660
+ volatile VALUE images, t;
541
661
 
542
- Check_Type(imagelist, T_ARRAY);
543
- len = rm_imagelist_length(imagelist);
662
+ len = imagelist_length(imagelist);
544
663
  if (len == 0)
545
664
  {
546
665
  rb_raise(rb_eArgError, "no images in this image list");
547
666
  }
548
667
 
668
+ images = rb_iv_get(imagelist, "@images");
549
669
  for (x = 0; x < len; x++)
550
670
  {
551
671
  Image *image;
552
672
 
553
- Data_Get_Struct(rb_ary_entry(imagelist, x), Image, image);
673
+ t = rb_ary_entry(images, x);
674
+ image = rm_check_destroyed(t);
554
675
  AppendImageToList(&head, image);
555
676
  }
556
677
 
@@ -559,41 +680,66 @@ rm_images_from_imagelist(VALUE imagelist)
559
680
 
560
681
 
561
682
  /*
562
- * Extern: rm_imagelist_scene_eq(imagelist, scene)
683
+ * Static: imagelist_scene_eq(imagelist, scene)
563
684
  * Purpose: @scene attribute writer
564
685
  */
565
- VALUE
566
- rm_imagelist_scene_eq(VALUE imagelist, VALUE scene)
686
+ static VALUE
687
+ imagelist_scene_eq(VALUE imagelist, VALUE scene)
567
688
  {
568
- rm_check_frozen(imagelist);
569
- (void) rb_iv_set(imagelist, "@scene", scene);
570
- return scene;
689
+ rb_check_frozen(imagelist);
690
+ (void) rb_iv_set(imagelist, "@scene", scene);
691
+ return scene;
571
692
  }
572
693
 
573
694
  /*
574
- External: rm_imagelist_length
575
- Purpose: return the # of images in an imagelist
695
+ Static: imagelist_length
696
+ Purpose: return the # of images in an imagelist
576
697
  */
577
- int
578
- rm_imagelist_length(VALUE imagelist)
698
+ static long
699
+ imagelist_length(VALUE imagelist)
579
700
  {
580
- volatile VALUE len;
581
-
582
- len = rb_funcall(imagelist, rm_ID_length, 0);
583
- return FIX2INT(len);
701
+ volatile VALUE images = rb_iv_get(imagelist, "@images");
702
+ return RARRAY(images)->len;
584
703
  }
585
704
 
586
705
  /*
587
- External: rm_imagelist_push
706
+ Static: imagelist_push
588
707
  Purpose: push an image onto the end of the imagelist
589
708
  */
590
- void
591
- rm_imagelist_push(VALUE imagelist, VALUE image)
709
+ static void
710
+ imagelist_push(VALUE imagelist, VALUE image)
592
711
  {
593
- rm_check_frozen(imagelist);
712
+ rb_check_frozen(imagelist);
594
713
  (void) rb_funcall(imagelist, rm_ID_push, 1, image);
595
714
  }
596
715
 
716
+
717
+ /*
718
+ * Static: clone_imagelist
719
+ * Purpose: clone a list of images, handle errors
720
+ */
721
+ static Image *
722
+ clone_imagelist(Image *images)
723
+ {
724
+ Image *new_imagelist = NULL, *image, *clone;
725
+ ExceptionInfo exception;
726
+
727
+ GetExceptionInfo(&exception);
728
+
729
+ image = GetFirstImageInList(images);
730
+ while (image)
731
+ {
732
+ clone = CloneImage(image, 0, 0, MagickTrue, &exception);
733
+ rm_check_exception(&exception, new_imagelist, DestroyOnError);
734
+ AppendImageToList(&new_imagelist, clone);
735
+ image = GetNextImageInList(image);
736
+ }
737
+
738
+ (void) DestroyExceptionInfo(&exception);
739
+ return new_imagelist;
740
+ }
741
+
742
+
597
743
  /*
598
744
  Method: ImageList#quantize(<number_colors<, colorspace<, dither<, tree_depth<, measure_error>>>>>)
599
745
  defaults: 256, Magick::RGBColorspace, true, 0, false
@@ -631,14 +777,14 @@ ImageList_quantize(int argc, VALUE *argv, VALUE self)
631
777
  break;
632
778
  }
633
779
 
634
- if (rm_imagelist_length(self) == 0)
780
+ if (imagelist_length(self) == 0L)
635
781
  {
636
782
  rb_raise(rb_eArgError, "no images in this image list");
637
783
  }
638
784
 
639
785
  // Convert image array to image sequence, clone image sequence.
640
786
  GetExceptionInfo(&exception);
641
- images = rm_images_from_imagelist(self);
787
+ images = images_from_imagelist(self);
642
788
  new_images = CloneImageList(images, &exception);
643
789
  rm_split(images);
644
790
  rm_check_exception(&exception, new_images, DestroyOnError);
@@ -652,10 +798,10 @@ ImageList_quantize(int argc, VALUE *argv, VALUE self)
652
798
 
653
799
  // Create new ImageList object, convert mapped image sequence to images,
654
800
  // append to images array.
655
- new_imagelist = rm_imagelist_new();
656
- while ((new_image = RemoveFirstImageFromList(&new_images)))
801
+ new_imagelist = ImageList_new();
802
+ while ((new_image = ShiftImageList(&new_images)))
657
803
  {
658
- rm_imagelist_push(new_imagelist, rm_image_new(new_image));
804
+ imagelist_push(new_imagelist, rm_image_new(new_image));
659
805
  }
660
806
 
661
807
  // Set @scene in new ImageList object to same value as in self.
@@ -686,7 +832,7 @@ ImageList_to_blob(VALUE self)
686
832
  Data_Get_Struct(info_obj, Info, info);
687
833
 
688
834
  // Convert the images array to an images sequence.
689
- images = rm_images_from_imagelist(self);
835
+ images = images_from_imagelist(self);
690
836
 
691
837
  GetExceptionInfo(&exception);
692
838
  (void) SetImageInfo(info, MagickTrue, &exception);
@@ -705,16 +851,10 @@ ImageList_to_blob(VALUE self)
705
851
  // can happen is that there's only one image or the format
706
852
  // doesn't support multi-image files.
707
853
  info->adjoin = MagickTrue;
708
- #if defined(HAVE_IMAGESTOBLOB)
709
854
  blob = ImagesToBlob(info, images, &length, &exception);
710
- #else
711
- blob = ImageToBlob(info, images, &length, &exception);
712
- #endif
713
- if (blob && exception.severity >= ErrorException)
855
+ if (exception.severity != UndefinedException)
714
856
  {
715
857
  magick_free((void*)blob);
716
- blob = NULL;
717
- length = 0;
718
858
  }
719
859
  rm_split(images);
720
860
  CHECK_EXCEPTION()
@@ -740,7 +880,7 @@ ImageList_to_blob(VALUE self)
740
880
  static VALUE file_arg_rescue(VALUE arg)
741
881
  {
742
882
  rb_raise(rb_eTypeError, "argument must be path name or open file (%s given)",
743
- rb_class2name(CLASS_OF(arg)));
883
+ rb_class2name(CLASS_OF(arg)));
744
884
  }
745
885
 
746
886
 
@@ -782,7 +922,7 @@ ImageList_write(VALUE self, VALUE file)
782
922
  file = rb_rescue(rb_String, file, file_arg_rescue, file);
783
923
 
784
924
  // Copy the filename to the Info and to the Image.
785
- filename = STRING_PTR_LEN(file, filenameL);
925
+ filename = rb_str2cstr(file, &filenameL);
786
926
  filenameL = min(filenameL, MaxTextExtent-1);
787
927
  memcpy(info->filename, filename, (size_t)filenameL);
788
928
  info->filename[filenameL] = '\0';
@@ -790,7 +930,7 @@ ImageList_write(VALUE self, VALUE file)
790
930
  }
791
931
 
792
932
  // Convert the images array to an images sequence.
793
- images = rm_images_from_imagelist(self);
933
+ images = images_from_imagelist(self);
794
934
 
795
935
  // Copy the filename into each images. Set a scene number to be used if
796
936
  // writing multiple files. (Ref: ImageMagick's utilities/convert.c
@@ -812,7 +952,7 @@ ImageList_write(VALUE self, VALUE file)
812
952
  (void) DestroyExceptionInfo(&exception);
813
953
 
814
954
  // Tell WriteImage if we want a multi-images file.
815
- if (rm_imagelist_length(self) > 1 && m->adjoin)
955
+ if (imagelist_length(self) > 1L && m->adjoin)
816
956
  {
817
957
  info->adjoin = MagickTrue;
818
958
  }