rmagick 4.2.5 → 5.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/Dockerfile +14 -0
  3. data/.devcontainer/ImageMagick6/devcontainer.json +11 -0
  4. data/.devcontainer/devcontainer.json +11 -0
  5. data/.devcontainer/setup-repo.sh +10 -0
  6. data/.devcontainer/setup-user.sh +45 -0
  7. data/.editorconfig +1 -1
  8. data/.github/workflows/ci.yml +90 -9
  9. data/.gitignore +4 -0
  10. data/.rubocop_todo.yml +16 -9
  11. data/.yardopts +1 -1
  12. data/CHANGELOG.md +141 -0
  13. data/Gemfile +20 -0
  14. data/README.md +12 -17
  15. data/Rakefile +63 -80
  16. data/before_install_linux.sh +4 -4
  17. data/before_install_osx.sh +7 -6
  18. data/ext/RMagick/extconf.rb +113 -52
  19. data/ext/RMagick/{rmagick.c → rmagick.cpp} +19 -22
  20. data/ext/RMagick/rmagick.h +88 -59
  21. data/ext/RMagick/rmagick_gvl.h +224 -0
  22. data/ext/RMagick/{rmdraw.c → rmdraw.cpp} +170 -159
  23. data/ext/RMagick/{rmenum.c → rmenum.cpp} +69 -50
  24. data/ext/RMagick/{rmfill.c → rmfill.cpp} +85 -24
  25. data/ext/RMagick/{rmilist.c → rmilist.cpp} +191 -93
  26. data/ext/RMagick/{rmimage.c → rmimage.cpp} +1544 -989
  27. data/ext/RMagick/{rminfo.c → rminfo.cpp} +140 -152
  28. data/ext/RMagick/{rmkinfo.c → rmkinfo.cpp} +46 -34
  29. data/ext/RMagick/rmmain.cpp +1923 -0
  30. data/ext/RMagick/{rmmontage.c → rmmontage.cpp} +50 -29
  31. data/ext/RMagick/{rmpixel.c → rmpixel.cpp} +108 -83
  32. data/ext/RMagick/{rmstruct.c → rmstruct.cpp} +6 -6
  33. data/ext/RMagick/{rmutil.c → rmutil.cpp} +62 -161
  34. data/lib/rmagick/version.rb +3 -1
  35. data/lib/rmagick.rb +2 -0
  36. data/lib/rmagick_internal.rb +76 -110
  37. data/lib/rvg/embellishable.rb +6 -2
  38. data/lib/rvg/misc.rb +7 -7
  39. data/lib/rvg/rvg.rb +2 -0
  40. data/lib/rvg/stretchable.rb +2 -2
  41. data/lib/rvg/transformable.rb +1 -1
  42. data/rmagick.gemspec +6 -17
  43. data/sig/rmagick/_draw_common_methods.rbs +64 -0
  44. data/sig/rmagick/_image_common_methods.rbs +389 -0
  45. data/sig/rmagick/draw.rbs +38 -0
  46. data/sig/rmagick/draw_attribute.rbs +28 -0
  47. data/sig/rmagick/enum.rbs +814 -0
  48. data/sig/rmagick/error.rbs +11 -0
  49. data/sig/rmagick/fill.rbs +21 -0
  50. data/sig/rmagick/geometry.rbs +14 -0
  51. data/sig/rmagick/image.rbs +194 -0
  52. data/sig/rmagick/image_list.rbs +181 -0
  53. data/sig/rmagick/iptc.rbs +101 -0
  54. data/sig/rmagick/kernel_info.rbs +12 -0
  55. data/sig/rmagick/optional_method_arguments.rbs +10 -0
  56. data/sig/rmagick/pixel.rbs +46 -0
  57. data/sig/rmagick/struct.rbs +90 -0
  58. data/sig/rmagick.rbs +43 -0
  59. data/sig/rvg/clippath.rbs +34 -0
  60. data/sig/rvg/container.rbs +78 -0
  61. data/sig/rvg/deep_equal.rbs +48 -0
  62. data/sig/rvg/describable.rbs +30 -0
  63. data/sig/rvg/embellishable.rbs +226 -0
  64. data/sig/rvg/misc.rbs +145 -0
  65. data/sig/rvg/paint.rbs +55 -0
  66. data/sig/rvg/pathdata.rbs +77 -0
  67. data/sig/rvg/rvg.rbs +125 -0
  68. data/sig/rvg/stretchable.rbs +56 -0
  69. data/sig/rvg/stylable.rbs +66 -0
  70. data/sig/rvg/text.rbs +118 -0
  71. data/sig/rvg/transformable.rbs +59 -0
  72. data/sig/rvg/units.rbs +33 -0
  73. metadata +63 -128
  74. data/.codeclimate.yml +0 -63
  75. data/deprecated/RMagick.rb +0 -6
  76. 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