rmagick 7.1.5 → 7.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0652dce5387352787bef0e59b1548a5c36b6f80a66b8ec9ab4c7f03828f5d0f
4
- data.tar.gz: 6d286a5f5649816c5cf1f821969783fb6ebef9f5a81b4502719f498869f926f9
3
+ metadata.gz: e308c3194e4a4a558c205843e22e8aa4a00435d18945b7d978e9c2a8a0d513c0
4
+ data.tar.gz: e1d208d02935f3fd02cd20cf7331806820b42729898e9a6117ec1fd19fb625e8
5
5
  SHA512:
6
- metadata.gz: 4ab4ce5e26eed8275df1cdc1130da0c5bb717fdca8f472c89b26a5aea37579a17e9bc4d9a34aa0c272a4b26242c03c2acbd9b690484b503ddfdf7220fc075cf2
7
- data.tar.gz: c5ee3eddbed492432ae70f34680a3d9a768fec6ba33bd3c97eca98262f29fd81d2037f56f8e8018ee0afc0a43896ad7186ee5f779da559f9d14ccc05aa28c3cb
6
+ metadata.gz: 8e9921e35f07f25cf2341dfac5d386362be9991ba52fc587a4556692d1fd32f86d02138a2338919a753a90c49450a18af708cb937058ae4db47580528882482d
7
+ data.tar.gz: 2577bf2c6006d4322c0c5a304ea0fcc7b34c1bafcbcba16194d75417acc863c2cdb2ef0140230b7e756c948016477e1ca1c7c96c33fc94d45b76066785f965e0
data/CHANGELOG.md CHANGED
@@ -3,6 +3,31 @@
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.1.6
7
+
8
+ > [!IMPORTANT]
9
+ > A `Magick::KernelInfo` kernel string starting with `@` now raises `ArgumentError`.
10
+ >
11
+ > `KernelInfo.new`, and `Image#morphology` and `#morphology_channel` when given a string kernel, passed the string to ImageMagick, which reads the kernel from the file a string starting with `@` names. A kernel string taken from user input could therefore read any file the process can open: a file holding a kernel definition changed the result image, and with ImageMagick 7 the error told whether the path exists. The message is "the kernel must not name a file with '@'", as for the other values that reject `@`.
12
+
13
+ Breaking Changes
14
+
15
+ * Reject a KernelInfo kernel string beginning with '@' instead of reading that file (#1895)
16
+
17
+ Improvements
18
+
19
+ * Add Magick.resource_usage to read how much of a resource ImageMagick uses (#1880)
20
+ * Add the methods, classes and fields missing from the API reference, and fix the entries that disagreed with the code (#1881, #1883-#1891, #1893, #1897, #1899)
21
+
22
+ Bug Fixes
23
+
24
+ * Fix RBS signatures that disagree with the implementation (#1901)
25
+ * Fix clone of Image, Draw, Pixel, KernelInfo and ImageList rejecting the freeze keyword (#1900)
26
+ * Fix resample and resize sharpening the image at blur 1.0 with ImageMagick 7 (#1898)
27
+ * Fix KernelInfo.builtin leaving out ImageMagick's default arguments (#1896)
28
+ * Fix mutating a frozen Magick::KernelInfo and a leak in KernelInfo#initialize (#1894)
29
+ * Fix TypeMetric#underline_thickness returning the underline position (#1892)
30
+
6
31
  ## RMagick 7.1.5
7
32
 
8
33
  > [!IMPORTANT]
@@ -196,35 +196,24 @@ Magick_init_formats(VALUE klass ATTRIBUTE_UNUSED)
196
196
 
197
197
 
198
198
  /**
199
- * Get/set resource limits. If a limit is specified the old limit is set to the
200
- * new value. Either way the current/old limit is returned.
201
- *
202
- * @overload limit_resource(resource)
203
- * Get resource limits.
204
- * @param resource [String, Symbol] the type of resource
199
+ * Convert the name of a resource to its ResourceType.
205
200
  *
206
- * @overload limit_resource(resource, limit)
207
- * Set resource limits.
208
- * @param resource [String, Symbol] the type of resource
209
- * @param limit [Numeric] the new limit number
201
+ * No Ruby usage (internal function)
210
202
  *
211
- * @return [Numeric] the old limit.
203
+ * @param resource the name of the resource, a String or Symbol
204
+ * @return the resource type, or UndefinedResource for nil or an empty string
212
205
  */
213
- VALUE
214
- Magick_limit_resource(int argc, VALUE *argv, VALUE klass)
206
+ static ResourceType
207
+ resource_type(VALUE resource)
215
208
  {
216
- VALUE resource, limit;
217
209
  ResourceType res = UndefinedResource;
218
210
  char *str;
219
211
  ID id;
220
- MagickSizeType cur_limit;
221
-
222
- rb_scan_args(argc, argv, "11", &resource, &limit);
223
212
 
224
213
  switch (TYPE(resource))
225
214
  {
226
215
  case T_NIL:
227
- return klass;
216
+ break;
228
217
 
229
218
  case T_SYMBOL:
230
219
  id = (ID)SYM2ID(resource);
@@ -262,7 +251,7 @@ Magick_limit_resource(int argc, VALUE *argv, VALUE klass)
262
251
  str = StringValueCStr(resource);
263
252
  if (*str == '\0')
264
253
  {
265
- return klass;
254
+ break;
266
255
  }
267
256
  else if (rm_strcasecmp("area", str) == 0)
268
257
  {
@@ -297,6 +286,40 @@ Magick_limit_resource(int argc, VALUE *argv, VALUE klass)
297
286
 
298
287
  RB_GC_GUARD(resource);
299
288
 
289
+ return res;
290
+ }
291
+
292
+
293
+ /**
294
+ * Get/set resource limits. If a limit is specified the old limit is set to the
295
+ * new value. Either way the current/old limit is returned.
296
+ *
297
+ * @overload limit_resource(resource)
298
+ * Get resource limits.
299
+ * @param resource [String, Symbol] the type of resource
300
+ *
301
+ * @overload limit_resource(resource, limit)
302
+ * Set resource limits.
303
+ * @param resource [String, Symbol] the type of resource
304
+ * @param limit [Numeric] the new limit number
305
+ *
306
+ * @return [Numeric] the old limit.
307
+ */
308
+ VALUE
309
+ Magick_limit_resource(int argc, VALUE *argv, VALUE klass)
310
+ {
311
+ VALUE resource, limit;
312
+ ResourceType res;
313
+ MagickSizeType cur_limit;
314
+
315
+ rb_scan_args(argc, argv, "11", &resource, &limit);
316
+
317
+ res = resource_type(resource);
318
+ if (res == UndefinedResource)
319
+ {
320
+ return klass;
321
+ }
322
+
300
323
  cur_limit = GetMagickResourceLimit(res);
301
324
 
302
325
  if (argc > 1)
@@ -310,6 +333,37 @@ Magick_limit_resource(int argc, VALUE *argv, VALUE klass)
310
333
  }
311
334
 
312
335
 
336
+ /**
337
+ * Get the amount of a resource that ImageMagick is using now. The memory, map
338
+ * and disk resources are in bytes. Most of them are the pixel caches of all
339
+ * images, including those of Image objects that are no longer referenced but
340
+ * have not been garbage collected yet. ImageMagick also counts blobs that it
341
+ * maps into memory and a few internal buffers, but not other memory it
342
+ * allocates.
343
+ *
344
+ * The area resource is the number of pixels of the last pixel cache that was
345
+ * checked against its limit, not a total.
346
+ *
347
+ * @param resource [String, Symbol] the type of resource
348
+ * @return [Numeric] the amount in use
349
+ * @see limit_resource
350
+ * @example
351
+ * GC.start if Magick.resource_usage(:memory) > 1024**3
352
+ */
353
+ VALUE
354
+ Magick_resource_usage(VALUE klass ATTRIBUTE_UNUSED, VALUE resource)
355
+ {
356
+ ResourceType res = resource_type(resource);
357
+
358
+ if (res == UndefinedResource)
359
+ {
360
+ rb_raise(rb_eArgError, "no resource given");
361
+ }
362
+
363
+ return ULL2NUM(GetMagickResource(res));
364
+ }
365
+
366
+
313
367
  /**
314
368
  * Set the amount of free memory allocated for the pixel cache. Once this
315
369
  * threshold is exceeded, all subsequent pixel cache operations are to/from
@@ -555,6 +555,7 @@ extern VALUE Magick_colors(VALUE);
555
555
  extern VALUE Magick_fonts(VALUE);
556
556
  extern VALUE Magick_init_formats(VALUE);
557
557
  extern VALUE Magick_limit_resource(int, VALUE *, VALUE);
558
+ extern VALUE Magick_resource_usage(VALUE, VALUE);
558
559
  extern VALUE Magick_set_cache_threshold(VALUE, VALUE);
559
560
  extern VALUE Magick_set_log_event_mask(int, VALUE *, VALUE);
560
561
  extern VALUE Magick_set_log_format(VALUE, VALUE);
@@ -587,10 +588,8 @@ ATTR_WRITER(Draw, tile)
587
588
  ATTR_WRITER(Draw, undercolor)
588
589
  extern VALUE Draw_alloc(VALUE);
589
590
  extern VALUE Draw_annotate(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
590
- extern VALUE Draw_clone(VALUE);
591
591
  extern VALUE Draw_composite(int, VALUE *, VALUE);
592
592
  extern VALUE Draw_draw(VALUE, VALUE);
593
- extern VALUE Draw_dup(VALUE);
594
593
  extern VALUE Draw_get_multiline_type_metrics(int, VALUE *, VALUE);
595
594
  extern VALUE Draw_get_type_metrics(int, VALUE *, VALUE);
596
595
  extern VALUE Draw_init_copy(VALUE, VALUE);
@@ -725,7 +724,7 @@ extern VALUE KernelInfo_initialize(VALUE, VALUE);
725
724
  extern VALUE KernelInfo_unity_add(VALUE, VALUE);
726
725
  extern VALUE KernelInfo_scale(VALUE, VALUE, VALUE);
727
726
  extern VALUE KernelInfo_scale_geometry(VALUE, VALUE);
728
- extern VALUE KernelInfo_clone(VALUE);
727
+ extern VALUE KernelInfo_init_copy(VALUE, VALUE);
729
728
 
730
729
  extern VALUE KernelInfo_builtin(VALUE, VALUE, VALUE);
731
730
 
@@ -840,7 +839,6 @@ extern VALUE Image_channel_mean(int, VALUE *, VALUE);
840
839
  extern VALUE Image_channel_entropy(int, VALUE *, VALUE);
841
840
  extern VALUE Image_charcoal(int, VALUE *, VALUE);
842
841
  extern VALUE Image_chop(VALUE, VALUE, VALUE, VALUE, VALUE);
843
- extern VALUE Image_clone(VALUE);
844
842
  extern VALUE Image_clut_channel(int, VALUE *, VALUE);
845
843
  extern VALUE Image_color_flood_fill(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
846
844
  extern VALUE Image_color_histogram(VALUE);
@@ -882,7 +880,6 @@ extern VALUE Image_dissolve(int, VALUE *, VALUE);
882
880
  extern VALUE Image_distort(int, VALUE *, VALUE);
883
881
  extern VALUE Image_distortion_channel(int, VALUE *, VALUE);
884
882
  extern VALUE Image__dump(VALUE, VALUE);
885
- extern VALUE Image_dup(VALUE);
886
883
  extern VALUE Image_each_profile(VALUE);
887
884
  extern VALUE Image_edge(int, VALUE *, VALUE);
888
885
  extern VALUE Image_emboss(int, VALUE *, VALUE);
@@ -1053,8 +1050,6 @@ ATTR_ACCESSOR(Pixel, yellow)
1053
1050
  ATTR_ACCESSOR(Pixel, black)
1054
1051
  extern VALUE Pixel_alloc(VALUE);
1055
1052
  extern VALUE Pixel_case_eq(VALUE, VALUE);
1056
- extern VALUE Pixel_clone(VALUE);
1057
- extern VALUE Pixel_dup(VALUE);
1058
1053
  extern VALUE Pixel_eql_q(VALUE, VALUE);
1059
1054
  extern VALUE Pixel_fcmp(int, VALUE *, VALUE);
1060
1055
  extern VALUE Pixel_from_color(VALUE, VALUE);
@@ -1010,26 +1010,6 @@ VALUE Draw_annotate(
1010
1010
  }
1011
1011
 
1012
1012
 
1013
- /**
1014
- * Clones this object.
1015
- *
1016
- * @return [Magick::Draw] the cloned object
1017
- */
1018
- VALUE
1019
- Draw_clone(VALUE self)
1020
- {
1021
- VALUE clone;
1022
-
1023
- clone = Draw_dup(self);
1024
- if (OBJ_FROZEN(self))
1025
- {
1026
- OBJ_FREEZE(clone);
1027
- }
1028
-
1029
- RB_GC_GUARD(clone);
1030
-
1031
- return clone;
1032
- }
1033
1013
 
1034
1014
 
1035
1015
  /**
@@ -1172,26 +1152,6 @@ Draw_draw(VALUE self, VALUE image_arg)
1172
1152
  }
1173
1153
 
1174
1154
 
1175
- /**
1176
- * Duplicate a Draw object.
1177
- *
1178
- * - Constructs a new Draw object, then calls initialize_copy.
1179
- *
1180
- * @return [Magick::Draw] the duplicated object
1181
- */
1182
- VALUE
1183
- Draw_dup(VALUE self)
1184
- {
1185
- Draw *draw;
1186
- VALUE dup;
1187
-
1188
- draw = ALLOC(Draw);
1189
- memset(draw, 0, sizeof(Draw));
1190
- dup = TypedData_Wrap_Struct(CLASS_OF(self), &rm_draw_data_type, draw);
1191
- RB_GC_GUARD(dup);
1192
-
1193
- return rb_funcall(dup, rm_ID_initialize_copy, 1, self);
1194
- }
1195
1155
 
1196
1156
 
1197
1157
  /**
@@ -2714,27 +2714,6 @@ Image_chromaticity_eq(VALUE self, VALUE chroma)
2714
2714
  }
2715
2715
 
2716
2716
 
2717
- /**
2718
- * Same as {Magick::Image#dup} except the frozen state of the original is propagated to the new
2719
- * copy.
2720
- *
2721
- * @return [Magick::Image] a clone of this object
2722
- */
2723
- VALUE
2724
- Image_clone(VALUE self)
2725
- {
2726
- VALUE clone;
2727
-
2728
- clone = Image_dup(self);
2729
- if (OBJ_FROZEN(self))
2730
- {
2731
- OBJ_FREEZE(clone);
2732
- }
2733
-
2734
- RB_GC_GUARD(clone);
2735
-
2736
- return clone;
2737
- }
2738
2717
 
2739
2718
 
2740
2719
  /**
@@ -3897,7 +3876,8 @@ composite_channel(int bang, int argc, VALUE *argv, VALUE self)
3897
3876
 
3898
3877
 
3899
3878
  /**
3900
- * Composite the source over the destination image channel as dictated by the affine transform.
3879
+ * Composite the source over the destination image, changing only the specified channels of the
3880
+ * destination. The arguments before the channels are the same as those of {Image#composite}.
3901
3881
  *
3902
3882
  * @overload composite_channel(image, x_off, y_off, composite_op, channel = Magick::AllChannels)
3903
3883
  * @param image [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
@@ -3970,8 +3950,8 @@ Image_composite_channel(int argc, VALUE *argv, VALUE self)
3970
3950
 
3971
3951
 
3972
3952
  /**
3973
- * Composite the source over the destination image channel as dictated by the affine transform.
3974
- * In-place form of {Image#composite_channel}.
3953
+ * Composite the source over the destination image, changing only the specified channels of the
3954
+ * destination. In-place form of {Image#composite_channel}.
3975
3955
  *
3976
3956
  * @overload composite_channel!(image, x_off, y_off, composite_op, channel = Magick::AllChannels)
3977
3957
  * @param image [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
@@ -4033,7 +4013,7 @@ Image_composite_channel(int argc, VALUE *argv, VALUE self)
4033
4013
  * @param composite_op [Magick::CompositeOperator] the composite operator
4034
4014
  * @param *channels [Magick::ChannelType] one or more ChannelType arguments.
4035
4015
  *
4036
- * @return [Magick::Image] a new image
4016
+ * @return [Magick::Image] self
4037
4017
  * @see Image#composite_channel
4038
4018
  * @see Image#composite!
4039
4019
  */
@@ -6222,22 +6202,6 @@ Image__dump(VALUE self, VALUE depth ATTRIBUTE_UNUSED)
6222
6202
  }
6223
6203
 
6224
6204
 
6225
- /**
6226
- * Duplicates an image.
6227
- *
6228
- * @return [Magick::Image] a new image
6229
- */
6230
- VALUE
6231
- Image_dup(VALUE self)
6232
- {
6233
- VALUE dup;
6234
-
6235
- rm_check_destroyed(self);
6236
- dup = TypedData_Wrap_Struct(CLASS_OF(self), &rm_image_data_type, NULL);
6237
- RB_GC_GUARD(dup);
6238
-
6239
- return rb_funcall(dup, rm_ID_initialize_copy, 1, self);
6240
- }
6241
6205
 
6242
6206
 
6243
6207
  /**
@@ -8697,11 +8661,12 @@ Image_level2(int argc, VALUE *argv, VALUE self)
8697
8661
  /**
8698
8662
  * Similar to {Image#level2} but applies to a single channel only.
8699
8663
  *
8700
- * @overload level_channel(aChannelType, black = 0.0, white = 1.0, gamma = Magick::QuantumRange)
8664
+ * @overload level_channel(aChannelType, black = 0.0, white = Magick::QuantumRange - black, gamma = 1.0)
8701
8665
  * @param aChannelType [Magick::ChannelType] A ChannelType value.
8702
8666
  * @param black [Numeric] A black point level in the range 0..QuantumRange.
8703
8667
  * @param white [Numeric] A white point level in the range 0..QuantumRange.
8704
- * @param gamma [Numeric] A gamma correction in the range 0.0 - 10.0.
8668
+ * @param gamma [Numeric] A gamma correction. Unlike with {Image#level}, a value greater than 10.0 is
8669
+ * used as given.
8705
8670
  * @return [Magick::Image] a new image
8706
8671
  * @see Image#level2
8707
8672
  */
@@ -12065,35 +12030,71 @@ Image_rendering_intent_eq(VALUE self, VALUE ri)
12065
12030
 
12066
12031
  #if defined(IMAGEMAGICK_7)
12067
12032
  /**
12068
- * Create new blurred image.
12033
+ * Return the image to resize or resample with the given blur factor.
12034
+ *
12035
+ * ImageMagick 7 dropped the blur argument of ResizeImage() and ResampleImage(). Their filter
12036
+ * reads the factor from the "filter:blur" artifact instead, as ImageMagick 6 did on top of the
12037
+ * argument, so the factor is set there, multiplied by any "filter:blur" the image already has.
12038
+ * A factor of 1.0 leaves the filter as it is.
12069
12039
  *
12070
12040
  * No Ruby usage (internal function)
12071
12041
  *
12072
12042
  * @param image the image
12073
- * @param blur the blur
12074
- * @return NULL if not apply blur, otherwise a new image
12043
+ * @param blur the blur factor: > 1.0 blurs and < 1.0 sharpens
12044
+ * @return the image itself when blur is 1.0, otherwise a clone that shares its pixels and has
12045
+ * the artifact set, which the caller destroys
12075
12046
  */
12076
12047
  static Image*
12077
- blurred_image(Image* image, double blur)
12048
+ image_with_filter_blur(Image* image, double blur)
12078
12049
  {
12079
- ExceptionInfo *exception;
12080
- Image *new_image;
12050
+ Image *clone;
12051
+ const char *artifact;
12052
+ char value[MaxTextExtent];
12081
12053
 
12082
- exception = AcquireExceptionInfo();
12083
- if (blur > 1.0)
12054
+ if (blur == 1.0)
12084
12055
  {
12085
- GVL_STRUCT_TYPE(BlurImage) args = { image, blur, blur, exception };
12086
- new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(BlurImage), &args);
12056
+ return image;
12087
12057
  }
12088
- else
12058
+
12059
+ artifact = GetImageArtifact(image, "filter:blur");
12060
+ if (artifact)
12089
12061
  {
12090
- GVL_STRUCT_TYPE(SharpenImage) args = { image, blur, blur, exception };
12091
- new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(SharpenImage), &args);
12062
+ blur *= InterpretLocaleValue(artifact, (char **)NULL);
12092
12063
  }
12093
- rm_check_exception(exception, new_image, DestroyOnError);
12094
- DestroyExceptionInfo(exception);
12064
+ snprintf(value, sizeof(value), "%.17g", blur);
12095
12065
 
12096
- return new_image;
12066
+ clone = rm_clone_image(image);
12067
+ if (!SetImageArtifact(clone, "filter:blur", value))
12068
+ {
12069
+ DestroyImage(clone);
12070
+ rb_raise(rb_eNoMemError, "not enough memory to continue");
12071
+ }
12072
+ return clone;
12073
+ }
12074
+
12075
+
12076
+ /**
12077
+ * Give the result of a resize or resample the "filter:blur" artifact of the original image, or
12078
+ * none, instead of the one image_with_filter_blur() set on the image it was made from.
12079
+ *
12080
+ * No Ruby usage (internal function)
12081
+ *
12082
+ * @param result the result image
12083
+ * @param image the original image
12084
+ */
12085
+ static void
12086
+ restore_filter_blur(Image* result, Image* image)
12087
+ {
12088
+ const char *artifact = GetImageArtifact(image, "filter:blur");
12089
+
12090
+ if (artifact)
12091
+ {
12092
+ (void) SetImageArtifact(result, "filter:blur", artifact);
12093
+ }
12094
+ else
12095
+ {
12096
+ (void) DeleteImageArtifact(result, "filter:blur");
12097
+ }
12097
12098
  }
12098
12099
  #endif
12099
12100
 
@@ -12178,12 +12179,22 @@ resample(int bang, int argc, VALUE *argv, VALUE self)
12178
12179
  break;
12179
12180
  }
12180
12181
 
12182
+ #if defined(IMAGEMAGICK_7)
12183
+ // Before AcquireExceptionInfo(), since it can raise
12184
+ Image *source = image_with_filter_blur(image, blur);
12185
+ #endif
12181
12186
  exception = AcquireExceptionInfo();
12182
12187
  #if defined(IMAGEMAGICK_7)
12183
- Image *preprocess = blurred_image(image, blur);
12184
- GVL_STRUCT_TYPE(ResampleImage) args = { preprocess, x_resolution, y_resolution, filter, exception };
12188
+ GVL_STRUCT_TYPE(ResampleImage) args = { source, x_resolution, y_resolution, filter, exception };
12185
12189
  new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ResampleImage), &args);
12186
- DestroyImage(preprocess);
12190
+ if (source != image)
12191
+ {
12192
+ if (new_image)
12193
+ {
12194
+ restore_filter_blur(new_image, image);
12195
+ }
12196
+ DestroyImage(source);
12197
+ }
12187
12198
  #else
12188
12199
  GVL_STRUCT_TYPE(ResampleImage) args = { image, x_resolution, y_resolution, filter, blur, exception };
12189
12200
  new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ResampleImage), &args);
