rmagick 4.2.6 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/ImageMagick6/devcontainer.json +1 -1
  3. data/.devcontainer/{ImageMagick7/devcontainer.json → devcontainer.json} +2 -2
  4. data/.devcontainer/setup-user.sh +1 -1
  5. data/.editorconfig +1 -1
  6. data/.github/workflows/ci.yml +87 -9
  7. data/.gitignore +4 -0
  8. data/.rubocop_todo.yml +16 -9
  9. data/.yardopts +1 -1
  10. data/CHANGELOG.md +130 -0
  11. data/Gemfile +20 -0
  12. data/README.md +10 -17
  13. data/Rakefile +63 -80
  14. data/before_install_linux.sh +3 -3
  15. data/before_install_osx.sh +6 -5
  16. data/ext/RMagick/extconf.rb +112 -52
  17. data/ext/RMagick/{rmagick.c → rmagick.cpp} +19 -22
  18. data/ext/RMagick/rmagick.h +88 -59
  19. data/ext/RMagick/rmagick_gvl.h +224 -0
  20. data/ext/RMagick/{rmdraw.c → rmdraw.cpp} +170 -159
  21. data/ext/RMagick/{rmenum.c → rmenum.cpp} +69 -50
  22. data/ext/RMagick/{rmfill.c → rmfill.cpp} +85 -24
  23. data/ext/RMagick/{rmilist.c → rmilist.cpp} +191 -93
  24. data/ext/RMagick/{rmimage.c → rmimage.cpp} +1543 -989
  25. data/ext/RMagick/{rminfo.c → rminfo.cpp} +140 -152
  26. data/ext/RMagick/{rmkinfo.c → rmkinfo.cpp} +46 -34
  27. data/ext/RMagick/rmmain.cpp +1923 -0
  28. data/ext/RMagick/{rmmontage.c → rmmontage.cpp} +50 -29
  29. data/ext/RMagick/{rmpixel.c → rmpixel.cpp} +108 -83
  30. data/ext/RMagick/{rmstruct.c → rmstruct.cpp} +6 -6
  31. data/ext/RMagick/{rmutil.c → rmutil.cpp} +62 -161
  32. data/lib/rmagick/version.rb +3 -1
  33. data/lib/rmagick.rb +2 -0
  34. data/lib/rmagick_internal.rb +76 -110
  35. data/lib/rvg/embellishable.rb +6 -2
  36. data/lib/rvg/misc.rb +7 -7
  37. data/lib/rvg/rvg.rb +2 -0
  38. data/lib/rvg/stretchable.rb +2 -2
  39. data/lib/rvg/transformable.rb +1 -1
  40. data/rmagick.gemspec +4 -13
  41. data/sig/rmagick/_draw_common_methods.rbs +64 -0
  42. data/sig/rmagick/_image_common_methods.rbs +389 -0
  43. data/sig/rmagick/draw.rbs +38 -0
  44. data/sig/rmagick/draw_attribute.rbs +28 -0
  45. data/sig/rmagick/enum.rbs +814 -0
  46. data/sig/rmagick/error.rbs +11 -0
  47. data/sig/rmagick/fill.rbs +21 -0
  48. data/sig/rmagick/geometry.rbs +14 -0
  49. data/sig/rmagick/image.rbs +194 -0
  50. data/sig/rmagick/image_list.rbs +181 -0
  51. data/sig/rmagick/iptc.rbs +101 -0
  52. data/sig/rmagick/kernel_info.rbs +12 -0
  53. data/sig/rmagick/optional_method_arguments.rbs +10 -0
  54. data/sig/rmagick/pixel.rbs +46 -0
  55. data/sig/rmagick/struct.rbs +90 -0
  56. data/sig/rmagick.rbs +43 -0
  57. data/sig/rvg/clippath.rbs +34 -0
  58. data/sig/rvg/container.rbs +78 -0
  59. data/sig/rvg/deep_equal.rbs +48 -0
  60. data/sig/rvg/describable.rbs +30 -0
  61. data/sig/rvg/embellishable.rbs +226 -0
  62. data/sig/rvg/misc.rbs +145 -0
  63. data/sig/rvg/paint.rbs +55 -0
  64. data/sig/rvg/pathdata.rbs +77 -0
  65. data/sig/rvg/rvg.rbs +125 -0
  66. data/sig/rvg/stretchable.rbs +56 -0
  67. data/sig/rvg/stylable.rbs +66 -0
  68. data/sig/rvg/text.rbs +118 -0
  69. data/sig/rvg/transformable.rbs +59 -0
  70. data/sig/rvg/units.rbs +33 -0
  71. metadata +59 -129
  72. data/.codeclimate.yml +0 -63
  73. data/deprecated/RMagick.rb +0 -6
  74. data/ext/RMagick/rmmain.c +0 -1951
