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.
- data/ChangeLog +78 -25
- data/README.html +117 -188
- data/README.txt +116 -181
- data/build_tarball.rake +205 -0
- data/doc/comtasks.html +2 -2
- data/doc/constants.html +118 -44
- data/doc/draw.html +57 -99
- data/doc/ex/adaptive_threshold.rb +1 -10
- data/doc/ex/add_noise.rb +4 -5
- data/doc/ex/axes.rb +1 -1
- data/doc/ex/bilevel_channel.rb +2 -13
- data/doc/ex/bounding_box.rb +3 -4
- data/doc/ex/channel.rb +6 -7
- data/doc/ex/clip_path.rb +11 -5
- data/doc/ex/color_histogram.rb +8 -20
- data/doc/ex/composite_layers.rb +53 -0
- data/doc/ex/fill_pattern.rb +26 -0
- data/doc/ex/get_multiline_type_metrics.rb +26 -37
- data/doc/ex/get_type_metrics.rb +25 -25
- data/doc/ex/images/notimplemented.gif +0 -0
- data/doc/ex/level.rb +1 -1
- data/doc/ex/matte_floodfill.rb +5 -6
- data/doc/ex/matte_replace.rb +5 -6
- data/doc/ex/negate_channel.rb +0 -10
- data/doc/ex/opacity.rb +3 -5
- data/doc/ex/polaroid.rb +4 -1
- data/doc/ex/posterize.rb +1 -12
- data/doc/ex/preview.rb +1 -8
- data/doc/ex/radial_blur.rb +1 -11
- data/doc/ex/raise.rb +1 -4
- data/doc/ex/random_threshold_channel.rb +4 -9
- data/doc/ex/sepiatone.rb +2 -9
- data/doc/ex/shadow.rb +12 -18
- data/doc/ex/sketch.rb +2 -9
- data/doc/ex/smile.rb +7 -7
- data/doc/ex/splice.rb +3 -10
- data/doc/ex/stegano.rb +5 -0
- data/doc/ex/threshold.rb +2 -2
- data/doc/ex/transpose.rb +1 -8
- data/doc/ex/transverse.rb +1 -8
- data/doc/ex/trim.rb +1 -2
- data/doc/ex/viewex.rb +4 -5
- data/doc/ex/vignette.rb +1 -8
- data/doc/ex/watermark.rb +1 -0
- data/doc/ex/wet_floor.rb +8 -14
- data/doc/ilist.html +301 -110
- data/doc/image1.html +362 -258
- data/doc/image2.html +429 -286
- data/doc/image3.html +418 -192
- data/doc/imageattrs.html +100 -39
- data/doc/imusage.html +26 -21
- data/doc/index.html +52 -93
- data/doc/info.html +160 -64
- data/doc/magick.html +37 -71
- data/doc/optequiv.html +155 -61
- data/doc/rvg.html +3 -3
- data/doc/rvgclip.html +2 -2
- data/doc/rvggroup.html +2 -2
- data/doc/rvgimage.html +3 -3
- data/doc/rvgpattern.html +3 -3
- data/doc/rvgshape.html +2 -2
- data/doc/rvgstyle.html +2 -2
- data/doc/rvgtext.html +2 -2
- data/doc/rvgtspan.html +4 -4
- data/doc/rvgtut.html +4 -4
- data/doc/rvguse.html +3 -3
- data/doc/rvgxform.html +2 -2
- data/doc/struct.html +26 -29
- data/doc/usage.html +99 -48
- data/examples/crop_with_gravity.rb +46 -0
- data/examples/demo.rb +2 -2
- data/examples/histogram.rb +11 -11
- data/examples/identify.rb +45 -45
- data/examples/spinner.rb +3 -2
- data/ext/RMagick/MANIFEST +7 -8
- data/ext/RMagick/extconf.rb +242 -0
- data/ext/RMagick/rmagick.h +136 -222
- data/ext/RMagick/rmdraw.c +226 -229
- data/ext/RMagick/rmfill.c +69 -118
- data/ext/RMagick/rmilist.c +234 -94
- data/ext/RMagick/rmimage.c +1719 -2564
- data/ext/RMagick/rminfo.c +433 -619
- data/ext/RMagick/rmmain.c +249 -487
- data/ext/RMagick/rmutil.c +344 -563
- data/lib/RMagick.rb +414 -358
- data/lib/rvg/clippath.rb +2 -2
- data/lib/rvg/container.rb +2 -2
- data/lib/rvg/describable.rb +2 -2
- data/lib/rvg/embellishable.rb +2 -2
- data/lib/rvg/misc.rb +3 -3
- data/lib/rvg/paint.rb +2 -7
- data/lib/rvg/pathdata.rb +2 -2
- data/lib/rvg/rvg.rb +2 -2
- data/lib/rvg/stretchable.rb +2 -14
- data/lib/rvg/stylable.rb +2 -2
- data/lib/rvg/text.rb +2 -2
- data/lib/rvg/transformable.rb +2 -2
- data/lib/rvg/units.rb +2 -2
- data/{metaconfig.in → metaconfig} +0 -1
- data/post-setup.rb +1 -1
- data/rmagick.gemspec +6 -9
- metadata +41 -49
- data/Makefile.in +0 -42
- data/configure +0 -12358
- data/configure.ac +0 -791
- data/ext/RMagick/extconf.rb.in +0 -25
- data/ext/RMagick/rmagick_config.h.in +0 -285
- data/gem_extconf.rb +0 -42
data/ext/RMagick/rmfill.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
/* $Id: rmfill.c,v 1.
|
1
|
+
/* $Id: rmfill.c,v 1.25 2007/10/28 23:43:24 rmagick Exp $ */
|
2
2
|
/*============================================================================\
|
3
|
-
| Copyright (C)
|
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.
|
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
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
-
|
88
|
+
MagickRealType red_step, green_step, blue_step;
|
121
89
|
|
122
90
|
steps = sqrt((double)((image->columns-x0)*(image->columns-x0)
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
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
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
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
|
-
|
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
|
189
|
-
green_step = (stop_color->green - start_color->green) / steps;
|
190
|
-
blue_step
|
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
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
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
|
-
|
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
|
260
|
-
green_step = (stop_color->green - start_color->green) / steps;
|
261
|
-
blue_step
|
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
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
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
|
-
|
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 =
|
347
|
-
green_step = (stop_color->green - start_color->green) / steps;
|
348
|
-
blue_step =
|
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
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
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
|
-
|
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 =
|
428
|
-
green_step = (stop_color->green - start_color->green) / steps;
|
429
|
-
blue_step =
|
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
|
-
|
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.
|
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
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
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
|
-
|
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
|
-
|
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);
|
data/ext/RMagick/rmilist.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
/* $Id: rmilist.c,v 1.
|
1
|
+
/* $Id: rmilist.c,v 1.65 2007/12/26 21:41:24 rmagick Exp $ */
|
2
2
|
/*============================================================================\
|
3
|
-
| Copyright (C)
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
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 =
|
317
|
+
expression = StringValuePtr(argv[0]);
|
243
318
|
|
244
|
-
images =
|
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
|
-
|
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 (
|
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 =
|
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)
|
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 =
|
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 (
|
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 =
|
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 =
|
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
|
-
|
439
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
510
|
-
|
628
|
+
volatile VALUE new_imagelist;
|
629
|
+
Image *image;
|
511
630
|
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
631
|
+
if (!images)
|
632
|
+
{
|
633
|
+
rb_bug("rm_imagelist_from_images called with NULL argument");
|
634
|
+
}
|
516
635
|
|
517
|
-
|
636
|
+
new_imagelist = ImageList_new();
|
518
637
|
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
638
|
+
while (images)
|
639
|
+
{
|
640
|
+
image = RemoveFirstImageFromList(&images);
|
641
|
+
imagelist_push(new_imagelist, rm_image_new(image));
|
642
|
+
}
|
524
643
|
|
525
|
-
|
526
|
-
|
644
|
+
(void) rb_iv_set(new_imagelist, "@scene", INT2FIX(0));
|
645
|
+
return new_imagelist;
|
527
646
|
}
|
528
647
|
|
529
648
|
|
530
649
|
/*
|
531
|
-
Extern:
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
*
|
683
|
+
* Static: imagelist_scene_eq(imagelist, scene)
|
563
684
|
* Purpose: @scene attribute writer
|
564
685
|
*/
|
565
|
-
VALUE
|
566
|
-
|
686
|
+
static VALUE
|
687
|
+
imagelist_scene_eq(VALUE imagelist, VALUE scene)
|
567
688
|
{
|
568
|
-
|
569
|
-
|
570
|
-
|
689
|
+
rb_check_frozen(imagelist);
|
690
|
+
(void) rb_iv_set(imagelist, "@scene", scene);
|
691
|
+
return scene;
|
571
692
|
}
|
572
693
|
|
573
694
|
/*
|
574
|
-
|
575
|
-
Purpose:
|
695
|
+
Static: imagelist_length
|
696
|
+
Purpose: return the # of images in an imagelist
|
576
697
|
*/
|
577
|
-
|
578
|
-
|
698
|
+
static long
|
699
|
+
imagelist_length(VALUE imagelist)
|
579
700
|
{
|
580
|
-
volatile VALUE
|
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
|
-
|
706
|
+
Static: imagelist_push
|
588
707
|
Purpose: push an image onto the end of the imagelist
|
589
708
|
*/
|
590
|
-
void
|
591
|
-
|
709
|
+
static void
|
710
|
+
imagelist_push(VALUE imagelist, VALUE image)
|
592
711
|
{
|
593
|
-
|
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 (
|
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 =
|
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 =
|
656
|
-
while ((new_image =
|
801
|
+
new_imagelist = ImageList_new();
|
802
|
+
while ((new_image = ShiftImageList(&new_images)))
|
657
803
|
{
|
658
|
-
|
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 =
|
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
|
-
|
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
|
-
|
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 =
|
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 =
|
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 (
|
955
|
+
if (imagelist_length(self) > 1L && m->adjoin)
|
816
956
|
{
|
817
957
|
info->adjoin = MagickTrue;
|
818
958
|
}
|