@@ -12213,12 +12224,12 @@ resample(int bang, int argc, VALUE *argv, VALUE self)
12213
12224
  * the original resolution of the image must be specified via the density attribute prior to
12214
12225
  * specifying the resample resolution.
12215
12226
  *
12216
- * @overload resample(x_resolution = 72.0, y_resolution = 72.0, filter = self.filter, blur = self.blur)
12227
+ * @overload resample(x_resolution = 72.0, y_resolution = x_resolution, filter = self.filter, blur = 1.0)
12217
12228
  * @param x_resolution [Numeric] the target horizontal resolution.
12218
12229
  * @param y_resolution [Numeric] the target vertical resolution.
12219
12230
  * @param filter [Magick::FilterType] the filter type
12220
- * @param blur [Numeric] the blur size
12221
- * @return [Magick] a new image
12231
+ * @param blur [Numeric] the blur factor of the filter: > 1.0 blurs and < 1.0 sharpens
12232
+ * @return [Magick::Image] a new image
12222
12233
  * @see Image#resample!
12223
12234
  */
12224
12235
  VALUE
@@ -12233,12 +12244,12 @@ Image_resample(int argc, VALUE *argv, VALUE self)
12233
12244
  * Resample image to specified horizontal resolution, vertical resolution, filter and blur factor.