@@ -5,8 +5,8 @@
5
5
  *
6
6
  * Changes since Nov. 2009 copyright © by Benjamin Thomas and Omer Bar-or
7
7
  *
8
- * @file rmilist.c
9
- * @version $Id: rmilist.c,v 1.94 2009/12/20 02:33:33 baror Exp $
8
+ * @file rmilist.cpp
9
+ * @version $Id: rmilist.cpp,v 1.94 2009/12/20 02:33:33 baror Exp $
10
10
  * @author Tim Hunter
11
11
  ******************************************************************************/
12
12
 
@@ -20,7 +20,39 @@ static void imagelist_push(VALUE, VALUE);
20
20
  static VALUE ImageList_new(void);
21
21
 
22
22
 
23
+ DEFINE_GVL_STUB3(AppendImages, const Image *, const MagickBooleanType, ExceptionInfo *);
24
+ DEFINE_GVL_STUB5(CloneImage, const Image *, const size_t, const size_t, const MagickBooleanType, ExceptionInfo *);
25
+ DEFINE_GVL_STUB2(CloneImageList, const Image *, ExceptionInfo *);
26
+ DEFINE_GVL_STUB2(CoalesceImages, const Image *, ExceptionInfo *);
27
+ DEFINE_GVL_STUB2(DisposeImages, const Image *, ExceptionInfo *);
28
+ DEFINE_GVL_STUB3(EvaluateImages, const Image *, const MagickEvaluateOperator, ExceptionInfo *);
29
+ DEFINE_GVL_STUB4(ImagesToBlob, const ImageInfo *, Image *, size_t *, ExceptionInfo *);
30
+ DEFINE_GVL_STUB3(MergeImageLayers, Image *, const LayerMethod, ExceptionInfo *);
31
+ DEFINE_GVL_STUB3(MontageImages, const Image *, const MontageInfo *, ExceptionInfo *);
32
+ DEFINE_GVL_STUB3(MorphImages, const Image *, const size_t, ExceptionInfo *);
33
+ DEFINE_GVL_STUB2(OptimizeImageLayers, const Image *, ExceptionInfo *);
34
+ DEFINE_GVL_STUB2(OptimizePlusImageLayers, const Image *, ExceptionInfo *);
35
+ #if defined(IMAGEMAGICK_7)
36
+ DEFINE_GVL_STUB3(AnimateImages, const ImageInfo *, Image *, ExceptionInfo *);
37
+ DEFINE_GVL_STUB3(CombineImages, const Image *, const ColorspaceType, ExceptionInfo *);
38
+ DEFINE_GVL_STUB3(CompareImagesLayers, const Image *, const LayerMethod, ExceptionInfo *);
39
+ DEFINE_GVL_STUB3(QuantizeImages, const QuantizeInfo *, Image *, ExceptionInfo *);
40
+ DEFINE_GVL_STUB4(RemapImages, const QuantizeInfo *, Image *, const Image *, ExceptionInfo *);
41
+ DEFINE_GVL_STUB3(WriteImage, const ImageInfo *, Image *, ExceptionInfo *);
42
+ #else
43
+ DEFINE_GVL_STUB2(AnimateImages, const ImageInfo *, Image *);
44
+ DEFINE_GVL_STUB3(CombineImages, const Image *, const ChannelType, ExceptionInfo *);
45
+ DEFINE_GVL_STUB3(CompareImageLayers, const Image *, const ImageLayerMethod, ExceptionInfo *);
46
+ DEFINE_GVL_STUB2(DeconstructImages, const Image *, ExceptionInfo *);
47
+ DEFINE_GVL_STUB2(QuantizeImages, const QuantizeInfo *, Image *);
48
+ DEFINE_GVL_STUB3(RemapImages, const QuantizeInfo *, Image *, const Image *);
49
+ DEFINE_GVL_STUB2(WriteImage, const ImageInfo *, Image *);
50
+ #endif
23
51
 
52
+ DEFINE_GVL_VOID_STUB6(CompositeLayers, Image *, const CompositeOperator, Image *, const ssize_t, const ssize_t, ExceptionInfo *);
53
+ DEFINE_GVL_VOID_STUB2(OptimizeImageTransparency, const Image *, ExceptionInfo *);
54
+ DEFINE_GVL_VOID_STUB2(RemoveDuplicateLayers, Image **, ExceptionInfo *);
55
+ DEFINE_GVL_VOID_STUB2(RemoveZeroDelayLayers, Image **, ExceptionInfo *);
24
56
 
25
57
 
26
58
  /**
@@ -32,6 +64,8 @@ static VALUE ImageList_new(void);
32
64
  *
33
65
  * @overload animate(delay)
34
66
  * @param delay [Numeric] the length of time between each image in an animation
67
+ * @yield [info]
68
+ * @yieldparam info [Magick::Image::Info]
35
69
  *
36
70
  * @return [Magick::ImageList] self
37
71
  */
