rmagick 7.0.5 → 7.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +39 -0
- data/Rakefile +6 -0
- data/ext/RMagick/extconf.rb +2 -2
- data/ext/RMagick/rmagick.cpp +26 -4
- data/ext/RMagick/rmagick.h +5 -3
- data/ext/RMagick/rmdraw.cpp +15 -45
- data/ext/RMagick/rmenum.cpp +5 -5
- data/ext/RMagick/rmilist.cpp +102 -24
- data/ext/RMagick/rmimage.cpp +102 -55
- data/ext/RMagick/rminfo.cpp +11 -3
- data/ext/RMagick/rmkinfo.cpp +1 -1
- data/ext/RMagick/rmmain.cpp +3 -2
- data/ext/RMagick/rmmontage.cpp +1 -1
- data/ext/RMagick/rmpixel.cpp +4 -4
- data/ext/RMagick/rmutil.cpp +44 -10
- data/lib/rmagick/version.rb +1 -1
- data/lib/rmagick_internal.rb +13 -7
- data/lib/rvg/embellishable.rb +8 -1
- data/lib/rvg/misc.rb +3 -22
- data/lib/rvg/stylable.rb +2 -2
- data/sig/rmagick/_image_common_methods.rbs +1 -0
- data/sig/rvg/misc.rbs +0 -1
- metadata +2 -2
data/ext/RMagick/rmilist.cpp
CHANGED
|
@@ -11,8 +11,16 @@
|
|
|
11
11
|
|
|
12
12
|
#include "rmagick.h"
|
|
13
13
|
|
|
14
|
+
struct ImagesFromImageList_Args
|
|
15
|
+
{
|
|
16
|
+
VALUE imagelist;
|
|
17
|
+
VALUE *clones;
|
|
18
|
+
Image *images;
|
|
19
|
+
};
|
|
20
|
+
|
|
14
21
|
static Image *clone_imagelist(Image *);
|
|
15
|
-
static Image *images_from_imagelist(VALUE);
|
|
22
|
+
static Image *images_from_imagelist(VALUE, VALUE *);
|
|
23
|
+
static VALUE images_from_imagelist_protected(VALUE);
|
|
16
24
|
static long imagelist_length(VALUE);
|
|
17
25
|
static long check_imagelist_length(VALUE);
|
|
18
26
|
static void imagelist_push(VALUE, VALUE);
|
|
@@ -93,7 +101,8 @@ ImageList_animate(int argc, VALUE *argv, VALUE self)
|
|
|
93
101
|
info_obj = rm_info_new();
|
|
94
102
|
|
|
95
103
|
// Convert the images array to an images sequence.
|
|
96
|
-
|
|
104
|
+
VALUE clones;
|
|
105
|
+
images = images_from_imagelist(self, &clones);
|
|
97
106
|
|
|
98
107
|
if (argc == 1)
|
|
99
108
|
{
|
|
@@ -120,6 +129,7 @@ ImageList_animate(int argc, VALUE *argv, VALUE self)
|
|
|
120
129
|
rm_check_image_exception(images, RetainOnError);
|
|
121
130
|
#endif
|
|
122
131
|
|
|
132
|
+
RB_GC_GUARD(clones);
|
|
123
133
|
RB_GC_GUARD(info_obj);
|
|
124
134
|
|
|
125
135
|
return self;
|
|
@@ -140,7 +150,8 @@ ImageList_append(VALUE self, VALUE stack_arg)
|
|
|
140
150
|
ExceptionInfo *exception;
|
|
141
151
|
|
|
142
152
|
// Convert the image array to an image sequence.
|
|
143
|
-
|
|
153
|
+
VALUE clones;
|
|
154
|
+
images = images_from_imagelist(self, &clones);
|
|
144
155
|
|
|
145
156
|
// If stack == true, stack rectangular images top-to-bottom,
|
|
146
157
|
// otherwise left-to-right.
|
|
@@ -150,6 +161,7 @@ ImageList_append(VALUE self, VALUE stack_arg)
|
|
|
150
161
|
GVL_STRUCT_TYPE(AppendImages) args = { images, stack, exception };
|
|
151
162
|
new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(AppendImages), &args);
|
|
152
163
|
rm_split(images);
|
|
164
|
+
RB_GC_GUARD(clones);
|
|
153
165
|
rm_check_exception(exception, new_image, DestroyOnError);
|
|
154
166
|
DestroyExceptionInfo(exception);
|
|
155
167
|
|
|
@@ -169,12 +181,14 @@ ImageList_average(VALUE self)
|
|
|
169
181
|
ExceptionInfo *exception;
|
|
170
182
|
|
|
171
183
|
// Convert the images array to an images sequence.
|
|
172
|
-
|
|
184
|
+
VALUE clones;
|
|
185
|
+
images = images_from_imagelist(self, &clones);
|
|
173
186
|
|
|
174
187
|
exception = AcquireExceptionInfo();
|
|
175
188
|
GVL_STRUCT_TYPE(EvaluateImages) args = { images, MeanEvaluateOperator, exception };
|
|
176
189
|
new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(EvaluateImages), &args);
|
|
177
190
|
rm_split(images);
|
|
191
|
+
RB_GC_GUARD(clones);
|
|
178
192
|
rm_check_exception(exception, new_image, DestroyOnError);
|
|
179
193
|
DestroyExceptionInfo(exception);
|
|
180
194
|
|
|
@@ -197,12 +211,14 @@ ImageList_coalesce(VALUE self)
|
|
|
197
211
|
ExceptionInfo *exception;
|
|
198
212
|
|
|
199
213
|
// Convert the image array to an image sequence.
|
|
200
|
-
|
|
214
|
+
VALUE clones;
|
|
215
|
+
images = images_from_imagelist(self, &clones);
|
|
201
216
|
|
|
202
217
|
exception = AcquireExceptionInfo();
|
|
203
218
|
GVL_STRUCT_TYPE(CoalesceImages) args = { images, exception };
|
|
204
219
|
new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CoalesceImages), &args);
|
|
205
220
|
rm_split(images);
|
|
221
|
+
RB_GC_GUARD(clones);
|
|
206
222
|
rm_check_exception(exception, new_images, DestroyOnError);
|
|
207
223
|
DestroyExceptionInfo(exception);
|
|
208
224
|
|
|
@@ -284,7 +300,8 @@ VALUE ImageList_combine(int argc, VALUE *argv, VALUE self)
|
|
|
284
300
|
}
|
|
285
301
|
#endif
|
|
286
302
|
|
|
287
|
-
|
|
303
|
+
VALUE clones;
|
|
304
|
+
images = images_from_imagelist(self, &clones);
|
|
288
305
|
exception = AcquireExceptionInfo();
|
|
289
306
|
#if defined(IMAGEMAGICK_6)
|
|
290
307
|
old_colorspace = images->colorspace;
|
|
@@ -296,6 +313,7 @@ VALUE ImageList_combine(int argc, VALUE *argv, VALUE self)
|
|
|
296
313
|
new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CombineImages), &args);
|
|
297
314
|
|
|
298
315
|
rm_split(images);
|
|
316
|
+
RB_GC_GUARD(clones);
|
|
299
317
|
#if defined(IMAGEMAGICK_6)
|
|
300
318
|
images->colorspace = old_colorspace;
|
|
301
319
|
#endif
|
|
@@ -341,11 +359,23 @@ ImageList_composite_layers(int argc, VALUE *argv, VALUE self)
|
|
|
341
359
|
}
|
|
342
360
|
|
|
343
361
|
// Convert ImageLists to image sequences.
|
|
344
|
-
|
|
362
|
+
VALUE clones, source_clones = Qnil;
|
|
363
|
+
dest = images_from_imagelist(self, &clones);
|
|
345
364
|
new_images = clone_imagelist(dest);
|
|
346
365
|
rm_split(dest);
|
|
347
|
-
|
|
348
|
-
|
|
366
|
+
RB_GC_GUARD(clones);
|
|
367
|
+
|
|
368
|
+
// new_images is not owned by any Ruby object yet, so resolving the source
|
|
369
|
+
// list has to be able to unwind without abandoning it.
|
|
370
|
+
struct ImagesFromImageList_Args source_args = { source_images, &source_clones, NULL };
|
|
371
|
+
int state = 0;
|
|
372
|
+
rb_protect(images_from_imagelist_protected, (VALUE)&source_args, &state);
|
|
373
|
+
if (state)
|
|
374
|
+
{
|
|
375
|
+
DestroyImageList(new_images);
|
|
376
|
+
rb_jump_tag(state);
|
|
377
|
+
}
|
|
378
|
+
source = source_args.images;
|
|
349
379
|
|
|
350
380
|
SetGeometry(new_images, &geometry);
|
|
351
381
|
ParseAbsoluteGeometry(new_images->geometry, &geometry);
|
|
@@ -360,6 +390,7 @@ ImageList_composite_layers(int argc, VALUE *argv, VALUE self)
|
|
|
360
390
|
GVL_STRUCT_TYPE(CompositeLayers) args = { new_images, composite_op, source, geometry.x, geometry.y, exception };
|
|
361
391
|
CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CompositeLayers), &args);
|
|
362
392
|
rm_split(source);
|
|
393
|
+
RB_GC_GUARD(source_clones);
|
|
363
394
|
rm_check_exception(exception, new_images, DestroyOnError);
|
|
364
395
|
DestroyExceptionInfo(exception);
|
|
365
396
|
|
|
@@ -381,7 +412,8 @@ ImageList_deconstruct(VALUE self)
|
|
|
381
412
|
Image *new_images, *images;
|
|
382
413
|
ExceptionInfo *exception;
|
|
383
414
|
|
|
384
|
-
|
|
415
|
+
VALUE clones;
|
|
416
|
+
images = images_from_imagelist(self, &clones);
|
|
385
417
|
exception = AcquireExceptionInfo();
|
|
386
418
|
#if defined(IMAGEMAGICK_7)
|
|
387
419
|
GVL_STRUCT_TYPE(CompareImagesLayers) args = { images, CompareAnyLayer, exception };
|
|
@@ -391,6 +423,7 @@ ImageList_deconstruct(VALUE self)
|
|
|
391
423
|
new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(DeconstructImages), &args);
|
|
392
424
|
#endif
|
|
393
425
|
rm_split(images);
|
|
426
|
+
RB_GC_GUARD(clones);
|
|
394
427
|
rm_check_exception(exception, new_images, DestroyOnError);
|
|
395
428
|
DestroyExceptionInfo(exception);
|
|
396
429
|
|
|
@@ -420,7 +453,8 @@ ImageList_display(VALUE self)
|
|
|
420
453
|
TypedData_Get_Struct(info_obj, Info, &rm_info_data_type, info);
|
|
421
454
|
|
|
422
455
|
// Convert the images array to an images sequence.
|
|
423
|
-
|
|
456
|
+
VALUE clones;
|
|
457
|
+
images = images_from_imagelist(self, &clones);
|
|
424
458
|
#if defined(IMAGEMAGICK_7)
|
|
425
459
|
exception = AcquireExceptionInfo();
|
|
426
460
|
DisplayImages(info, images, exception);
|
|
@@ -433,6 +467,7 @@ ImageList_display(VALUE self)
|
|
|
433
467
|
rm_check_image_exception(images, RetainOnError);
|
|
434
468
|
#endif
|
|
435
469
|
|
|
470
|
+
RB_GC_GUARD(clones);
|
|
436
471
|
RB_GC_GUARD(info_obj);
|
|
437
472
|
|
|
438
473
|
return self;
|
|
@@ -450,13 +485,15 @@ ImageList_flatten_images(VALUE self)
|
|
|
450
485
|
Image *images, *new_image;
|
|
451
486
|
ExceptionInfo *exception;
|
|
452
487
|
|
|
453
|
-
|
|
488
|
+
VALUE clones;
|
|
489
|
+
images = images_from_imagelist(self, &clones);
|
|
454
490
|
exception = AcquireExceptionInfo();
|
|
455
491
|
|
|
456
492
|
GVL_STRUCT_TYPE(MergeImageLayers) args = { images, FlattenLayer, exception };
|
|
457
493
|
new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
|
|
458
494
|
|
|
459
495
|
rm_split(images);
|
|
496
|
+
RB_GC_GUARD(clones);
|
|
460
497
|
rm_check_exception(exception, new_image, DestroyOnError);
|
|
461
498
|
DestroyExceptionInfo(exception);
|
|
462
499
|
|
|
@@ -494,7 +531,8 @@ ImageList_montage(VALUE self)
|
|
|
494
531
|
|
|
495
532
|
TypedData_Get_Struct(montage_obj, Montage, &rm_montage_data_type, montage);
|
|
496
533
|
|
|
497
|
-
|
|
534
|
+
VALUE clones;
|
|
535
|
+
images = images_from_imagelist(self, &clones);
|
|
498
536
|
|
|
499
537
|
for (Image *image = images; image; image = GetNextImageInList(image))
|
|
500
538
|
{
|
|
@@ -514,6 +552,7 @@ ImageList_montage(VALUE self)
|
|
|
514
552
|
GVL_STRUCT_TYPE(MontageImages) args = { images, montage->info, exception };
|
|
515
553
|
new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MontageImages), &args);
|
|
516
554
|
rm_split(images);
|
|
555
|
+
RB_GC_GUARD(clones);
|
|
517
556
|
rm_check_exception(exception, new_images, DestroyOnError);
|
|
518
557
|
DestroyExceptionInfo(exception);
|
|
519
558
|
|
|
@@ -546,11 +585,13 @@ ImageList_morph(VALUE self, VALUE nimages)
|
|
|
546
585
|
}
|
|
547
586
|
|
|
548
587
|
number_images = NUM2LONG(nimages);
|
|
549
|
-
|
|
588
|
+
VALUE clones;
|
|
589
|
+
images = images_from_imagelist(self, &clones);
|
|
550
590
|
exception = AcquireExceptionInfo();
|
|
551
591
|
GVL_STRUCT_TYPE(MorphImages) args = { images, number_images, exception };
|
|
552
592
|
new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MorphImages), &args);
|
|
553
593
|
rm_split(images);
|
|
594
|
+
RB_GC_GUARD(clones);
|
|
554
595
|
rm_check_exception(exception, new_images, DestroyOnError);
|
|
555
596
|
DestroyExceptionInfo(exception);
|
|
556
597
|
|
|
@@ -569,13 +610,15 @@ ImageList_mosaic(VALUE self)
|
|
|
569
610
|
Image *images, *new_image;
|
|
570
611
|
ExceptionInfo *exception;
|
|
571
612
|
|
|
572
|
-
|
|
613
|
+
VALUE clones;
|
|
614
|
+
images = images_from_imagelist(self, &clones);
|
|
573
615
|
|
|
574
616
|
exception = AcquireExceptionInfo();
|
|
575
617
|
GVL_STRUCT_TYPE(MergeImageLayers) args = { images, MosaicLayer, exception };
|
|
576
618
|
new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
|
|
577
619
|
|
|
578
620
|
rm_split(images);
|
|
621
|
+
RB_GC_GUARD(clones);
|
|
579
622
|
rm_check_exception(exception, new_image, DestroyOnError);
|
|
580
623
|
DestroyExceptionInfo(exception);
|
|
581
624
|
|
|
@@ -601,7 +644,8 @@ ImageList_optimize_layers(VALUE self, VALUE method)
|
|
|
601
644
|
new_images2 = NULL; // defeat "unused variable" message
|
|
602
645
|
|
|
603
646
|
VALUE_TO_ENUM(method, mthd, LayerMethod);
|
|
604
|
-
|
|
647
|
+
VALUE clones;
|
|
648
|
+
images = images_from_imagelist(self, &clones);
|
|
605
649
|
|
|
606
650
|
exception = AcquireExceptionInfo();
|
|
607
651
|
switch (mthd)
|
|
@@ -730,6 +774,7 @@ ImageList_optimize_layers(VALUE self, VALUE method)
|
|
|
730
774
|
}
|
|
731
775
|
|
|
732
776
|
rm_split(images);
|
|
777
|
+
RB_GC_GUARD(clones);
|
|
733
778
|
rm_check_exception(exception, new_images, DestroyOnError);
|
|
734
779
|
DestroyExceptionInfo(exception);
|
|
735
780
|
|
|
@@ -802,12 +847,14 @@ rm_imagelist_from_images(Image *images)
|
|
|
802
847
|
* @see rm_imagelist_from_images
|
|
803
848
|
*/
|
|
804
849
|
static Image *
|
|
805
|
-
images_from_imagelist(VALUE imagelist)
|
|
850
|
+
images_from_imagelist(VALUE imagelist, VALUE *clones)
|
|
806
851
|
{
|
|
807
852
|
long x, len;
|
|
808
853
|
Image *head = NULL;
|
|
809
854
|
VALUE images, t;
|
|
810
855
|
|
|
856
|
+
*clones = rb_ary_new();
|
|
857
|
+
|
|
811
858
|
len = check_imagelist_length(imagelist);
|
|
812
859
|
|
|
813
860
|
images = rb_iv_get(imagelist, "@images");
|
|
@@ -823,7 +870,9 @@ images_from_imagelist(VALUE imagelist)
|
|
|
823
870
|
image = rm_clone_image(image);
|
|
824
871
|
|
|
825
872
|
// Wrap raw ImageMagick object by Ruby object to destroy using Ruby's GC.
|
|
826
|
-
|
|
873
|
+
// The wrapper is kept in *clones so that the GC cannot reclaim it, and
|
|
874
|
+
// with it the Image, while the list below is still in use.
|
|
875
|
+
rb_ary_push(*clones, rm_image_new(image));
|
|
827
876
|
}
|
|
828
877
|
AppendImageToList(&head, image);
|
|
829
878
|
}
|
|
@@ -835,6 +884,26 @@ images_from_imagelist(VALUE imagelist)
|
|
|
835
884
|
}
|
|
836
885
|
|
|
837
886
|
|
|
887
|
+
/**
|
|
888
|
+
* Call images_from_imagelist() so that it can be passed to rb_protect().
|
|
889
|
+
*
|
|
890
|
+
* No Ruby usage (internal function)
|
|
891
|
+
*
|
|
892
|
+
* @param arg a pointer to an ImagesFromImageList_Args, cast to a VALUE
|
|
893
|
+
* @return nil, the result is stored in the argument
|
|
894
|
+
* @see images_from_imagelist
|
|
895
|
+
*/
|
|
896
|
+
static VALUE
|
|
897
|
+
images_from_imagelist_protected(VALUE arg)
|
|
898
|
+
{
|
|
899
|
+
struct ImagesFromImageList_Args *args = (struct ImagesFromImageList_Args *)arg;
|
|
900
|
+
|
|
901
|
+
args->images = images_from_imagelist(args->imagelist, args->clones);
|
|
902
|
+
|
|
903
|
+
return Qnil;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
|
|
838
907
|
/**
|
|
839
908
|
* return the # of images in an imagelist.
|
|
840
909
|
*
|
|
@@ -859,7 +928,7 @@ imagelist_length(VALUE imagelist)
|
|
|
859
928
|
|
|
860
929
|
|
|
861
930
|
/**
|
|
862
|
-
* Raise exception if imagelist is
|
|
931
|
+
* Raise exception if imagelist is empty.
|
|
863
932
|
*
|
|
864
933
|
* No Ruby usage (internal function)
|
|
865
934
|
*
|
|
@@ -934,7 +1003,7 @@ clone_imagelist(Image *images)
|
|
|
934
1003
|
* Analyzes the colors within a set of reference images and chooses a fixed number of colors to represent the set.
|
|
935
1004
|
* The goal of the algorithm is to minimize the difference between the input and output images while minimizing the processing time.
|
|
936
1005
|
*
|
|
937
|
-
* @overload quantize(number_colors = 256, colorspace = Magick::
|
|
1006
|
+
* @overload quantize(number_colors = 256, colorspace = Magick::RGBColorspace, dither = true, tree_depth = 0, measure_error = false)
|
|
938
1007
|
* @param number_colors [Numeric] the maximum number of colors to use in the output images.
|
|
939
1008
|
* @param colorspace [Magick::ColorspaceType] the colorspace to quantize in.
|
|
940
1009
|
* @param dither [Magick::DitherMethod, Boolean] a DitherMethod value or true if you want apply dither.
|
|
@@ -994,11 +1063,13 @@ ImageList_quantize(int argc, VALUE *argv, VALUE self)
|
|
|
994
1063
|
|
|
995
1064
|
|
|
996
1065
|
// Convert image array to image sequence, clone image sequence.
|
|
997
|
-
|
|
1066
|
+
VALUE clones;
|
|
1067
|
+
images = images_from_imagelist(self, &clones);
|
|
998
1068
|
exception = AcquireExceptionInfo();
|
|
999
1069
|
GVL_STRUCT_TYPE(CloneImageList) args_CloneImageList = { images, exception };
|
|
1000
1070
|
new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CloneImageList), &args_CloneImageList);
|
|
1001
1071
|
rm_split(images);
|
|
1072
|
+
RB_GC_GUARD(clones);
|
|
1002
1073
|
rm_check_exception(exception, new_images, DestroyOnError);
|
|
1003
1074
|
|
|
1004
1075
|
rm_ensure_result(new_images);
|
|
@@ -1071,7 +1142,8 @@ ImageList_remap(int argc, VALUE *argv, VALUE self)
|
|
|
1071
1142
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
|
|
1072
1143
|
}
|
|
1073
1144
|
|
|
1074
|
-
|
|
1145
|
+
VALUE clones;
|
|
1146
|
+
images = images_from_imagelist(self, &clones);
|
|
1075
1147
|
|
|
1076
1148
|
#if defined(IMAGEMAGICK_7)
|
|
1077
1149
|
exception = AcquireExceptionInfo();
|
|
@@ -1087,6 +1159,8 @@ ImageList_remap(int argc, VALUE *argv, VALUE self)
|
|
|
1087
1159
|
rm_check_image_exception(images, RetainOnError);
|
|
1088
1160
|
#endif
|
|
1089
1161
|
|
|
1162
|
+
RB_GC_GUARD(clones);
|
|
1163
|
+
|
|
1090
1164
|
return self;
|
|
1091
1165
|
}
|
|
1092
1166
|
|
|
@@ -1118,7 +1192,8 @@ ImageList_to_blob(VALUE self)
|
|
|
1118
1192
|
TypedData_Get_Struct(info_obj, Info, &rm_info_data_type, info);
|
|
1119
1193
|
|
|
1120
1194
|
// Convert the images array to an images sequence.
|
|
1121
|
-
|
|
1195
|
+
VALUE clones;
|
|
1196
|
+
images = images_from_imagelist(self, &clones);
|
|
1122
1197
|
|
|
1123
1198
|
exception = AcquireExceptionInfo();
|
|
1124
1199
|
SetImageInfo(info, MagickTrue, exception);
|
|
@@ -1151,6 +1226,7 @@ ImageList_to_blob(VALUE self)
|
|
|
1151
1226
|
length = 0;
|
|
1152
1227
|
}
|
|
1153
1228
|
rm_split(images);
|
|
1229
|
+
RB_GC_GUARD(clones);
|
|
1154
1230
|
CHECK_EXCEPTION();
|
|
1155
1231
|
DestroyExceptionInfo(exception);
|
|
1156
1232
|
|
|
@@ -1216,7 +1292,8 @@ ImageList_write(VALUE self, VALUE file)
|
|
|
1216
1292
|
}
|
|
1217
1293
|
|
|
1218
1294
|
// Convert the images array to an images sequence.
|
|
1219
|
-
|
|
1295
|
+
VALUE clones;
|
|
1296
|
+
images = images_from_imagelist(self, &clones);
|
|
1220
1297
|
|
|
1221
1298
|
// Copy the filename into each image. Set a scene number to be used if
|
|
1222
1299
|
// writing multiple files. (Ref: ImageMagick's utilities/convert.c
|
|
@@ -1267,6 +1344,7 @@ ImageList_write(VALUE self, VALUE file)
|
|
|
1267
1344
|
#endif
|
|
1268
1345
|
|
|
1269
1346
|
rm_split(images);
|
|
1347
|
+
RB_GC_GUARD(clones);
|
|
1270
1348
|
|
|
1271
1349
|
RB_GC_GUARD(info_obj);
|
|
1272
1350
|
|