12234
12245
  * In-place form of {Image#resample}.
12235
12246
  *
12236
- * @overload resample!(x_resolution = 72.0, y_resolution = 72.0, filter = self.filter, blur = self.blur)
12247
+ * @overload resample!(x_resolution = 72.0, y_resolution = x_resolution, filter = self.filter, blur = 1.0)
12237
12248
  * @param x_resolution [Numeric] the target horizontal resolution.
12238
12249
  * @param y_resolution [Numeric] the target vertical resolution.
12239
12250
  * @param filter [Magick::FilterType] the filter type
12240
- * @param blur [Numeric] the blur size
12241
- * @return [Magick] a new image
12251
+ * @param blur [Numeric] the blur factor of the filter: > 1.0 blurs and < 1.0 sharpens
12252
+ * @return [Magick::Image] self
12242
12253
  * @see Image#resample
12243
12254
  */
12244
12255
  VALUE
@@ -12319,14 +12330,21 @@ resize(int bang, int argc, VALUE *argv, VALUE self)
12319
12330
  break;
12320
12331
  }
12321
12332
 
12333
+ #if defined(IMAGEMAGICK_7)
12334
+ // Before AcquireExceptionInfo(), since it can raise
12335
+ Image *source = image_with_filter_blur(image, blur);
12336
+ #endif
12322
12337
  exception = AcquireExceptionInfo();