@@ -72,15 +106,17 @@ ImageList_animate(int argc, VALUE *argv, VALUE self)
72
106
  }
73
107
  }
74
108
 
75
- Data_Get_Struct(info_obj, Info, info);
109
+ TypedData_Get_Struct(info_obj, Info, &rm_info_data_type, info);
76
110
  #if defined(IMAGEMAGICK_7)
77
111
  exception = AcquireExceptionInfo();
78
- AnimateImages(info, images, exception);
112
+ GVL_STRUCT_TYPE(AnimateImages) args = { info, images, exception };
113
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(AnimateImages), &args);
79
114
  rm_split(images);
80
115
  CHECK_EXCEPTION();
81
116
  DestroyExceptionInfo(exception);
82
117
  #else
83
- AnimateImages(info, images);
118
+ GVL_STRUCT_TYPE(AnimateImages) args = { info, images };
119
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(AnimateImages), &args);
84
120
  rm_split(images);
85
121
  rm_check_image_exception(images, RetainOnError);
86
122
  #endif
@@ -101,7 +137,7 @@ VALUE
101
137
  ImageList_append(VALUE self, VALUE stack_arg)
102
138
  {
103
139
  Image *images, *new_image;
104
- unsigned int stack;
140
+ MagickBooleanType stack;
105
141
  ExceptionInfo *exception;
106
142
 
107
143
  // Convert the image array to an image sequence.
@@ -109,10 +145,11 @@ ImageList_append(VALUE self, VALUE stack_arg)
109
145
 
110
146
  // If stack == true, stack rectangular images top-to-bottom,
111
147
  // otherwise left-to-right.
112
- stack = RTEST(stack_arg);
148
+ stack = (MagickBooleanType)RTEST(stack_arg);
113
149
 
114
150
  exception = AcquireExceptionInfo();
115
- new_image = AppendImages(images, stack, exception);
151
+ GVL_STRUCT_TYPE(AppendImages) args = { images, stack, exception };
152
+ new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(AppendImages), &args);
116
153
  rm_split(images);
117
154
  rm_check_exception(exception, new_image, DestroyOnError);
118
155
  DestroyExceptionInfo(exception);
@@ -136,8 +173,8 @@ ImageList_average(VALUE self)
136
173
  images = images_from_imagelist(self);
137
174
 
138
175
  exception = AcquireExceptionInfo();
139
- new_image = EvaluateImages(images, MeanEvaluateOperator, exception);
140
-
176
+ GVL_STRUCT_TYPE(EvaluateImages) args = { images, MeanEvaluateOperator, exception };
177
+ new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(EvaluateImages), &args);
141
178
  rm_split(images);
142
179
  rm_check_exception(exception, new_image, DestroyOnError);
143
180
  DestroyExceptionInfo(exception);
@@ -164,7 +201,8 @@ ImageList_coalesce(VALUE self)
164
201
  images = images_from_imagelist(self);
165
202
 
166
203
  exception = AcquireExceptionInfo();
167
- new_images = CoalesceImages(images, exception);
204
+ GVL_STRUCT_TYPE(CoalesceImages) args = { images, exception };
205
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CoalesceImages), &args);
168
206
  rm_split(images);
169
207
  rm_check_exception(exception, new_images, DestroyOnError);
170
208
  DestroyExceptionInfo(exception);
@@ -224,20 +262,20 @@ VALUE ImageList_combine(int argc, VALUE *argv, VALUE self)
224
262
  {
225
263
  case 5:
226
264
  if (colorspace == CMYKColorspace)
227
- channel |= AlphaChannel;
265
+ channel = (ChannelType)(channel | AlphaChannel);
228
266
  else
229
267
  rb_raise(rb_eArgError, "invalid number of images in this image list");
230
268
  case 4:
231
269
  if (colorspace == CMYKColorspace)
232
- channel |= IndexChannel;
270
+ channel = (ChannelType)(channel | IndexChannel);
233
271
  else
234
- channel |= AlphaChannel;
272
+ channel = (ChannelType)(channel | AlphaChannel);
235
273
  case 3:
236
- channel |= GreenChannel;
237
- channel |= BlueChannel;
274
+ channel = (ChannelType)(channel | GreenChannel);
275
+ channel = (ChannelType)(channel | BlueChannel);
238
276
  break;
239
277
  case 2:
240
- channel |= AlphaChannel;
278
+ channel = (ChannelType)(channel | AlphaChannel);
241
279
  break;
242
280
  case 1:
243
281
  break;
@@ -252,10 +290,11 @@ VALUE ImageList_combine(int argc, VALUE *argv, VALUE self)
252
290
  #if defined(IMAGEMAGICK_6)
253
291
  old_colorspace = images->colorspace;
254
292
  SetImageColorspace(images, colorspace);
255
- new_image = CombineImages(images, channel, exception);
293
+ GVL_STRUCT_TYPE(CombineImages) args = { images, channel, exception };
256
294
  #else
257
- new_image = CombineImages(images, colorspace, exception);
295
+ GVL_STRUCT_TYPE(CombineImages) args = { images, colorspace, exception };
258
296
  #endif
297
+ new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CombineImages), &args);
259
298
 
