rmagick 7.1.7 → 7.2.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 +40 -0
- data/README.md +11 -0
- data/Rakefile +1 -0
- data/ext/RMagick/extconf.rb +3 -2
- data/ext/RMagick/rmagick.h +12 -7
- data/ext/RMagick/rmagick_gvl.cpp +1216 -0
- data/ext/RMagick/rmagick_gvl.h +4 -2
- data/ext/RMagick/rmagick_gvl.hpp +100 -0
- data/ext/RMagick/rmdraw.cpp +101 -70
- data/ext/RMagick/rmfill.cpp +17 -17
- data/ext/RMagick/rmilist.cpp +139 -85
- data/ext/RMagick/rmimage.cpp +1354 -979
- data/ext/RMagick/rminfo.cpp +58 -39
- data/ext/RMagick/rmkinfo.cpp +28 -9
- data/ext/RMagick/rmmain.cpp +2 -0
- data/ext/RMagick/rmmontage.cpp +38 -18
- data/ext/RMagick/rmpixel.cpp +7 -4
- data/ext/RMagick/rmutil.cpp +60 -12
- data/lib/rmagick/version.rb +1 -1
- data/lib/rmagick_internal.rb +15 -4
- data/lib/rvg/rvg.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 765ab71db74f8e2497d857f4041b604abbf848bdcc49d91ae9eb83c13c8dc130
|
|
4
|
+
data.tar.gz: 1466fca25cf24eb504a197f5db46f1a2ae36e5750d4bc82b2e08836efc6fc3b1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e5f6bc440331557b902c94cf9665f572bb50f48242f1760c5cec131d9b86af2d6a92592d43077429ad90cd11171000be3e8c9ba9fb848ed11be515a431e1ee3b
|
|
7
|
+
data.tar.gz: e8cc721b925f6ff4217870ad1234b7e2eb59573a3e951056bf494d50c9855230e80f4564270e0aea067782adacdb3d202b91cbafd8318fff711919c4138751b8
|
data/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,46 @@
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
|
5
5
|
|
|
6
|
+
## RMagick 7.2.0
|
|
7
|
+
|
|
8
|
+
> [!IMPORTANT]
|
|
9
|
+
> Heavy calls can run on a Fiber scheduler's worker pool, `Image#fx` rejects an expression that names a file, and some results change with ImageMagick 7.
|
|
10
|
+
>
|
|
11
|
+
> On Ruby 4.0 and later, a Fiber scheduler with a worker pool, such as `Async::Scheduler.new(worker_pool: IO::Event::WorkerPool.new)`, now runs heavy ImageMagick calls on its workers, and the other fibers keep running. While such a call uses an image, using that image from another fiber raises `RuntimeError` ("object is in use by another fiber") instead of waiting. `Thread#raise`, `Timeout` and Ctrl-C now reach a thread after the ImageMagick call returns, with or without a scheduler. See "Threads, fibers and fork" in README for the rules.
|
|
12
|
+
>
|
|
13
|
+
> `Image#fx` now raises `ArgumentError` for an expression that starts with `@`, or that has a `%[fx:@...]`, `%[hex:@...]` or `%[pixel:@...]` escape. ImageMagick read the file it names, so an expression taken from user input could read any file the process can open. The message is "the expression must not name a file with '@'", as for the other values that reject `@`.
|
|
14
|
+
>
|
|
15
|
+
> With ImageMagick 7, `Pixel.new(red, green, blue, opacity)` now takes the fourth argument as opacity, as with ImageMagick 6, so `Pixel.new(0, 0, 0, 0)` is opaque. `Image#to_color` now uses the depth and alpha channel of the image, as with ImageMagick 6, so it returns `"#D8936A"` instead of `"#D8D893936A6A"` for an 8-bit image without alpha.
|
|
16
|
+
|
|
17
|
+
Breaking Changes
|
|
18
|
+
|
|
19
|
+
* Reject an Image#fx expression beginning with '@' instead of reading that file (#1919)
|
|
20
|
+
* Fix Pixel.new treating the fourth argument as alpha instead of opacity with ImageMagick 7 (#1907)
|
|
21
|
+
* Fix Image#to_color ignoring the image depth and alpha channel with ImageMagick 7 (#1908)
|
|
22
|
+
|
|
23
|
+
Improvements
|
|
24
|
+
|
|
25
|
+
* Improve performance by running ImageMagick calls on a Fiber scheduler's worker pool (#1921)
|
|
26
|
+
* Describe how to use RMagick with threads, fibers and fork in README (#1932)
|
|
27
|
+
* Fix the API reference pages that disagree with the code (#1903-#1906)
|
|
28
|
+
|
|
29
|
+
Bug Fixes
|
|
30
|
+
|
|
31
|
+
* Fix a crash when an image is destroyed in the block of Image#polaroid and similar methods (#1933)
|
|
32
|
+
* Fix an image staying "in use by another fiber" in the child of a fork (#1931)
|
|
33
|
+
* Fix Image#write and other calls doing nothing right after an Async task is stopped (#1930)
|
|
34
|
+
* Fix memory leak when Thread#raise or Timeout interrupts an image operation (#1926)
|
|
35
|
+
* Fix wrong pixels when two calls read the same image at once (#1925)
|
|
36
|
+
* Fix Image#to_color returning the wrong color for a CMYK image (#1920)
|
|
37
|
+
* Fix Image#pixel_color crashing for a coordinate whose pixel offset overflows (#1918)
|
|
38
|
+
* Fix Image.read_inline crashing when ImageMagick returns no image (#1915)
|
|
39
|
+
* Fix pixel_color and get_pixels returning a huge value for a negative HDRI pixel with ImageMagick 7 (#1914)
|
|
40
|
+
* Fix Image.constitute accepting a pixel array whose size overflows (#1913)
|
|
41
|
+
* Fix Image.constitute reading freed memory and leaking on a bad pixel value (#1912)
|
|
42
|
+
* Fix out-of-range values wrapping around in Pixel and the alpha keyword (#1911)
|
|
43
|
+
* Fix highlight_color and lowlight_color having no effect in compare_channel (#1910)
|
|
44
|
+
* Fix Pixel#to_color rejecting depth 16, 32 and 64 with a 64-bit quantum depth (#1909)
|
|
45
|
+
|
|
6
46
|
## RMagick 7.1.7
|
|
7
47
|
|
|
8
48
|
Bug Fixes
|
data/README.md
CHANGED
|
@@ -192,6 +192,17 @@ require 'rmagick'
|
|
|
192
192
|
|
|
193
193
|
See <https://rmagick.github.io/usage.html> for links to more information.
|
|
194
194
|
|
|
195
|
+
### Threads, fibers and fork
|
|
196
|
+
|
|
197
|
+
RMagick releases the GVL while ImageMagick works, so calls on different images run in parallel.
|
|
198
|
+
|
|
199
|
+
- Use each image from one thread at a time. To work in parallel, give each thread its own images.
|
|
200
|
+
- On Ruby 4.0 and later, a Fiber scheduler with a worker pool, such as `Async::Scheduler.new(worker_pool: IO::Event::WorkerPool.new)`, runs heavy calls on its workers, and the other fibers keep running. While such a call uses an image, using that image from another fiber raises `RuntimeError` ("object is in use by another fiber").
|
|
201
|
+
- Each call in flight holds its images in memory, so memory use grows with the number of workers. Limit the calls that run at once, for example with `Async::Semaphore`.
|
|
202
|
+
- `Thread#raise`, `Timeout` and Ctrl-C reach a thread after the ImageMagick call returns. An exception raised in a `trap` handler can unwind through ImageMagick instead.
|
|
203
|
+
- Do not fork while other threads or workers are running ImageMagick. The child can hang on a lock that they held.
|
|
204
|
+
- After ImageMagick has used OpenMP, a call that uses OpenMP in a forked child can hang. A process that forks after using RMagick should set `MAGICK_THREAD_LIMIT=1`.
|
|
205
|
+
|
|
195
206
|
Things that can go wrong
|
|
196
207
|
------------------------
|
|
197
208
|
|
data/Rakefile
CHANGED
|
@@ -191,6 +191,7 @@ if RUBY_PLATFORM.include?('linux')
|
|
|
191
191
|
|
|
192
192
|
RubyMemcheck.config(
|
|
193
193
|
binary_name: 'RMagick2',
|
|
194
|
+
valgrind_options: RubyMemcheck::Configuration::DEFAULT_VALGRIND_OPTIONS + ['--max-stackframe=65536'],
|
|
194
195
|
valgrind_suppressions_dir: 'spec/valgrind'
|
|
195
196
|
)
|
|
196
197
|
|
data/ext/RMagick/extconf.rb
CHANGED
|
@@ -81,7 +81,7 @@ module RMagick
|
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
def configure_headers
|
|
84
|
-
@headers = %w[assert.h ctype.h stdio.h stdlib.h math.h time.h sys/types.h ruby.h ruby/io.h]
|
|
84
|
+
@headers = %w[assert.h ctype.h stdio.h stdlib.h math.h time.h sys/types.h ruby.h ruby/io.h ruby/fiber/scheduler.h]
|
|
85
85
|
|
|
86
86
|
if have_header('MagickCore/MagickCore.h')
|
|
87
87
|
headers << 'MagickCore/MagickCore.h'
|
|
@@ -275,7 +275,8 @@ module RMagick
|
|
|
275
275
|
|
|
276
276
|
def create_header_file
|
|
277
277
|
ruby_api = [
|
|
278
|
-
'rb_io_path' # Ruby 3.3.0
|
|
278
|
+
'rb_io_path', # Ruby 3.3.0
|
|
279
|
+
'rb_fiber_scheduler_blocking_operation_extract' # Ruby 4.0.0
|
|
279
280
|
]
|
|
280
281
|
memory_api = %w[
|
|
281
282
|
posix_memalign
|
data/ext/RMagick/rmagick.h
CHANGED
|
@@ -104,7 +104,7 @@ extern "C" {
|
|
|
104
104
|
|
|
105
105
|
// Handle Quantum <-> Ruby Numeric object conversion
|
|
106
106
|
#if (MAGICKCORE_QUANTUM_DEPTH == 8 || MAGICKCORE_QUANTUM_DEPTH == 16)
|
|
107
|
-
#define QUANTUM2NUM(q)
|
|
107
|
+
#define QUANTUM2NUM(q) INT2NUM((q)) /**< Quantum -> Ruby Numeric conversion */
|
|
108
108
|
#define NUM2QUANTUM(n) (Quantum)NUM2UINT((n)) /**< Quantum <- Ruby Numeric conversion */
|
|
109
109
|
#elif (MAGICKCORE_QUANTUM_DEPTH == 32)
|
|
110
110
|
#define QUANTUM2NUM(q) UINT2NUM((q)) /**< Quantum -> Ruby Numeric conversion */
|
|
@@ -443,7 +443,7 @@ extern const rb_data_type_t rm_kernel_info_data_type;
|
|
|
443
443
|
*/
|
|
444
444
|
#define C_boolean_to_R_boolean(attr) (attr) ? Qtrue : Qfalse /**< C boolean -> Ruby boolean */
|
|
445
445
|
#define R_boolean_to_C_boolean(attr) (MagickBooleanType)RTEST(attr) /**< C boolean <- Ruby boolean */
|
|
446
|
-
#define C_int_to_R_int(attr)
|
|
446
|
+
#define C_int_to_R_int(attr) INT2NUM(attr) /**< C int -> Ruby int */
|
|
447
447
|
#define R_int_to_C_int(attr) NUM2INT(attr) /**< C int <- Ruby int */
|
|
448
448
|
#define C_long_to_R_long(attr) LONG2NUM(attr) /**< C long -> Ruby long */
|
|
449
449
|
#define R_long_to_C_long(attr) NUM2LONG(attr) /**< C long <- Ruby long */
|
|
@@ -458,7 +458,7 @@ extern const rb_data_type_t rm_kernel_info_data_type;
|
|
|
458
458
|
{\
|
|
459
459
|
klass *ptr;\
|
|
460
460
|
if (rb_obj_is_kind_of(self, Class_Image) == Qtrue) {\
|
|
461
|
-
|
|
461
|
+
rm_check_readable(self); \
|
|
462
462
|
}\
|
|
463
463
|
TypedData_Get_Struct(self, klass, data_type, ptr);\
|
|
464
464
|
return C_##type##_to_R_##type(ptr->attr);\
|
|
@@ -468,7 +468,7 @@ extern const rb_data_type_t rm_kernel_info_data_type;
|
|
|
468
468
|
#define IMPLEMENT_TYPED_ATTR_READERF(klass, attr, field, type, data_type) \
|
|
469
469
|
{\
|
|
470
470
|
klass *ptr;\
|
|
471
|
-
|
|
471
|
+
rm_check_readable(self); \
|
|
472
472
|
TypedData_Get_Struct(self, klass, data_type, ptr);\
|
|
473
473
|
return C_##type##_to_R_##type(ptr->field);\
|
|
474
474
|
}
|
|
@@ -478,10 +478,11 @@ extern const rb_data_type_t rm_kernel_info_data_type;
|
|
|
478
478
|
{\
|
|
479
479
|
klass *ptr;\
|
|
480
480
|
if (rb_obj_is_kind_of(self, Class_Image) == Qtrue) {\
|
|
481
|
-
|
|
481
|
+
rm_check_readable(self); \
|
|
482
482
|
}\
|
|
483
483
|
rb_check_frozen(self);\
|
|
484
484
|
TypedData_Get_Struct(self, klass, data_type, ptr);\
|
|
485
|
+
rm_gvl_check_writable(ptr);\
|
|
485
486
|
ptr->attr = R_##type##_to_C_##type(val);\
|
|
486
487
|
return val;\
|
|
487
488
|
}
|
|
@@ -491,10 +492,11 @@ extern const rb_data_type_t rm_kernel_info_data_type;
|
|
|
491
492
|
{\
|
|
492
493
|
klass *ptr;\
|
|
493
494
|
if (rb_obj_is_kind_of(self, Class_Image) == Qtrue) {\
|
|
494
|
-
|
|
495
|
+
rm_check_readable(self); \
|
|
495
496
|
}\
|
|
496
497
|
rb_check_frozen(self);\
|
|
497
498
|
TypedData_Get_Struct(self, klass, data_type, ptr);\
|
|
499
|
+
rm_gvl_check_writable(ptr);\
|
|
498
500
|
ptr->field = R_##type##_to_C_##type(val);\
|
|
499
501
|
return self;\
|
|
500
502
|
}
|
|
@@ -1157,7 +1159,8 @@ extern size_t rm_strnlen_s(const char *, size_t);
|
|
|
1157
1159
|
extern bool rm_has_file_reference(const char *);
|
|
1158
1160
|
extern void rm_check_ary_len(VALUE, long);
|
|
1159
1161
|
extern VALUE rm_check_ary_type(VALUE ary);
|
|
1160
|
-
extern Image *
|
|
1162
|
+
extern Image *rm_check_readable(VALUE);
|
|
1163
|
+
extern Image *rm_check_writable(VALUE);
|
|
1161
1164
|
extern Image *rm_check_frozen(VALUE);
|
|
1162
1165
|
extern char *rm_str2cstr(VALUE *, size_t *);
|
|
1163
1166
|
extern char *rm_path2cstr(VALUE *, size_t *);
|
|
@@ -1215,4 +1218,6 @@ extern void rm_check_image_exception(Image *, ErrorRetention);
|
|
|
1215
1218
|
|
|
1216
1219
|
} // extern "C"
|
|
1217
1220
|
|
|
1221
|
+
#include "rmagick_gvl.hpp"
|
|
1222
|
+
|
|
1218
1223
|
#endif
|