12323
12338
  #if defined(IMAGEMAGICK_7)
12324
- Image *preprocess = (argc == 4) ? blurred_image(image, blur) : image;
12325
- GVL_STRUCT_TYPE(ResizeImage) args = { preprocess, columns, rows, filter, exception };
12339
+ GVL_STRUCT_TYPE(ResizeImage) args = { source, columns, rows, filter, exception };
12326
12340
  new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ResizeImage), &args);
12327
- if (argc == 4)
12341
+ if (source != image)
12328
12342
  {
12329
- DestroyImage(preprocess);
12343
+ if (new_image)
12344
+ {
12345
+ restore_filter_blur(new_image, image);
12346
+ }
12347
+ DestroyImage(source);
12330
12348
  }
12331
12349
  #else
12332
12350
  GVL_STRUCT_TYPE(ResizeImage) args = { image, columns, rows, filter, blur, exception };
@@ -12359,7 +12377,7 @@ resize(int bang, int argc, VALUE *argv, VALUE self)
12359
12377
  * @param cols [Numeric] The desired width
12360
12378
  * @param rows [Numeric] The desired height.
12361
12379
  * @param filter [Magick::FilterType] the filter type
12362
- * @param blur [Numeric] the blur size
12380
+ * @param blur [Numeric] the blur factor of the filter: > 1.0 blurs and < 1.0 sharpens
12363
12381
  *
12364
12382
  * @return [Magick::Image] a new image
12365
12383
  * @see Image#resize!
@@ -12385,7 +12403,7 @@ Image_resize(int argc, VALUE *argv, VALUE self)
12385
12403
  * @param cols [Numeric] The desired width
12386
12404
  * @param rows [Numeric] The desired height.
12387
12405
  * @param filter [Magick::FilterType] the filter type
12388
- * @param blur [Numeric] the blur size
12406
+ * @param blur [Numeric] the blur factor of the filter: > 1.0 blurs and < 1.0 sharpens
12389
12407
  *
12390
12408
  * @return [Magick::Image] a new image
12391
12409
  * @see Image#resize!
@@ -14603,8 +14621,8 @@ Image_ticks_per_second_eq(VALUE self, VALUE tps)
14603
14621
  * @param red_alpha [Numeric] the red value
14604
14622
  * @param green_alpha [Numeric] the green value
14605
14623
  * @param blue_alpha [Numeric] the blue value
14606
- * @param alpha_alpha [Numeric] the alpha value
14607
- * @return a new image
14624
+ * @param alpha_alpha [Numeric] accepted but ignored: TintImage leaves the alpha channel unchanged
14625
+ * @return [Magick::Image] a new image
14608
14626
  */
14609
14627
  VALUE
14610
14628
  Image_tint(int argc, VALUE *argv, VALUE self)
@@ -15255,7 +15273,8 @@ VALUE Image_image_type_eq(VALUE self, VALUE image_type)
15255
15273
 
15256
15274
 
15257
15275
  /**
15258
- * Removes an artifact from the image and returns its value.
15276
+ * Removes an artifact from the image. The same as {Image#define} with a nil value, except that it
15277
+ * returns self and that the name must be a String.
15259
15278
  *
15260
15279
  * @param artifact [String] the artifact
15261
15280
  * @return [Magick::Image] self
@@ -82,14 +82,28 @@ KernelInfo_alloc(VALUE klass)
82
82
  /**
83
83
  * KernelInfo object constructor
84
84
  *
85
+ * - Calling it again on an initialized object replaces its kernel and destroys the old one.
86
+ * - A kernel string whose first non-blank character is '@' is rejected: ImageMagick would read the
87
+ * kernel from the file it names. A string that contains a %[fx:@...], %[hex:@...] or
88
+ * %[pixel:@...] escape is rejected as well, by the same check as the other options that name files.
89
+ *
85
90
  * @param kernel_string [String] kernel info string representation to be parsed
86
91
  * @return [Magick::KernelInfo] self
92
+ * @raise [FrozenError] if the object is frozen
93
+ * @raise [ArgumentError] if the kernel string names a file with '@'
87
94
  */
88
95
  VALUE
89
96
  KernelInfo_initialize(VALUE self, VALUE kernel_string)
90
97
  {
91
- KernelInfo *kernel;
92
- char *string = StringValueCStr(kernel_string);
98
+ KernelInfo *kernel, *old_kernel;
99
+ char *string;
100
+
101
+ rb_check_frozen(self);
102
+ string = StringValueCStr(kernel_string);
103
+ if (rm_has_file_reference(string))
104
+ {
105
+ rb_raise(rb_eArgError, "the kernel must not name a file with '@'");
106
+ }
93
107
 
94
108
  #if defined(IMAGEMAGICK_7)
95
109
  ExceptionInfo *exception;
@@ -113,7 +127,12 @@ KernelInfo_initialize(VALUE self, VALUE kernel_string)
113
127
  rb_raise(rb_eRuntimeError, "failed to parse kernel string");
114
128
  }
115
129
 
130
+ old_kernel = (KernelInfo *)DATA_PTR(self);
116
131
  DATA_PTR(self) = kernel;
132
+ if (old_kernel)
133
+ {
134
+ DestroyKernelInfo(old_kernel);
135
+ }
117
136
 
118
137
  return self;
119
138
  }
@@ -145,6 +164,24 @@ get_kernel_info(VALUE self)
145
164
  }
146
165
 
147
166
 
167
+ /**
168
+ * Return the KernelInfo struct of an object that is about to be changed,
169
+ * raising FrozenError if the object is frozen.
170
+ *
171
+ * No Ruby usage (internal function)
172
+ *
173
+ * @param self the KernelInfo object
174
+ * @return the KernelInfo struct
175
+ * @throw FrozenError if the object is frozen
176
+ */
177
+ static KernelInfo *
178
+ get_unfrozen_kernel_info(VALUE self)
179
+ {
180
+ rb_check_frozen(self);
181
+ return get_kernel_info(self);
182
+ }
183
+
184
+
148
185
  /**
149
186
  * Adds a given amount of the 'Unity' Convolution Kernel to the given pre-scaled and normalized Kernel.
150
187
  *
@@ -153,7 +190,7 @@ get_kernel_info(VALUE self)
153
190
  VALUE
154
191
  KernelInfo_unity_add(VALUE self, VALUE scale)
155
192
  {
156
- GVL_STRUCT_TYPE(UnityAddKernelInfo) args = { get_kernel_info(self), NUM2DBL(scale) };
193
+ GVL_STRUCT_TYPE(UnityAddKernelInfo) args = { get_unfrozen_kernel_info(self), NUM2DBL(scale) };
157
194
  CALL_FUNC_WITHOUT_GVL(GVL_FUNC(UnityAddKernelInfo), &args);
158
195
  return Qnil;
159
196
  }
@@ -164,8 +201,10 @@ KernelInfo_unity_add(VALUE self, VALUE scale)
164
201
  * of the sum of the kernel values (as per given flags).
165
202
  *
166
203
  * @param scale [Numeric] scale to use
167
- * @param flags [Magick::GeometryFlags] one of Magick::NormalizeValue, Magick::CorrelateNormalizeValue,
168
- * and/or Magick::PercentValue
204
+ * @param flags [Magick::GeometryFlags] Magick::NoValue, Magick::NormalizeValue or
205
+ * Magick::CorrelateNormalizeValue. ScaleKernelInfo ignores the other values, including
206
+ * Magick::PercentValue; use {KernelInfo#scale_geometry} for a percentage.
207
+ * @return [nil]
169
208
  */
170
209
  VALUE
171
210
  KernelInfo_scale(VALUE self, VALUE scale, VALUE flags)
@@ -174,7 +213,7 @@ KernelInfo_scale(VALUE self, VALUE scale, VALUE flags)
174
213
 
175
214
  VALUE_TO_ENUM(flags, geoflags, GeometryFlags);
176
215
 
177
- GVL_STRUCT_TYPE(ScaleKernelInfo) args = { get_kernel_info(self), NUM2DBL(scale), geoflags };
216
+ GVL_STRUCT_TYPE(ScaleKernelInfo) args = { get_unfrozen_kernel_info(self), NUM2DBL(scale), geoflags };
178
217
  CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ScaleKernelInfo), &args);
179
218
  return Qnil;
180
219
  }