260
299
  rm_split(images);
261
300
  #if defined(IMAGEMAGICK_6)
@@ -274,10 +313,10 @@ VALUE ImageList_combine(int argc, VALUE *argv, VALUE self)
274
313
  * @overload composite_layers(images)
275
314
  * @param images [Magick::ImageList] the source images
276
315
  *
277
- * @overload composite_layers(images, operator)
316
+ * @overload composite_layers(images, composite_op)
278
317
  * - Default operator is {Magick::OverCompositeOp}
279
318
  * @param images [Magick::ImageList] the source images
280
- * @param operator [Magick::CompositeOperator] the operator
319
+ * @param composite_op [Magick::CompositeOperator] the operator
281
320
  *
282
321
  * @return [Magick::ImageList] a new imagelist
283
322
  */
@@ -287,13 +326,13 @@ ImageList_composite_layers(int argc, VALUE *argv, VALUE self)
287
326
  VALUE source_images;
288
327
  Image *dest, *source, *new_images;
289
328
  RectangleInfo geometry;
290
- CompositeOperator operator = OverCompositeOp;
329
+ CompositeOperator composite_op = OverCompositeOp;
291
330
  ExceptionInfo *exception;
292
331
 
293
332
  switch (argc)
294
333
  {
295
334
  case 2:
296
- VALUE_TO_ENUM(argv[1], operator, CompositeOperator);
335
+ VALUE_TO_ENUM(argv[1], composite_op, CompositeOperator);
297
336
  case 1:
298
337
  source_images = argv[0];
299
338
  break;
@@ -319,7 +358,8 @@ ImageList_composite_layers(int argc, VALUE *argv, VALUE self)
319
358
  new_images->gravity, &geometry);
320
359
 
321
360
  exception = AcquireExceptionInfo();
322
- CompositeLayers(new_images, operator, source, geometry.x, geometry.y, exception);
361
+ GVL_STRUCT_TYPE(CompositeLayers) args = { new_images, composite_op, source, geometry.x, geometry.y, exception };
362
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CompositeLayers), &args);
323
363
  rm_split(source);
324
364
  rm_check_exception(exception, new_images, DestroyOnError);
325
365
  DestroyExceptionInfo(exception);
@@ -345,9 +385,11 @@ ImageList_deconstruct(VALUE self)
345
385
  images = images_from_imagelist(self);
346
386
  exception = AcquireExceptionInfo();
347
387
  #if defined(IMAGEMAGICK_7)
348
- new_images = CompareImagesLayers(images, CompareAnyLayer, exception);
388
+ GVL_STRUCT_TYPE(CompareImagesLayers) args = { images, CompareAnyLayer, exception };
389
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CompareImagesLayers), &args);
349
390
  #else
350
- new_images = DeconstructImages(images, exception);
391
+ GVL_STRUCT_TYPE(DeconstructImages) args = { images, exception };
392
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(DeconstructImages), &args);
351
393
  #endif
352
394
  rm_split(images);
353
395
  rm_check_exception(exception, new_images, DestroyOnError);
@@ -360,6 +402,8 @@ ImageList_deconstruct(VALUE self)
360
402
  /**
361
403
  * Display all the images to an X window screen.
362
404
  *
405
+ * @yield [info]
406
+ * @yieldparam info [Magick::Image::Info]
363
407
  * @return [Magick::ImageList] self
364
408
  */
365
409
  VALUE
@@ -374,7 +418,7 @@ ImageList_display(VALUE self)
374
418
 
375
419
  // Create a new Info object to use with this call
376
420
  info_obj = rm_info_new();
377
- Data_Get_Struct(info_obj, Info, info);
421
+ TypedData_Get_Struct(info_obj, Info, &rm_info_data_type, info);
378
422
 
379
423
  // Convert the images array to an images sequence.
380
424
  images = images_from_imagelist(self);
@@ -410,7 +454,8 @@ ImageList_flatten_images(VALUE self)
410
454
  images = images_from_imagelist(self);
411
455
  exception = AcquireExceptionInfo();
412
456
 
413
- new_image = MergeImageLayers(images, FlattenLayer, exception);
457
+ GVL_STRUCT_TYPE(MergeImageLayers) args = { images, FlattenLayer, exception };
458
+ new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
414
459
 
415
460
  rm_split(images);
416
461
  rm_check_exception(exception, new_image, DestroyOnError);
@@ -428,8 +473,9 @@ ImageList_flatten_images(VALUE self)
428
473
  * @overload montage
429
474
  * Creates {Magick::ImageList::Montage} object, yields to block
430
475
  * if present in {Magick::ImageList::Montage} object's scope.
431
- * @yield [Magick::ImageList::Montage]
432
- *
476
+ * @yield [opt]
477
+ * @yieldparam opt [Magick::ImageList::Montage]
478
+ *
433
479
  * @return [Magick::ImageList] a new image list
434
480
  */
435
481
  VALUE
@@ -444,20 +490,10 @@ ImageList_montage(VALUE self)
444
490
  montage_obj = rm_montage_new();
445
491
  if (rb_block_given_p())
446
492
  {
447
- // Run the block in the instance's context, allowing the app to modify the
448
- // object's attributes.
449
- if (rb_proc_arity(rb_block_proc()) == 0)
450
- {
451
- rb_warn("passing a block without an image argument is deprecated");
452
- rb_obj_instance_eval(0, NULL, montage_obj);
453
- }
454
- else
455
- {
456
- rb_yield(montage_obj);
457
- }
493
+ rb_yield(montage_obj);
458
494
  }
459
495
 
460
- Data_Get_Struct(montage_obj, Montage, montage);
496
+ TypedData_Get_Struct(montage_obj, Montage, &rm_montage_data_type, montage);
461
497
 
462
498
  images = images_from_imagelist(self);
463
499
 
@@ -476,7 +512,8 @@ ImageList_montage(VALUE self)
476
512
  exception = AcquireExceptionInfo();
477
513
 
478
514
  // MontageImage can return more than one image.
479
- new_images = MontageImages(images, montage->info, exception);
515
+ GVL_STRUCT_TYPE(MontageImages) args = { images, montage->info, exception };
516
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MontageImages), &args);
480
517
  rm_split(images);
481
518
  rm_check_exception(exception, new_images, DestroyOnError);
482
519
  DestroyExceptionInfo(exception);
@@ -500,19 +537,20 @@ ImageList_morph(VALUE self, VALUE nimages)
500
537
  {
501
538
  Image *images, *new_images;
502
539
  ExceptionInfo *exception;
503
- long number_images;
540
+ size_t number_images;
504
541
 
505
542
 
506
543
  // Use a signed long so we can test for a negative argument.
507
- number_images = NUM2LONG(nimages);
508
- if (number_images <= 0)
544
+ if (NUM2LONG(nimages) <= 0)
509
545
  {
510
546
  rb_raise(rb_eArgError, "number of intervening images must be > 0");
511
547
  }
512
548
 
549
+ number_images = NUM2LONG(nimages);
513
550
  images = images_from_imagelist(self);
514
551
  exception = AcquireExceptionInfo();
515
- new_images = MorphImages(images, (unsigned long)number_images, exception);
552
+ GVL_STRUCT_TYPE(MorphImages) args = { images, number_images, exception };
553
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MorphImages), &args);
516
554
  rm_split(images);
517
555
  rm_check_exception(exception, new_images, DestroyOnError);
518
556
  DestroyExceptionInfo(exception);
@@ -535,7 +573,8 @@ ImageList_mosaic(VALUE self)
535
573
  images = images_from_imagelist(self);
536
574
 
537
575
  exception = AcquireExceptionInfo();
538
- new_image = MergeImageLayers(images, MosaicLayer, exception);
576
+ GVL_STRUCT_TYPE(MergeImageLayers) args = { images, MosaicLayer, exception };
577
+ new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
539
578
 
540
579
  rm_split(images);
541
580
  rm_check_exception(exception, new_image, DestroyOnError);
@@ -569,22 +608,37 @@ ImageList_optimize_layers(VALUE self, VALUE method)
569
608
  switch (mthd)
570
609
  {
571
610
  case CoalesceLayer:
572
- new_images = CoalesceImages(images, exception);
611
+ {
612
+ GVL_STRUCT_TYPE(CoalesceImages) args = { images, exception };
613
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CoalesceImages), &args);
614
+ }
573
615
  break;
574
616
  case DisposeLayer:
575
- new_images = DisposeImages(images, exception);
617
+ {
618
+ GVL_STRUCT_TYPE(DisposeImages) args = { images, exception };
619
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(DisposeImages), &args);
620
+ }
576
621
  break;
577
622
  case OptimizeTransLayer:
578
- new_images = clone_imagelist(images);
579
- OptimizeImageTransparency(new_images, exception);
623
+ {
624
+ new_images = clone_imagelist(images);
625
+ GVL_STRUCT_TYPE(OptimizeImageTransparency) args = { new_images, exception };
626
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(OptimizeImageTransparency), &args);
627
+ }
580
628
  break;