@@ -190,7 +229,7 @@ KernelInfo_scale_geometry(VALUE self, VALUE geometry)
190
229
  {
191
230
  char *geom = StringValueCStr(geometry);
192
231
 
193
- GVL_STRUCT_TYPE(ScaleGeometryKernelInfo) args = { get_kernel_info(self), geom };
232
+ GVL_STRUCT_TYPE(ScaleGeometryKernelInfo) args = { get_unfrozen_kernel_info(self), geom };
194
233
  CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ScaleGeometryKernelInfo), &args);
195
234
 
196
235
  RB_GC_GUARD(geometry);
@@ -199,19 +238,32 @@ KernelInfo_scale_geometry(VALUE self, VALUE geometry)
199
238
  }
200
239
 
201
240
  /**
202
- * Creates a new clone of the object so that it can be modified without affecting the original.
241
+ * Initialize a copy made by clone or dup with a copy of the kernel of the original.
203
242
  *
204
- * @return [Magick::KernelInfo] new KernelInfo object
243
+ * @param orig the original object
244
+ * @return [Magick::KernelInfo] self
245
+ * @raise [FrozenError] if the object is frozen
205
246
  */
206
247
  VALUE
207
- KernelInfo_clone(VALUE self)
248
+ KernelInfo_init_copy(VALUE self, VALUE orig)
208
249
  {
209
- KernelInfo *kernel = CloneKernelInfo(get_kernel_info(self));
250
+ KernelInfo *kernel, *old_kernel;
251
+
252
+ rb_check_frozen(self);
253
+ kernel = CloneKernelInfo(get_kernel_info(orig));
210
254
  if (!kernel)
211
255
  {
212
256
  rb_raise(rb_eNoMemError, "not enough memory to continue");
213
257
  }
214
- return TypedData_Wrap_Struct(Class_KernelInfo, &rm_kernel_info_data_type, kernel);
258
+
259
+ old_kernel = (KernelInfo *)DATA_PTR(self);
260
+ DATA_PTR(self) = kernel;
261
+ if (old_kernel)
262
+ {
263
+ DestroyKernelInfo(old_kernel);
264
+ }
265
+
266
+ return self;
215
267
  }
216
268
 
217
269
  /**
@@ -219,6 +271,9 @@ KernelInfo_clone(VALUE self)
219
271
  * kernels used for special purposes such as gaussian blurring, skeleton
220
272
  * pruning, and edge distance determination.
221
273
  *
274
+ * - The kernel is parsed from "name:geometry" as KernelInfo.new does, so the
275
+ * arguments that are left out get ImageMagick's defaults.
276
+ *
222
277
  * @param what [Magick::KernelInfoType] kernel one of Magick::KernelInfoType enums
223
278
  * @param geometry [String] geometry to pass to default kernel
224
279
  * @return [Magick::KernelInfo] a new KernelInfo object
@@ -229,21 +284,32 @@ KernelInfo_builtin(VALUE self, VALUE what, VALUE geometry)
229
284
  KernelInfo *kernel;
230
285
  KernelInfoType kernel_type;
231
286
  GeometryInfo info;
232
- const char *geom_str;
287
+ const char *geom_str, *name;
288
+ char kernel_string[MaxTextExtent];
289
+ int length;
233
290
  #if defined(IMAGEMAGICK_7)
234
291
  ExceptionInfo *exception;
235
292
  #endif
236
293
 
237
294
  VALUE_TO_ENUM(what, kernel_type, KernelInfoType);
238
295
  geom_str = StringValueCStr(geometry);
239
- if (ParseGeometry(geom_str, &info) == NoValue && *geom_str)
296
+ // AcquireKernelInfo() reads a list of kernels separated by ';'. ParseGeometry() rejects such a
297
+ // string today, but builtin makes one built-in kernel, so reject ';' explicitly as well.
298
+ if ((ParseGeometry(geom_str, &info) == NoValue && *geom_str) || strchr(geom_str, ';'))
240
299
  {
241
300
  rb_raise(rb_eArgError, "invalid geometry string");
242
301
  }
243
302
 
303
+ name = CommandOptionToMnemonic(MagickKernelOptions, kernel_type);
304
+ length = snprintf(kernel_string, sizeof(kernel_string), "%s:%s", name, geom_str);
305
+ if (length < 0 || (size_t)length >= sizeof(kernel_string))
306
+ {
307
+ rb_raise(rb_eArgError, "geometry string too long");
308
+ }
309
+
244
310
  #if defined(IMAGEMAGICK_7)
245
311
  exception = AcquireExceptionInfo();
246
- kernel = AcquireKernelBuiltIn(kernel_type, &info, exception);
312
+ kernel = AcquireKernelInfo(kernel_string, exception);
247
313
  if (rm_should_raise_exception(exception, DestroyExceptionRetention))
248
314
  {
249
315
  if (kernel != (KernelInfo *) NULL)
@@ -253,9 +319,11 @@ KernelInfo_builtin(VALUE self, VALUE what, VALUE geometry)
253
319
  rm_raise_exception(exception);
254
320
  }
255
321
  #else
256
- kernel = AcquireKernelBuiltIn(kernel_type, &info);
322
+ kernel = AcquireKernelInfo(kernel_string);
257
323
  #endif
258
324
 
325
+ RB_GC_GUARD(geometry);
326
+
259
327
  if (!kernel)
260
328
  {
261
329
  rb_raise(rb_eRuntimeError, "failed to acquire builtin kernel");
@@ -267,6 +267,7 @@ Init_RMagick2(void)
267
267
  rb_define_module_function(Module_Magick, "fonts", RUBY_METHOD_FUNC(Magick_fonts), 0);
268
268
  rb_define_module_function(Module_Magick, "init_formats", RUBY_METHOD_FUNC(Magick_init_formats), 0);
269
269
  rb_define_module_function(Module_Magick, "limit_resource", RUBY_METHOD_FUNC(Magick_limit_resource), -1);
270
+ rb_define_module_function(Module_Magick, "resource_usage", RUBY_METHOD_FUNC(Magick_resource_usage), 1);
270
271
  rb_define_module_function(Module_Magick, "set_cache_threshold", RUBY_METHOD_FUNC(Magick_set_cache_threshold), 1);
271
272
  rb_define_module_function(Module_Magick, "set_log_event_mask", RUBY_METHOD_FUNC(Magick_set_log_event_mask), -1);
272
273
  rb_define_module_function(Module_Magick, "set_log_format", RUBY_METHOD_FUNC(Magick_set_log_format), 1);
@@ -436,7 +437,6 @@ Init_RMagick2(void)
436
437
  rb_define_method(Class_Image, "charcoal", RUBY_METHOD_FUNC(Image_charcoal), -1);
437
438
  rb_define_method(Class_Image, "chop", RUBY_METHOD_FUNC(Image_chop), 4);
438
439
  rb_define_method(Class_Image, "clut_channel", RUBY_METHOD_FUNC(Image_clut_channel), -1);
439
- rb_define_method(Class_Image, "clone", RUBY_METHOD_FUNC(Image_clone), 0);
440
440
  rb_define_method(Class_Image, "color_flood_fill", RUBY_METHOD_FUNC(Image_color_flood_fill), 5);
441
441
  rb_define_method(Class_Image, "color_histogram", RUBY_METHOD_FUNC(Image_color_histogram), 0);
442
442
  rb_define_method(Class_Image, "colorize", RUBY_METHOD_FUNC(Image_colorize), -1);
@@ -476,7 +476,6 @@ Init_RMagick2(void)
476
476
  rb_define_method(Class_Image, "distort", RUBY_METHOD_FUNC(Image_distort), -1);
477
477
  rb_define_method(Class_Image, "distortion_channel", RUBY_METHOD_FUNC(Image_distortion_channel), -1);
478
478
  rb_define_method(Class_Image, "_dump", RUBY_METHOD_FUNC(Image__dump), 1);
479
- rb_define_method(Class_Image, "dup", RUBY_METHOD_FUNC(Image_dup), 0);
480
479
  rb_define_method(Class_Image, "each_profile", RUBY_METHOD_FUNC(Image_each_profile), 0);
481
480
  rb_define_method(Class_Image, "edge", RUBY_METHOD_FUNC(Image_edge), -1);
482
481
  rb_define_method(Class_Image, "emboss", RUBY_METHOD_FUNC(Image_emboss), -1);
@@ -678,10 +677,8 @@ Init_RMagick2(void)
678
677
  rb_include_module(Class_Draw, Module_DrawAttribute);
679
678
 
680
679
  rb_define_method(Class_Draw, "annotate", RUBY_METHOD_FUNC(Draw_annotate), 6);
681
- rb_define_method(Class_Draw, "clone", RUBY_METHOD_FUNC(Draw_clone), 0);
682
680
  rb_define_method(Class_Draw, "composite", RUBY_METHOD_FUNC(Draw_composite), -1);
683
681
  rb_define_method(Class_Draw, "draw", RUBY_METHOD_FUNC(Draw_draw), 1);
684
- rb_define_method(Class_Draw, "dup", RUBY_METHOD_FUNC(Draw_dup), 0);
685
682
  rb_define_method(Class_Draw, "get_type_metrics", RUBY_METHOD_FUNC(Draw_get_type_metrics), -1);
686
683
  rb_define_method(Class_Draw, "get_multiline_type_metrics", RUBY_METHOD_FUNC(Draw_get_multiline_type_metrics), -1);
687
684
  rb_define_method(Class_Draw, "initialize", RUBY_METHOD_FUNC(Draw_initialize), 0);
@@ -747,8 +744,6 @@ Init_RMagick2(void)
747
744
  rb_define_method(Class_Pixel, "eql?", RUBY_METHOD_FUNC(Pixel_eql_q), 1);
748
745
  rb_define_method(Class_Pixel, "initialize", RUBY_METHOD_FUNC(Pixel_initialize), -1);
749
746
  rb_define_method(Class_Pixel, "initialize_copy", RUBY_METHOD_FUNC(Pixel_init_copy), 1);
750
- rb_define_method(Class_Pixel, "clone", RUBY_METHOD_FUNC(Pixel_clone), 0);
751
- rb_define_method(Class_Pixel, "dup", RUBY_METHOD_FUNC(Pixel_dup), 0);
752
747
  rb_define_method(Class_Pixel, "fcmp", RUBY_METHOD_FUNC(Pixel_fcmp), -1);
753
748
  rb_define_method(Class_Pixel, "hash", RUBY_METHOD_FUNC(Pixel_hash), 0);
754
749
  rb_define_method(Class_Pixel, "intensity", RUBY_METHOD_FUNC(Pixel_intensity), 0);
@@ -907,8 +902,7 @@ Init_RMagick2(void)
907
902
  rb_define_method(Class_KernelInfo, "unity_add", RUBY_METHOD_FUNC(KernelInfo_unity_add), 1);
908
903
  rb_define_method(Class_KernelInfo, "scale", RUBY_METHOD_FUNC(KernelInfo_scale), 2);
909
904
  rb_define_method(Class_KernelInfo, "scale_geometry", RUBY_METHOD_FUNC(KernelInfo_scale_geometry), 1);
910
- rb_define_method(Class_KernelInfo, "clone", RUBY_METHOD_FUNC(KernelInfo_clone), 0);
911
- rb_define_method(Class_KernelInfo, "dup", RUBY_METHOD_FUNC(KernelInfo_clone), 0);
905
+ rb_define_method(Class_KernelInfo, "initialize_copy", RUBY_METHOD_FUNC(KernelInfo_init_copy), 1);
912
906
 
913
907
  rb_define_singleton_method(Class_KernelInfo, "builtin", RUBY_METHOD_FUNC(KernelInfo_builtin), 2);
914
908
 
@@ -531,50 +531,8 @@ Pixel_case_eq(VALUE self, VALUE other)
531
531
  }
532
532
 
533
533
 
534
- /**
535
- * Clone a Pixel.
536
- *
537
- * @return [Magick::Pixel] a clone object
538
- * @see #dup
539
- * @see #initialize_copy
540
- */
541
- VALUE
542
- Pixel_clone(VALUE self)
543
- {
544
- VALUE clone;
545
-
546
- clone = Pixel_dup(self);
547
- if (OBJ_FROZEN(self))
548
- {
549
- OBJ_FREEZE(clone);
550
- }
551
-
552
- RB_GC_GUARD(clone);
553
-
554
- return clone;
555
- }
556
534
 