581
629
  case RemoveDupsLayer:
582
- new_images = clone_imagelist(images);
583
- RemoveDuplicateLayers(&new_images, exception);
630
+ {
631
+ new_images = clone_imagelist(images);
632
+ GVL_STRUCT_TYPE(RemoveDuplicateLayers) args = { &new_images, exception };
633
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(RemoveDuplicateLayers), &args);
634
+ }
584
635
  break;
585
636
  case RemoveZeroLayer:
586
- new_images = clone_imagelist(images);
587
- RemoveZeroDelayLayers(&new_images, exception);
637
+ {
638
+ new_images = clone_imagelist(images);
639
+ GVL_STRUCT_TYPE(RemoveZeroDelayLayers) args = { &new_images, exception };
640
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(RemoveZeroDelayLayers), &args);
641
+ }
588
642
  break;
589
643
  case CompositeLayer:
590
644
  rm_split(images);
@@ -593,50 +647,81 @@ ImageList_optimize_layers(VALUE self, VALUE method)
593
647
  break;
594
648
  // In 6.3.4-ish, OptimizeImageLayer replaced OptimizeLayer
595
649
  case OptimizeImageLayer:
596
- new_images = OptimizeImageLayers(images, exception);
650
+ {
651
+ GVL_STRUCT_TYPE(OptimizeImageLayers) args = { images, exception };
652
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(OptimizeImageLayers), &args);
653
+ }
597
654
  break;
598
655
  // and OptimizeLayer became a "General Purpose, GIF Animation Optimizer" (ref. mogrify.c)
599
656
  case OptimizeLayer:
600
- new_images = CoalesceImages(images, exception);
601
- rm_split(images);
602
- rm_check_exception(exception, new_images, DestroyOnError);
603
- new_images2 = OptimizeImageLayers(new_images, exception);
604
- DestroyImageList(new_images);
605
- rm_check_exception(exception, new_images2, DestroyOnError);
606
- new_images = new_images2;
607
- OptimizeImageTransparency(new_images, exception);
608
- rm_check_exception(exception, new_images, DestroyOnError);
609
- // mogrify supports -dither here. We don't.
610
- GetQuantizeInfo(&quantize_info);
657
+ {
658
+ GVL_STRUCT_TYPE(CoalesceImages) args_CoalesceImages = { images, exception };
659
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CoalesceImages), &args_CoalesceImages);
660
+ rm_split(images);
661
+ rm_check_exception(exception, new_images, DestroyOnError);
662
+
663
+ GVL_STRUCT_TYPE(OptimizeImageLayers) args_OptimizeImageLayers = { new_images, exception };
664
+ new_images2 = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(OptimizeImageLayers), &args_OptimizeImageLayers);
665
+ DestroyImageList(new_images);
666
+ rm_check_exception(exception, new_images2, DestroyOnError);
667
+
668
+ new_images = new_images2;
669
+ GVL_STRUCT_TYPE(OptimizeImageTransparency) args_OptimizeImageTransparency = { new_images, exception };
670
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(OptimizeImageTransparency), &args_OptimizeImageTransparency);
671
+ rm_check_exception(exception, new_images, DestroyOnError);
672
+ // mogrify supports -dither here. We don't.
673
+ GetQuantizeInfo(&quantize_info);
611
674
  #if defined(IMAGEMAGICK_7)
612
- RemapImages(&quantize_info, new_images, NULL, exception);
675
+ GVL_STRUCT_TYPE(RemapImages) args_RemapImages = { &quantize_info, new_images, NULL, exception };
613
676
  #else
614
- RemapImages(&quantize_info, new_images, NULL);
677
+ GVL_STRUCT_TYPE(RemapImages) args_RemapImages = { &quantize_info, new_images, NULL };
615
678
  #endif
679
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(RemapImages), &args_RemapImages);
680
+
681
+ }
616
682
  break;
617
683
  case OptimizePlusLayer:
618
- new_images = OptimizePlusImageLayers(images, exception);
684
+ {
685
+ GVL_STRUCT_TYPE(OptimizePlusImageLayers) args = { images, exception };
686
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(OptimizePlusImageLayers), &args);
687
+ }
619
688
  break;
620
689
  case CompareAnyLayer:
621
690
  case CompareClearLayer:
622
691
  case CompareOverlayLayer:
692
+ {
623
693
  #if defined(IMAGEMAGICK_7)
624
- new_images = CompareImagesLayers(images, mthd, exception);
694
+ GVL_STRUCT_TYPE(CompareImagesLayers) args = { images, mthd, exception };
695
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CompareImagesLayers), &args);
625
696
  #else
626
- new_images = CompareImageLayers(images, mthd, exception);
697
+ GVL_STRUCT_TYPE(CompareImageLayers) args = { images, mthd, exception };
698
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CompareImageLayers), &args);
627
699
  #endif
700
+ }
628
701
  break;
629
702
  case MosaicLayer:
630
- new_images = MergeImageLayers(images, mthd, exception);
703
+ {
704
+ GVL_STRUCT_TYPE(MergeImageLayers) args = { images, mthd, exception };
705
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
706
+ }
631
707
  break;
632
708
  case FlattenLayer:
633
- new_images = MergeImageLayers(images, mthd, exception);
709
+ {
710
+ GVL_STRUCT_TYPE(MergeImageLayers) args = { images, mthd, exception };
711
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
712
+ }
634
713
  break;
635
714
  case MergeLayer:
636
- new_images = MergeImageLayers(images, mthd, exception);
715
+ {
716
+ GVL_STRUCT_TYPE(MergeImageLayers) args = { images, mthd, exception };
717
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
718
+ }
637
719
  break;
638
720
  case TrimBoundsLayer:
639
- new_images = MergeImageLayers(images, mthd, exception);
721
+ {
722
+ GVL_STRUCT_TYPE(MergeImageLayers) args = { images, mthd, exception };
723
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(MergeImageLayers), &args);
724
+ }
640
725
  break;
641
726
  default:
642
727
  rm_split(images);
@@ -834,7 +919,8 @@ clone_imagelist(Image *images)
834
919
  {
835
920
  Image *clone;
836
921
 
837
- clone = CloneImage(image, 0, 0, MagickTrue, exception);
922
+ GVL_STRUCT_TYPE(CloneImage) args = { image, 0, 0, MagickTrue, exception };
923
+ clone = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CloneImage), &args);
838
924
  rm_check_exception(exception, new_imagelist, DestroyOnError);
839
925
  AppendImageToList(&new_imagelist, clone);
840
926
  image = GetNextImageInList(image);
@@ -889,7 +975,7 @@ ImageList_quantize(int argc, VALUE *argv, VALUE self)
889
975
  if (rb_obj_is_kind_of(argv[2], Class_DitherMethod))
890
976
  {
891
977
  VALUE_TO_ENUM(argv[2], quantize_info.dither_method, DitherMethod);
892
- quantize_info.dither = quantize_info.dither_method != NoDitherMethod;
978
+ quantize_info.dither = (MagickBooleanType)(quantize_info.dither_method != NoDitherMethod);
893
979
  }
894
980
  else
895
981
  {
@@ -911,17 +997,19 @@ ImageList_quantize(int argc, VALUE *argv, VALUE self)
911
997
  // Convert image array to image sequence, clone image sequence.
912
998
  images = images_from_imagelist(self);
913
999
  exception = AcquireExceptionInfo();
914
- new_images = CloneImageList(images, exception);
1000
+ GVL_STRUCT_TYPE(CloneImageList) args_CloneImageList = { images, exception };
1001
+ new_images = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(CloneImageList), &args_CloneImageList);
915
1002
  rm_split(images);
916
1003
  rm_check_exception(exception, new_images, DestroyOnError);
917
1004
 
918
1005
  rm_ensure_result(new_images);
919
1006
 
920
1007
  #if defined(IMAGEMAGICK_7)
921
- QuantizeImages(&quantize_info, new_images, exception);
1008
+ GVL_STRUCT_TYPE(QuantizeImages) args_QuantizeImages = { &quantize_info, new_images, exception };
922
1009
  #else
923
- QuantizeImages(&quantize_info, new_images);
1010
+ GVL_STRUCT_TYPE(QuantizeImages) args_QuantizeImages = { &quantize_info, new_images };
924
1011
  #endif
1012
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(QuantizeImages), &args_QuantizeImages);
925
1013
  rm_check_exception(exception, new_images, DestroyOnError);
926
1014
  DestroyExceptionInfo(exception);
927
1015
 
@@ -988,12 +1076,14 @@ ImageList_remap(int argc, VALUE *argv, VALUE self)
988
1076
 
989
1077
  #if defined(IMAGEMAGICK_7)
990
1078
  exception = AcquireExceptionInfo();
991
- RemapImages(&quantize_info, images, remap_image, exception);
1079
+ GVL_STRUCT_TYPE(RemapImages) args = { &quantize_info, images, remap_image, exception };
1080
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(RemapImages), &args);
992
1081
  rm_split(images);
993
1082
  CHECK_EXCEPTION();
994
1083
  DestroyExceptionInfo(exception);
995
1084
  #else
996
- RemapImages(&quantize_info, images, remap_image);
1085
+ GVL_STRUCT_TYPE(RemapImages) args = { &quantize_info, images, remap_image };
1086
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(RemapImages), &args);
997
1087
  rm_split(images);
998
1088
  rm_check_image_exception(images, RetainOnError);
999
1089
  #endif