557
535
 
558
- /**
559
- * Duplicate a Pixel.
560
- *
561
- * @return [Magick::Pixel] a duplicated object
562
- * @see #clone
563
- * @see #initialize_copy
564
- */
565
- VALUE
566
- Pixel_dup(VALUE self)
567
- {
568
- Pixel *pixel;
569
- VALUE dup;
570
-
571
- pixel = ALLOC(Pixel);
572
- memset(pixel, '\0', sizeof(Pixel));
573
- dup = TypedData_Wrap_Struct(CLASS_OF(self), &rm_pixel_data_type, pixel);
574
- RB_GC_GUARD(dup);
575
-
576
- return rb_funcall(dup, rm_ID_initialize_copy, 1, self);
577
- }
578
536
 
579
537
 
580
538
  /**
@@ -838,7 +838,7 @@ Import_TypeMetric(TypeMetric *tm)
838
838
  max_advance = rb_float_new(tm->max_advance);
839
839
  bounds = Import_SegmentInfo(&tm->bounds);
840
840
  underline_position = rb_float_new(tm->underline_position);
841
- underline_thickness = rb_float_new(tm->underline_position);
841
+ underline_thickness = rb_float_new(tm->underline_thickness);
842
842
 
843
843
  RB_GC_GUARD(pixels_per_em);
844
844
  RB_GC_GUARD(ascent);
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Magick
4
- VERSION = '7.1.5'
4
+ VERSION = '7.1.6'
5
5
  MIN_RUBY_VERSION = '3.2.0'
6
6
  MIN_IM6_VERSION = '6.9.0'
7
7
  MIN_IM7_VERSION = '7.1.0'
@@ -1410,12 +1410,6 @@ module Magick
1410
1410
  @images.clear
1411
1411
  end
1412
1412
 
1413
- def clone
1414
- ditto = dup
1415
- ditto.freeze if frozen?
1416
- ditto
1417
- end
1418
-
1419
1413
  # override Enumerable#collect
1420
1414
  def collect(&)
1421
1415
  current = get_current
@@ -1507,13 +1501,6 @@ module Magick
1507
1501
  self
1508
1502
  end
1509
1503
 
1510
- def dup
1511
- ditto = self.class.new
1512
- @images.each { |img| ditto << img }
1513
- ditto.scene = @scene
1514
- ditto
1515
- end
1516
-
1517
1504
  def eql?(other)
1518
1505
  begin
1519
1506
  assert_image_array other
@@ -1570,6 +1557,13 @@ module Magick
1570
1557
  @scene = length - 1 if length > 0 # last image in array
1571
1558
  end
1572
1559
 
1560
+ # Called by clone and dup, after the instance variables are copied. The copy
1561
+ # has its own array of the same images.
1562
+ def initialize_copy(other)
1563
+ super
1564
+ @images = @images.dup
1565
+ end
1566
+
1573
1567
  def insert(index, *args)
1574
1568
  args.each { |image| assert_image image }
1575
1569
  current = get_current
@@ -23,8 +23,8 @@ module Magick
23
23
  def matte_floodfill: (int x, int y) -> Image
24
24
  def matte_fill_to_border: (int x, int y) -> Image
25
25
  def matte_reset!: () -> Image
26
- def resize_to_fill: (real ncols, ?real nrows, ?GravityType gravity) -> Image
27
- def resize_to_fill!: (real ncols, ?real nrows, ?GravityType gravity) -> Image
26
+ def resize_to_fill: (real ncols, ?real? nrows, ?GravityType gravity) -> Image
27
+ def resize_to_fill!: (real ncols, ?real? nrows, ?GravityType gravity) -> self
28
28
  alias crop_resized resize_to_fill
29
29
  alias crop_resized! resize_to_fill!
30
30
  def resize_to_fit: (magick_real cols, ?magick_real rows) -> Image
@@ -147,15 +147,16 @@ module Magick
147
147
  def alpha: () -> bool
148
148
  | (AlphaChannelOption value) -> AlphaChannelOption
149
149
  def alpha?: () -> bool
150
- def artifact: (string artifact) -> String?
150
+ def artifact: (interned artifact) -> String?
151
151
  def auto_gamma_channel: (*ChannelType channel) -> Image
152
152
  def auto_level_channel: (*ChannelType channel) -> Image
153
153
  def auto_orient: () -> Image
154
- def auto_orient!: () -> self
154
+ def auto_orient!: () -> self?
155
155
  def properties: () -> Hash[String, String]
156
156
  | () { ([String, String]) -> void } -> self
157
157
  def bilevel_channel: (magick_real threshold, *ChannelType channel) -> Image
158
- def black_threshold: (magick_real red, ?magick_real green, ?magick_real blue, ?int alpha) -> Image
158
+ def black_threshold: (magick_real red, ?magick_real green, ?magick_real blue) -> Image
159
+ | (magick_real red, magick_real green, magick_real blue, alpha: int) -> Image
159
160
  def blend: (magick_image overlay, magick_percentage src_percent, ?magick_percentage dst_percent, ?GravityType gravity, ?int x_offset, ?int y_offset) -> Image
160
161
  | (magick_image overlay, magick_percentage src_percent, magick_percentage dst_percent, ?int x_offset, ?int y_offset) -> Image
161
162
  def blue_shift: (?magick_real factor) -> Image
@@ -180,7 +181,7 @@ module Magick
180
181
  def charcoal: (?magick_real radius, ?magick_real sigma) -> Image
181
182
  def chop: (int x, int y, int width, int height) -> Image
182
183
  def clut_channel: (magick_image clut_image, *ChannelType channel) -> self
183
- def clone: () -> Image
184
+ def clone: (?freeze: bool?) -> Image
184
185
  def color_flood_fill: (magick_color target_color, magick_color fill_color, int xv, int yv, PaintMethod method) -> Image
185
186
  def color_histogram: () -> Hash[Pixel, Integer]
186
187
  def colorize: (magick_real red, magick_real green, magick_real blue, magick_color target) -> Image
@@ -203,10 +204,13 @@ module Magick
203
204
  | (magick_image image, magick_real a, magick_real b, magick_real c, magick_real d, int x_off, int y_off) -> Image
204
205
  | (magick_image image, magick_real a, magick_real b, magick_real c, magick_real d, GravityType gravity, int x_off, int y_off) -> Image
205
206
  def composite_tiled: (magick_image src, ?CompositeOperator composite_op, *ChannelType channel) -> Image
207
+ | (magick_image src, *ChannelType channel) -> Image
206
208
  def composite_tiled!: (magick_image src, ?CompositeOperator composite_op, *ChannelType channel) -> self
209
+ | (magick_image src, *ChannelType channel) -> self
207
210
  def compress_colormap!: () -> Image
208
211
  def contrast: (?bool sharpen) -> Image
209
- def contrast_stretch_channel: (magick_percentage black_point, magick_percentage white_point, *ChannelType channel) -> Image
212
+ def contrast_stretch_channel: (magick_percentage black_point, ?magick_percentage white_point, *ChannelType channel) -> Image
213
+ | (magick_percentage black_point, *ChannelType channel) -> Image
210
214
  def convolve: (int order_arg, Array[magick_real] kernel_arg) -> Image
211
215
  def convolve_channel: (int order_arg, Array[magick_real] kernel_arg, *ChannelType channel) -> Image
212
216
  def morphology: (MorphologyMethod method_v, int iterations, KernelInfo kernel_v) -> Image
@@ -220,7 +224,7 @@ module Magick
220
224
  | (int x, int y, int width, int height, ?bool reset) -> Image
221
225
  def cycle_colormap: (int amount) -> Image
222
226
  def decipher: (string passphrase) -> Image
223
- def define: (string artifact, string? value) -> string?
227
+ def define: (interned artifact, (string | Numeric)? value) -> String?
224
228
  def deskew: (?magick_percentage threshold, ?int auto_crop_width) -> Image
225
229
  def delete_compose_mask: () -> self
226
230
  def delete_profile: (string name) -> self
@@ -228,12 +232,13 @@ module Magick
228
232
  def difference: (magick_image other) -> [Float, Float, Float]
229
233
  def dispatch: (int x, int y, int columns, int rows, string map, ?bool float) -> Array[Integer]
230
234
  def displace: (magick_image displacement_map, magick_real x_amp, ?magick_real y_amp, ?GravityType gravity, ?int x_offset, ?int y_offset) -> Image
235
+ | (magick_image displacement_map, magick_real x_amp, magick_real y_amp, int x_offset, ?int y_offset) -> Image
231
236
  def dissolve: (magick_image overlay, magick_percentage src_percent, ?magick_percentage dst_percent, ?GravityType gravity, ?int x_offset, ?int y_offset) -> Image
232
237
  def distort: (DistortMethod method, Array[magick_real] points, ?bool bestfit) -> Image
233
238
  def distortion_channel: (magick_image reconstructed_image, MetricType metric, *ChannelType channel) -> Float
234
239
  def _dump: (untyped depth) -> String
235
240
  def dup: () -> Image
236
- def each_profile: () { (String name, String val) -> void } -> untyped
241
+ def each_profile: () { ([String, String?] profile) -> void } -> untyped
237
242
  def edge: (?magick_real radius) -> Image
238
243
  def emboss: (?magick_real radius, ?magick_real sigma) -> Image
239
244
  def encipher: (string passphrase) -> Image
@@ -246,13 +251,13 @@ module Magick
246
251
  def export_pixels: (?int x, ?int y, ?int cols, ?int rows, ?string map) -> Array[Integer]
247
252
  def export_pixels_to_str: (?int x, ?int y, ?int cols, ?int rows, ?string map, ?StorageType storage_type) -> String
248
253
  def extent: (int width, int height, ?int x, ?int y) -> Image
249
- def find_similar_region: (magick_image target, int x, int y) -> [Integer, Integer]?
254
+ def find_similar_region: (magick_image target, ?int x, ?int y) -> [Integer, Integer]?
250
255
  def flip: () -> Image
251
256
  def flip!: () -> self
252
257
  def flop: () -> Image
253
258
  def flop!: () -> self
254
259
  def frame: (?int width, ?int height, ?int x, ?int y, ?int inner_bevel, ?int outer_bevel, ?magick_color color) -> Image
255
- def function_channel: (MagickFunction function, ?magick_real arg1, ?magick_real arg2, ?magick_real arg3, ?magick_real arg4, *ChannelType channel) -> Image
260
+ def function_channel: (MagickFunction function, *(magick_real | ChannelType) args) -> Image
256
261
  def fx: (string expression, *ChannelType channel) -> Image
257
262
  def gamma_channel: (magick_real gamma, *ChannelType channel) -> Image
258
263
  def gamma_correct: (magick_real red_gamma, ?magick_real green_gamma, ?magick_real blue_gamma) -> Image
@@ -275,7 +280,7 @@ module Magick
275
280
  def magnify!: () -> self
276
281
  def mask: (?magick_image image) -> Image?
277
282
  def matte_flood_fill: (magick_color color, int x_obj, int y_obj, PaintMethod method, alpha: int) -> Image
278
- def median_filter: (magick_real radius) -> Image
283
+ def median_filter: (?magick_real radius) -> Image
279
284
  def minify: () -> Image
280
285
  def minify!: () -> self
281
286
  def modulate: (?magick_percentage brightness, ?magick_percentage saturation, ?magick_percentage hue) -> Image
@@ -300,7 +305,7 @@ module Magick
300
305
  | (?magick_real angle) { (Image::PolaroidOptions) -> void } -> Image
301
306
  def posterize: (?int levels, ?bool dither) -> Image
302
307
  def preview: (PreviewType preview) -> Image
303
- def profile!: (string name, ?string profile) -> self
308
+ def profile!: (string name, string? profile) -> self
304
309
  def quantum_operator: (QuantumExpressionOperator quantum_expression_op, magick_real rvalue, ?ChannelType channel) -> self
305
310
  def radial_blur: (magick_real angle) -> Image
306
311
  def radial_blur_channel: (magick_real angle, *ChannelType channel) -> Image
@@ -330,7 +335,7 @@ module Magick
330
335
  def segment: (?ColorspaceType colorspace, ?magick_real cluster_threshold, ?magick_real smoothing_threshold, ?bool verbose) -> Image
331
336
  def selective_blur_channel: (magick_real radius, magick_real sigma, magick_percentage threshold, *ChannelType channel) -> Image
332
337
  def separate: (*ChannelType channel) -> ImageList
333
- def sepiatone: (magick_real threshold) -> Image
338
+ def sepiatone: (?magick_real threshold) -> Image
334
339
  def set_channel_depth: (ChannelType channel, int depth) -> self
335
340
  def shade: (?bool shading, ?magick_real azimuth, ?magick_real elevation) -> Image
336
341
  def shadow: (?int x_offset, ?int y_offset, ?magick_real sigma, ?magick_percentage alpha) -> Image
@@ -385,6 +390,7 @@ module Magick
385
390
  | (magick_image mark, magick_percentage brightness, magick_percentage saturation, GravityType gravity, ?int x_off, ?int y_off) -> Image
386
391
  def wave: (?magick_real amplitude, ?magick_real wavelength) -> Image
387
392
  def wet_floor: (?magick_real initial, ?magick_real rate) -> Image
388
- def white_threshold: (magick_real red, ?magick_real green, ?magick_real blue, ?alpha: int) -> Image
393
+ def white_threshold: (magick_real red, ?magick_real green, ?magick_real blue) -> Image
394
+ | (magick_real red, magick_real green, magick_real blue, alpha: int) -> Image
389
395
  end
390
396
  end
@@ -11,7 +11,7 @@ module Magick
11
11
  # If define as Array[Image] implies the possibility of returning nil.
12
12
  # it would require consideration of nil in subsequent method calls.
13
13
  # So, it defined in Tuple type to avoid allowing unnecessary guard statements to be written.
14
- def self.constitute: (int witdth_arg, int height_arg, string map_arg, Array[Pixel] pixels_arg) -> Image
14
+ def self.constitute: (int witdth_arg, int height_arg, string map_arg, Array[Integer] | Array[Float] pixels_arg) -> Image
15
15
  def self._load: (string str) -> Image
16
16
  def self.capture: (bool silent, bool frame, bool descend, bool screen, bool borders) -> Image
17
17
  | (bool silent, bool frame, bool descend, bool screen, bool borders) { (Image::Info) -> void } -> Image
@@ -24,8 +24,8 @@ module Magick
24
24
  def self.from_blob: (string blob) -> [Image]
25
25
  | (string blob) { (Image::Info) -> void } -> [Image]
26
26
 
27
- def initialize: (int cols, int rows, ?magick_fill fill) -> void
28
- | (int cols, int rows, ?magick_fill fill) { (Image::Info) -> void } -> void
27
+ def initialize: (int cols, int rows, ?magick_fill? fill) -> void
28
+ | (int cols, int rows, ?magick_fill? fill) { (Image::Info) -> void } -> void
29
29
  def <=>: (untyped object) -> (Integer | nil)
30
30
  def []: (interned key_arg) -> String?
31
31
  def []=: (interned key_arg, String attr_arg) -> self
@@ -35,7 +35,7 @@ module Magick
35
35
  def marshal_dump: () -> [String, String]
36
36
  def marshal_load: ([string, string] ary) -> self
37
37
  def montage: () -> String?
38
- def quantize: (?int number_colors, ?ColorspaceType colorspace, ?bool dither, ?int tree_depth, ?bool measure_error) -> Image
38
+ def quantize: (?int number_colors, ?ColorspaceType colorspace, ?(DitherMethod | bool) dither, ?int tree_depth, ?bool measure_error) -> Image
39
39
  def scene: () -> Integer
40
40
  def ticks_per_second=: (int tps) -> int
41
41
  def to_blob: () -> String?
@@ -37,7 +37,7 @@ module Magick
37
37
  def []=: (int nth, magick_image | Array[Image] image) -> void
38
38
  | (Range[Integer] range, magick_image | Array[Image] image) -> void
39
39
  | (int start, int length, magick_image | Array[Image] image) -> void
40
- def at: () -> Image
40
+ def at: (int index) -> Image?
41
41
  def each: () -> Enumerator[Image, self]
42
42
  | () { (Image) -> void } -> void
43
43
  def each_index: () -> Enumerator[Integer, self]
@@ -54,13 +54,14 @@ module Magick
54
54
  | () { (Image) -> boolish } -> Integer?
55
55
  | () -> ::Enumerator[Image, Integer?]
56
56
  def length: () -> Integer
57
+ alias size length
57
58
  def rindex: (Image | ImageList | Array[Image] obj) -> ::Integer?
58
59
  | () { (Image) -> boolish } -> Integer?
59
60
  | () -> ::Enumerator[Image, Integer?]
60
61
  def sort!: () -> self
61
62
  | () { (Image a, Image b) -> Integer } -> self
62
63
  def clear: () -> void
63
- def clone: () -> ImageList
64
+ def clone: (?freeze: bool?) -> ImageList
64
65
  | ...
65
66
  def collect: () { (Image) -> Image } -> ImageList
66
67
  def collect!: () { (Image) -> Image } -> self
@@ -83,7 +84,7 @@ module Magick
83
84
  | () -> self
84
85
  def dup: () -> ImageList
85
86
  | ...
86
- def eql?: (ImageList | Array[Image] other) -> bool
87
+ def eql?: (untyped other) -> bool
87
88
  def fill: (Image image, ?int start, ?int length) -> ImageList
88
89
  | (Image image, Range[Integer] range) -> ImageList
89
90
  | (?int start, ?int length) { (Integer index) -> Image } -> ImageList
@@ -102,8 +103,8 @@ module Magick
102
103
  def marshal_dump: () -> Array[(Integer | String)?]
103
104
  def marshal_load: (Array[(Integer | String)?] ary) -> void
104
105
  def method_missing: (untyped meth_id, *untyped args) ?{ (*untyped, **untyped) -> untyped } -> untyped
105
- def new_image: (int cols, int rows, ?magick_fill fill) -> self
106
- | (int cols, int rows, ?magick_fill fill) { (Image::Info) -> void } -> self
106
+ def new_image: (int cols, int rows, ?magick_fill? fill) -> self
107
+ | (int cols, int rows, ?magick_fill? fill) { (Image::Info) -> void } -> self
107
108
  def partition: () { (Image) -> boolish } -> [ImageList, ImageList]
108
109
  def ping: (*(File | string) files) -> self
109
110
  | (*(File | string) files) { (Image::Info) -> void } -> self
@@ -123,8 +124,8 @@ module Magick
123
124
  | (int start, int length) -> ImageList?
124
125
  | (Range[Integer] range) -> ImageList?
125
126
  def slice!: (int index) -> Image?
126
- | (int start, int length) -> Image?
127
- | (Range[Integer] range) -> Image?
127
+ | (int start, int length) -> Array[Image]?
128
+ | (Range[Integer] range) -> Array[Image]?
128
129
  def ticks_per_second=: (int t) -> void
129
130
  def to_a: () -> Array[Image]
130
131
  def uniq: () -> ImageList
@@ -132,6 +133,8 @@ module Magick
132
133
  def unshift: (Image obj) -> self
133
134
  def values_at: (*int index) -> ImageList
134
135
  | (Range[Integer] range) -> ImageList
136
+ alias indexes values_at
137
+ alias indices values_at
135
138
 
136
139
  alias __display__ display
137
140
  def remap: (?magick_image? remap_image, ?DitherMethod dither_method) -> self
@@ -8,7 +8,7 @@ module Magick
8
8
  def unity_add: (magick_real scale) -> nil
9
9
  def scale: (magick_real scale, GeometryFlags flags) -> nil
10
10
  def scale_geometry: (string geometry) -> nil
11
- def clone: () -> KernelInfo
11
+ def clone: (?freeze: bool?) -> KernelInfo
12
12
  def dup: () -> KernelInfo
13
13
  end
14
14
  end
@@ -28,13 +28,13 @@ module Magick
28
28
  attr_writer black: real
29
29
 
30
30
  def self.from_color: (string name) -> Pixel
31
- def self.from_hsla: (magick_percentage hue, magick_percentage saturation, magick_percentage lightness, magick_percentage alpha) -> Pixel
31
+ def self.from_hsla: (magick_percentage hue, magick_percentage saturation, magick_percentage lightness, ?magick_percentage alpha) -> Pixel
32
32
 
33
33
  def <=>: (untyped other) -> (-1 | 0 | 1 | nil)
34
34
  def ===: (untyped other) -> bool
35
35
  def eql?: (untyped other) -> bool
36
36
  def initialize: (?real red, ?real green, ?real blue, ?real opacity) -> void
37
- def clone: () -> Pixel
37
+ def clone: (?freeze: bool?) -> Pixel
38
38
  def dup: () -> Pixel
39
39
  def fcmp: (magick_color other, ?magick_real fuzz, ?ColorspaceType colorspace) -> bool
40
40
  def hash: () -> Integer
data/sig/rmagick.rbs CHANGED
@@ -38,6 +38,7 @@ module Magick
38
38
  def self.init_formats: () -> Hash[String, String]
39
39
  def self.limit_resource: (interned resource) -> Integer
40
40
  | (interned resource, int limit) -> Integer
41
+ def self.resource_usage: (interned resource) -> Integer
41
42
  def self.set_cache_threshold: (int threshold) -> self
42
43
  def self.set_log_event_mask: (*string args) -> self
43
44
  def self.set_log_format: (string format) -> self
@@ -46,7 +46,7 @@ module Magick
46
46
  # Define an SVG path. The argument can be either a path string
47
47
  # or a PathData object.
48
48
  # Use the RVG::ShapeConstructors#path method to create Path objects in a container.
49
- def initialize: (interned path) -> void
49
+ def initialize: (interned | PathData path) -> void
50
50
  end
51
51
 
52
52
  class Rect < Shape
@@ -139,7 +139,7 @@ module Magick
139
139
 
140
140
  # Draws a path defined by an SVG path string or a PathData
141
141
  # object.
142
- def path: (interned path) -> Path
142
+ def path: (interned | PathData path) -> Path
143
143
 
144
144
  # Draws a rectangle whose upper-left corner is [<tt>x</tt>, <tt>y</tt>] and
145
145
  # with the specified +width+ and +height+. Unless otherwise
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rmagick
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.5
4
+ version: 7.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Hunter