@@ -1009,7 +1099,8 @@ ImageList_remap(int argc, VALUE *argv, VALUE self)
1009
1099
  *
1010
1100
  * @overload to_blob
1011
1101
  * Runs an info parm block if present - the user can specify the image format and depth
1012
- * @yield [Magick::Image::Info]
1102
+ * @yield [info]
1103
+ * @yieldparam info [Magick::Image::Info]
1013
1104
  *
1014
1105
  * @return [String] the blob
1015
1106
  */
@@ -1025,7 +1116,7 @@ ImageList_to_blob(VALUE self)
1025
1116
  ExceptionInfo *exception;
1026
1117
 
1027
1118
  info_obj = rm_info_new();
1028
- Data_Get_Struct(info_obj, Info, info);
1119
+ TypedData_Get_Struct(info_obj, Info, &rm_info_data_type, info);
1029
1120
 
1030
1121
  // Convert the images array to an images sequence.
1031
1122
  images = images_from_imagelist(self);
@@ -1052,7 +1143,8 @@ ImageList_to_blob(VALUE self)
1052
1143
  // can happen is that there's only one image or the format
1053
1144
  // doesn't support multi-image files.
1054
1145
  info->adjoin = MagickTrue;
1055
- blob = ImagesToBlob(info, images, &length, exception);
1146
+ GVL_STRUCT_TYPE(ImagesToBlob) args = { info, images, &length, exception };
1147
+ blob = CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ImagesToBlob), &args);
1056
1148
  if (blob && exception->severity >= ErrorException)
1057
1149
  {
1058
1150
  magick_free((void*)blob);
@@ -1069,7 +1161,7 @@ ImageList_to_blob(VALUE self)
1069
1161
  return Qnil;
1070
1162
  }
1071
1163
 
1072
- blob_str = rb_str_new(blob, (long)length);
1164
+ blob_str = rb_str_new((const char *)blob, (long)length);
1073
1165
  magick_free((void*)blob);
1074
1166
 
1075
1167
  RB_GC_GUARD(info_obj);
@@ -1085,6 +1177,8 @@ ImageList_to_blob(VALUE self)
1085
1177
  * the images will be written as a single multi-image file. Otherwise each image
1086
1178
  * will be written to a separate file.
1087
1179
  *
1180
+ * @yield [info]
1181
+ * @yieldparam info [Magick::Image::Info]
1088
1182
  * @param file [File, String] the file
1089
1183
  */
1090
1184
  VALUE
@@ -1098,7 +1192,7 @@ ImageList_write(VALUE self, VALUE file)
1098
1192
  ExceptionInfo *exception;
1099
1193
 
1100
1194
  info_obj = rm_info_new();
1101
- Data_Get_Struct(info_obj, Info, info);
1195
+ TypedData_Get_Struct(info_obj, Info, &rm_info_data_type, info);
1102
1196
 
1103
1197
 
1104
1198
  if (TYPE(file) == T_FILE)
@@ -1107,8 +1201,10 @@ ImageList_write(VALUE self, VALUE file)
1107
1201
 
1108
1202
  // Ensure file is open - raise error if not
1109
1203
  GetOpenFile(file, fptr);
1204
+ rb_io_check_writable(fptr);
1205
+
1206
+ add_format_prefix(info, rm_io_path(file));
1110
1207
  #if defined(_WIN32)
1111
- add_format_prefix(info, fptr->pathv);
1112
1208
  SetImageInfoFile(info, NULL);
1113
1209
  #else
1114
1210
  SetImageInfoFile(info, rb_io_stdio_file(fptr));
@@ -1143,7 +1239,7 @@ ImageList_write(VALUE self, VALUE file)
1143
1239
  #endif
1144
1240
 
1145
1241
  // Tell WriteImage if we want a multi-images file.
1146
- if (imagelist_length(self) > 1L && GetMagickAdjoin(m))
1242
+ if (imagelist_length(self) > 1L && m && GetMagickAdjoin(m))
1147
1243
  {
1148
1244
  info->adjoin = MagickTrue;
1149
1245
  }
@@ -1152,10 +1248,12 @@ ImageList_write(VALUE self, VALUE file)
1152
1248
  {
1153
1249
  rm_sync_image_options(img, info);
1154
1250
  #if defined(IMAGEMAGICK_7)
1155
- WriteImage(info, img, exception);
1251
+ GVL_STRUCT_TYPE(WriteImage) args = { info, img, exception };
1252
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(WriteImage), &args);
1156
1253
  rm_check_exception(exception, img, RetainOnError);
1157
1254
  #else
1158
- WriteImage(info, img);
1255
+ GVL_STRUCT_TYPE(WriteImage) args = { info, img };
1256
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(WriteImage), &args);
1159
1257
  // images will be split before raising an exception
1160
1258
  rm_check_image_exception(images, RetainOnError);
1161
1259
  #endif