rmagick 7.1.4 → 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 +4 -4
- data/CHANGELOG.md +45 -0
- data/ext/RMagick/rmagick.cpp +73 -19
- data/ext/RMagick/rmagick.h +3 -7
- data/ext/RMagick/rmdraw.cpp +0 -40
- data/ext/RMagick/rmimage.cpp +204 -119
- data/ext/RMagick/rminfo.cpp +37 -3
- data/ext/RMagick/rmkinfo.cpp +84 -16
- data/ext/RMagick/rmmain.cpp +2 -8
- data/ext/RMagick/rmmontage.cpp +13 -2
- data/ext/RMagick/rmpixel.cpp +0 -42
- data/ext/RMagick/rmstruct.cpp +1 -1
- data/ext/RMagick/rmutil.cpp +44 -0
- data/lib/rmagick/version.rb +1 -1
- data/lib/rmagick_internal.rb +7 -13
- data/sig/rmagick/_image_common_methods.rbs +21 -15
- data/sig/rmagick/image.rbs +4 -4
- data/sig/rmagick/image_list.rbs +10 -7
- data/sig/rmagick/kernel_info.rbs +1 -1
- data/sig/rmagick/pixel.rbs +2 -2
- data/sig/rmagick.rbs +1 -0
- data/sig/rvg/embellishable.rbs +2 -2
- metadata +2 -2
data/ext/RMagick/rmimage.cpp
CHANGED
|
@@ -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
|
/**
|
|
@@ -2900,6 +2879,35 @@ Image_color_histogram(VALUE self)
|
|
|
2900
2879
|
}
|
|
2901
2880
|
|
|
2902
2881
|
|
|
2882
|
+
/**
|
|
2883
|
+
* Return true if the format is one handled by ImageMagick's META coder. set_profile
|
|
2884
|
+
* decodes the profile with the coder of that name, so any other format would run an
|
|
2885
|
+
* unrelated decoder (MSL, MVG, SVG, ...) on the profile bytes.
|
|
2886
|
+
*
|
|
2887
|
+
* No Ruby usage (internal function)
|
|
2888
|
+
*
|
|
2889
|
+
* @param format the format name
|
|
2890
|
+
* @return true if the format is a META profile format, otherwise false
|
|
2891
|
+
*/
|
|
2892
|
+
static bool
|
|
2893
|
+
is_meta_profile_format(const char *format)
|
|
2894
|
+
{
|
|
2895
|
+
static const char *meta_formats[] = {
|
|
2896
|
+
"8BIM", "8BIMTEXT", "8BIMWTEXT", "APP1", "APP1JPEG", "EXIF",
|
|
2897
|
+
"ICC", "ICM", "IPTC", "IPTCTEXT", "IPTCWTEXT", "XMP"
|
|
2898
|
+
};
|
|
2899
|
+
|
|
2900
|
+
for (size_t i = 0; i < sizeof(meta_formats) / sizeof(meta_formats[0]); i++)
|
|
2901
|
+
{
|
|
2902
|
+
if (rm_strcasecmp(format, meta_formats[i]) == 0)
|
|
2903
|
+
{
|
|
2904
|
+
return true;
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
return false;
|
|
2908
|
+
}
|
|
2909
|
+
|
|
2910
|
+
|
|
2903
2911
|
/**
|
|
2904
2912
|
* Store all the profiles in the profile in the target image. Called from
|
|
2905
2913
|
* Image_color_profile_eq and Image_iptc_profile_eq.
|
|
@@ -2927,10 +2935,17 @@ set_profile(VALUE self, const char *name, VALUE profile)
|
|
|
2927
2935
|
|
|
2928
2936
|
profile_blob = rm_str2cstr(&profile, &profile_length);
|
|
2929
2937
|
|
|
2938
|
+
// Reject the name before GetMagickInfo(), which loads the coder module it names
|
|
2939
|
+
// ("*" loads all of them).
|
|
2940
|
+
if (!is_meta_profile_format(name))
|
|
2941
|
+
{
|
|
2942
|
+
rb_raise(rb_eArgError, "unknown name: %s", name);
|
|
2943
|
+
}
|
|
2944
|
+
|
|
2930
2945
|
exception = AcquireExceptionInfo();
|
|
2931
2946
|
m = GetMagickInfo(name, exception);
|
|
2932
2947
|
CHECK_EXCEPTION();
|
|
2933
|
-
if (!m)
|
|
2948
|
+
if (!m || !is_meta_profile_format(m->name))
|
|
2934
2949
|
{
|
|
2935
2950
|
DestroyExceptionInfo(exception);
|
|
2936
2951
|
rb_raise(rb_eArgError, "unknown name: %s", name);
|
|
@@ -3861,7 +3876,8 @@ composite_channel(int bang, int argc, VALUE *argv, VALUE self)
|
|
|
3861
3876
|
|
|
3862
3877
|
|
|
3863
3878
|
/**
|
|
3864
|
-
* Composite the source over the destination image
|
|
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}.
|
|
3865
3881
|
*
|
|
3866
3882
|
* @overload composite_channel(image, x_off, y_off, composite_op, channel = Magick::AllChannels)
|
|
3867
3883
|
* @param image [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
|
|
@@ -3934,8 +3950,8 @@ Image_composite_channel(int argc, VALUE *argv, VALUE self)
|
|
|
3934
3950
|
|
|
3935
3951
|
|
|
3936
3952
|
/**
|
|
3937
|
-
* Composite the source over the destination image
|
|
3938
|
-
* 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}.
|
|
3939
3955
|
*
|
|
3940
3956
|
* @overload composite_channel!(image, x_off, y_off, composite_op, channel = Magick::AllChannels)
|
|
3941
3957
|
* @param image [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
|
|
@@ -3997,7 +4013,7 @@ Image_composite_channel(int argc, VALUE *argv, VALUE self)
|
|
|
3997
4013
|
* @param composite_op [Magick::CompositeOperator] the composite operator
|
|
3998
4014
|
* @param *channels [Magick::ChannelType] one or more ChannelType arguments.
|
|
3999
4015
|
*
|
|
4000
|
-
* @return [Magick::Image]
|
|
4016
|
+
* @return [Magick::Image] self
|
|
4001
4017
|
* @see Image#composite_channel
|
|
4002
4018
|
* @see Image#composite!
|
|
4003
4019
|
*/
|
|
@@ -6186,22 +6202,6 @@ Image__dump(VALUE self, VALUE depth ATTRIBUTE_UNUSED)
|
|
|
6186
6202
|
}
|
|
6187
6203
|
|
|
6188
6204
|
|
|
6189
|
-
/**
|
|
6190
|
-
* Duplicates an image.
|
|
6191
|
-
*
|
|
6192
|
-
* @return [Magick::Image] a new image
|
|
6193
|
-
*/
|
|
6194
|
-
VALUE
|
|
6195
|
-
Image_dup(VALUE self)
|
|
6196
|
-
{
|
|
6197
|
-
VALUE dup;
|
|
6198
|
-
|
|
6199
|
-
rm_check_destroyed(self);
|
|
6200
|
-
dup = TypedData_Wrap_Struct(CLASS_OF(self), &rm_image_data_type, NULL);
|
|
6201
|
-
RB_GC_GUARD(dup);
|
|
6202
|
-
|
|
6203
|
-
return rb_funcall(dup, rm_ID_initialize_copy, 1, self);
|
|
6204
|
-
}
|
|
6205
6205
|
|
|
6206
6206
|
|
|
6207
6207
|
/**
|
|
@@ -8305,6 +8305,42 @@ Image_import_pixels(int argc, VALUE *argv, VALUE self)
|
|
|
8305
8305
|
}
|
|
8306
8306
|
|
|
8307
8307
|
|
|
8308
|
+
/**
|
|
8309
|
+
* Append formatted text to the buffer used by build_inspect_string.
|
|
8310
|
+
*
|
|
8311
|
+
* No Ruby usage (internal function)
|
|
8312
|
+
*
|
|
8313
|
+
* Notes:
|
|
8314
|
+
* - vsnprintf returns the length of the untruncated text, so only the bytes
|
|
8315
|
+
* that actually fit are counted. The returned offset never exceeds len-1,
|
|
8316
|
+
* so once the buffer is full later appends add nothing to it.
|
|
8317
|
+
*
|
|
8318
|
+
* @param buffer buffer for the output string
|
|
8319
|
+
* @param len length of buffer
|
|
8320
|
+
* @param x # bytes used in buffer, at most len-1
|
|
8321
|
+
* @param format printf-style format string
|
|
8322
|
+
* @return the new # bytes used in buffer, at most len-1
|
|
8323
|
+
* @see build_inspect_string
|
|
8324
|
+
*/
|
|
8325
|
+
static int
|
|
8326
|
+
append_inspect_string(char *buffer, size_t len, int x, const char *format, ...)
|
|
8327
|
+
{
|
|
8328
|
+
va_list args;
|
|
8329
|
+
int n;
|
|
8330
|
+
|
|
8331
|
+
va_start(args, format);
|
|
8332
|
+
n = vsnprintf(buffer+x, len-x, format, args);
|
|
8333
|
+
va_end(args);
|
|
8334
|
+
|
|
8335
|
+
if (n > 0)
|
|
8336
|
+
{
|
|
8337
|
+
x += (int)min((size_t)n, len-1-x);
|
|
8338
|
+
}
|
|
8339
|
+
|
|
8340
|
+
return x;
|
|
8341
|
+
}
|
|
8342
|
+
|
|
8343
|
+
|
|
8308
8344
|
/**
|
|
8309
8345
|
* Override Object#inspect - return a string description of the image.
|
|
8310
8346
|
*
|
|
@@ -8328,56 +8364,56 @@ build_inspect_string(Image *image, char *buffer, size_t len)
|
|
|
8328
8364
|
// Print magick filename if different from current filename.
|
|
8329
8365
|
if (*image->magick_filename != '\0' && strcmp(image->magick_filename, image->filename) != 0)
|
|
8330
8366
|
{
|
|
8331
|
-
x
|
|
8367
|
+
x = append_inspect_string(buffer, len, x, "%.1024s=>", image->magick_filename);
|
|
8332
8368
|
}
|
|
8333
8369
|
// Print current filename.
|
|
8334
|
-
x
|
|
8370
|
+
x = append_inspect_string(buffer, len, x, "%.1024s", image->filename);
|
|
8335
8371
|
// Print scene number.
|
|
8336
8372
|
if ((GetPreviousImageInList(image) != NULL) && (GetNextImageInList(image) != NULL) && image->scene > 0)
|
|
8337
8373
|
{
|
|
8338
|
-
x
|
|
8374
|
+
x = append_inspect_string(buffer, len, x, "[%" RMIuSIZE "]", image->scene);
|
|
8339
8375
|
}
|
|
8340
8376
|
// Print format
|
|
8341
|
-
x
|
|
8377
|
+
x = append_inspect_string(buffer, len, x, " %s ", image->magick);
|
|
8342
8378
|
|
|
8343
8379
|
// Print magick columnsXrows if different from current.
|
|
8344
8380
|
if (image->magick_columns != 0 || image->magick_rows != 0)
|
|
8345
8381
|
{
|
|
8346
8382
|
if (image->magick_columns != image->columns || image->magick_rows != image->rows)
|
|
8347
8383
|
{
|
|
8348
|
-
x
|
|
8384
|
+
x = append_inspect_string(buffer, len, x, "%" RMIuSIZE "x%" RMIuSIZE "=>", image->magick_columns, image->magick_rows);
|
|
8349
8385
|
}
|
|
8350
8386
|
}
|
|
8351
8387
|
|
|
8352
|
-
x
|
|
8388
|
+
x = append_inspect_string(buffer, len, x, "%" RMIuSIZE "x%" RMIuSIZE " ", image->columns, image->rows);
|
|
8353
8389
|
|
|
8354
8390
|
// Print current columnsXrows
|
|
8355
8391
|
if ( image->page.width != 0 || image->page.height != 0
|
|
8356
8392
|
|| image->page.x != 0 || image->page.y != 0)
|
|
8357
8393
|
{
|
|
8358
|
-
x
|
|
8359
|
-
|
|
8360
|
-
|
|
8394
|
+
x = append_inspect_string(buffer, len, x, "%" RMIuSIZE "x%" RMIuSIZE "+%" RMIdSIZE "+%" RMIdSIZE " ",
|
|
8395
|
+
image->page.width, image->page.height,
|
|
8396
|
+
image->page.x, image->page.y);
|
|
8361
8397
|
}
|
|
8362
8398
|
|
|
8363
8399
|
if (image->storage_class == DirectClass)
|
|
8364
8400
|
{
|
|
8365
|
-
x
|
|
8401
|
+
x = append_inspect_string(buffer, len, x, "DirectClass ");
|
|
8366
8402
|
if (image->total_colors != 0)
|
|
8367
8403
|
{
|
|
8368
8404
|
if (image->total_colors >= (unsigned long)(1 << 24))
|
|
8369
8405
|
{
|
|
8370
|
-
x
|
|
8406
|
+
x = append_inspect_string(buffer, len, x, "%" RMIuSIZE "mc ", image->total_colors/1024/1024);
|
|
8371
8407
|
}
|
|
8372
8408
|
else
|
|
8373
8409
|
{
|
|
8374
8410
|
if (image->total_colors >= (unsigned long)(1 << 16))
|
|
8375
8411
|
{
|
|
8376
|
-
x
|
|
8412
|
+
x = append_inspect_string(buffer, len, x, "%" RMIuSIZE "kc ", image->total_colors/1024);
|
|
8377
8413
|
}
|
|
8378
8414
|
else
|
|
8379
8415
|
{
|
|
8380
|
-
x
|
|
8416
|
+
x = append_inspect_string(buffer, len, x, "%" RMIuSIZE "c ", image->total_colors);
|
|
8381
8417
|
}
|
|
8382
8418
|
}
|
|
8383
8419
|
}
|
|
@@ -8388,39 +8424,39 @@ build_inspect_string(Image *image, char *buffer, size_t len)
|
|
|
8388
8424
|
// building with GM. GM defines that field as an unsigned int.
|
|
8389
8425
|
if (image->total_colors <= image->colors)
|
|
8390
8426
|
{
|
|
8391
|
-
x
|
|
8427
|
+
x = append_inspect_string(buffer, len, x, "PseudoClass %ldc ", (long) image->colors);
|
|
8392
8428
|
}
|
|
8393
8429
|
else
|
|
8394
8430
|
{
|
|
8395
|
-
x
|
|
8431
|
+
x = append_inspect_string(buffer, len, x, "PseudoClass %" RMIuSIZE "=>%" RMIuSIZE "c ", image->total_colors, image->colors);
|
|
8396
8432
|
if (image->error.mean_error_per_pixel != 0.0)
|
|
8397
8433
|
{
|
|
8398
|
-
x
|
|
8399
|
-
|
|
8400
|
-
|
|
8401
|
-
|
|
8434
|
+
x = append_inspect_string(buffer, len, x, "%ld/%.6f/%.6fdb ",
|
|
8435
|
+
(long) (image->error.mean_error_per_pixel+0.5),
|
|
8436
|
+
image->error.normalized_mean_error,
|
|
8437
|
+
image->error.normalized_maximum_error);
|
|
8402
8438
|
}
|
|
8403
8439
|
}
|
|
8404
8440
|
}
|
|
8405
8441
|
|
|
8406
8442
|
// Print bit depth
|
|
8407
8443
|
quantum_depth = GetImageQuantumDepth(image, MagickTrue);
|
|
8408
|
-
x
|
|
8444
|
+
x = append_inspect_string(buffer, len, x, "%lu-bit", quantum_depth);
|
|
8409
8445
|
|
|
8410
8446
|
// Print blob info if appropriate.
|
|
8411
8447
|
if (GetBlobSize(image) != 0)
|
|
8412
8448
|
{
|
|
8413
8449
|
if (GetBlobSize(image) >= (1 << 24))
|
|
8414
8450
|
{
|
|
8415
|
-
x
|
|
8451
|
+
x = append_inspect_string(buffer, len, x, " %lumb", (unsigned long) (GetBlobSize(image)/1024/1024));
|
|
8416
8452
|
}
|
|
8417
8453
|
else if (GetBlobSize(image) >= 1024)
|
|
8418
8454
|
{
|
|
8419
|
-
x
|
|
8455
|
+
x = append_inspect_string(buffer, len, x, " %lukb", (unsigned long) (GetBlobSize(image)/1024));
|
|
8420
8456
|
}
|
|
8421
8457
|
else
|
|
8422
8458
|
{
|
|
8423
|
-
x
|
|
8459
|
+
x = append_inspect_string(buffer, len, x, " %lub", (unsigned long) GetBlobSize(image));
|
|
8424
8460
|
}
|
|
8425
8461
|
}
|
|
8426
8462
|
|
|
@@ -8440,7 +8476,7 @@ build_inspect_string(Image *image, char *buffer, size_t len)
|
|
|
8440
8476
|
}
|
|
8441
8477
|
}
|
|
8442
8478
|
|
|
8443
|
-
assert(x < (int)
|
|
8479
|
+
assert(x < (int)len);
|
|
8444
8480
|
buffer[x] = '\0';
|
|
8445
8481
|
|
|
8446
8482
|
return;
|
|
@@ -8625,11 +8661,12 @@ Image_level2(int argc, VALUE *argv, VALUE self)
|
|
|
8625
8661
|
/**
|
|
8626
8662
|
* Similar to {Image#level2} but applies to a single channel only.
|
|
8627
8663
|
*
|
|
8628
|
-
* @overload level_channel(aChannelType, black = 0.0, white =
|
|
8664
|
+
* @overload level_channel(aChannelType, black = 0.0, white = Magick::QuantumRange - black, gamma = 1.0)
|
|
8629
8665
|
* @param aChannelType [Magick::ChannelType] A ChannelType value.
|
|
8630
8666
|
* @param black [Numeric] A black point level in the range 0..QuantumRange.
|
|
8631
8667
|
* @param white [Numeric] A white point level in the range 0..QuantumRange.
|
|
8632
|
-
* @param gamma [Numeric] A gamma correction
|
|
8668
|
+
* @param gamma [Numeric] A gamma correction. Unlike with {Image#level}, a value greater than 10.0 is
|
|
8669
|
+
* used as given.
|
|
8633
8670
|
* @return [Magick::Image] a new image
|
|
8634
8671
|
* @see Image#level2
|
|
8635
8672
|
*/
|
|
@@ -10868,8 +10905,9 @@ Image_pixel_interpolation_method_eq(VALUE self, VALUE method)
|
|
|
10868
10905
|
|
|
10869
10906
|
/**
|
|
10870
10907
|
* Produce an image that looks like a Polaroid instant picture. If the image has a "Caption"
|
|
10871
|
-
* property, the value is used as a caption. A caption whose first non-blank character is '@'
|
|
10872
|
-
*
|
|
10908
|
+
* property, the value is used as a caption. A caption whose first non-blank character is '@',
|
|
10909
|
+
* or that contains a %[fx:@...], %[hex:@...] or %[pixel:@...] escape, is rejected because
|
|
10910
|
+
* ImageMagick reads the file it names.
|
|
10873
10911
|
*
|
|
10874
10912
|
* The following annotate attributes control the label rendering:
|
|
10875
10913
|
* align, decorate, density, encoding, fill, font, font_family, font_stretch, font_style,
|
|
@@ -10890,7 +10928,7 @@ Image_pixel_interpolation_method_eq(VALUE self, VALUE method)
|
|
|
10890
10928
|
* @yieldparam opt [Magick::Image::PolaroidOptions]
|
|
10891
10929
|
*
|
|
10892
10930
|
* @return [Magick::Image] a new image
|
|
10893
|
-
* @raise [ArgumentError] if the "Caption" property
|
|
10931
|
+
* @raise [ArgumentError] if the "Caption" property names a file with '@'
|
|
10894
10932
|
*/
|
|
10895
10933
|
VALUE
|
|
10896
10934
|
Image_polaroid(int argc, VALUE *argv, VALUE self)
|
|
@@ -10928,20 +10966,11 @@ Image_polaroid(int argc, VALUE *argv, VALUE self)
|
|
|
10928
10966
|
#else
|
|
10929
10967
|
caption = GetImageProperty(clone, "Caption");
|
|
10930
10968
|
#endif
|
|
10931
|
-
if (caption)
|
|
10969
|
+
if (caption && rm_has_file_reference(caption))
|
|
10932
10970
|
{
|
|
10933
|
-
|
|
10934
|
-
|
|
10935
|
-
|
|
10936
|
-
{
|
|
10937
|
-
p++;
|
|
10938
|
-
}
|
|
10939
|
-
if (*p == '@')
|
|
10940
|
-
{
|
|
10941
|
-
DestroyImage(clone);
|
|
10942
|
-
DestroyExceptionInfo(exception);
|
|
10943
|
-
rb_raise(rb_eArgError, "the Caption property must not begin with '@'");
|
|
10944
|
-
}
|
|
10971
|
+
DestroyImage(clone);
|
|
10972
|
+
DestroyExceptionInfo(exception);
|
|
10973
|
+
rb_raise(rb_eArgError, "the Caption property must not name a file with '@'");
|
|
10945
10974
|
}
|
|
10946
10975
|
|
|
10947
10976
|
#if defined(IMAGEMAGICK_7)
|
|
@@ -11045,11 +11074,13 @@ Image_preview(VALUE self, VALUE preview)
|
|
|
11045
11074
|
|
|
11046
11075
|
/**
|
|
11047
11076
|
* Set the image profile. If "profile" is nil, deletes the profile. Otherwise "profile" must be a
|
|
11048
|
-
* string containing the specified profile
|
|
11077
|
+
* string containing the specified profile, and "name" must be one of the profile formats of
|
|
11078
|
+
* ImageMagick's META coder (8BIM, APP1, EXIF, ICC, ICM, IPTC, XMP and their variants).
|
|
11049
11079
|
*
|
|
11050
11080
|
* @param name [String, nil] The profile name, or "*" to represent all the profiles in the image.
|
|
11051
11081
|
* @param profile [String] The profile value, or nil to cause the profile to be removed.
|
|
11052
11082
|
* @return [Magick::Image] self
|
|
11083
|
+
* @raise [ArgumentError] if "profile" is not nil and "name" is not a META profile format
|
|
11053
11084
|
*/
|
|
11054
11085
|
VALUE
|
|
11055
11086
|
Image_profile_bang(VALUE self, VALUE name, VALUE profile)
|
|
@@ -11999,35 +12030,71 @@ Image_rendering_intent_eq(VALUE self, VALUE ri)
|
|
|
11999
12030
|
|
|
12000
12031
|
#if defined(IMAGEMAGICK_7)
|
|
12001
12032
|
/**
|
|
12002
|
-
*
|
|
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.
|
|
12003
12039
|
*
|
|
12004
12040
|
* No Ruby usage (internal function)
|
|
12005
12041
|
*
|
|
12006
12042
|
* @param image the image
|
|
12007
|
-
* @param blur the blur
|
|
12008
|
-
* @return
|
|
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
|
|
12009
12046
|
*/
|
|
12010
12047
|
static Image*
|
|
12011
|
-
|
|
12048
|
+
image_with_filter_blur(Image* image, double blur)
|
|
12012
12049
|
{
|
|
12013
|
-
|
|
12014
|
-
|
|
12050
|
+
Image *clone;
|
|
12051
|
+
const char *artifact;
|
|
12052
|
+
char value[MaxTextExtent];
|
|
12015
12053
|
|
|
12016
|
-
|
|
12017
|
-
if (blur > 1.0)
|
|
12054
|
+
if (blur == 1.0)
|
|
12018
12055
|
{
|
|
12019
|
-
|
|
12020
|
-
new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(BlurImage), &args);
|
|
12056
|
+
return image;
|
|
12021
12057
|
}
|
|
12022
|
-
|
|
12058
|
+
|
|
12059
|
+
artifact = GetImageArtifact(image, "filter:blur");
|
|
12060
|
+
if (artifact)
|
|
12023
12061
|
{
|
|
12024
|
-
|
|
12025
|
-
new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(SharpenImage), &args);
|
|
12062
|
+
blur *= InterpretLocaleValue(artifact, (char **)NULL);
|
|
12026
12063
|
}
|
|
12027
|
-
|
|
12028
|
-
DestroyExceptionInfo(exception);
|
|
12064
|
+
snprintf(value, sizeof(value), "%.17g", blur);
|
|
12029
12065
|
|
|
12030
|
-
|
|
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
|
+
}
|
|
12031
12098
|
}
|
|
12032
12099
|
#endif
|
|
12033
12100
|
|
|
@@ -12112,12 +12179,22 @@ resample(int bang, int argc, VALUE *argv, VALUE self)
|
|
|
12112
12179
|
break;
|
|
12113
12180
|
}
|
|
12114
12181
|
|
|
12182
|
+
#if defined(IMAGEMAGICK_7)
|
|
12183
|
+
// Before AcquireExceptionInfo(), since it can raise
|
|
12184
|
+
Image *source = image_with_filter_blur(image, blur);
|
|
12185
|
+
#endif
|
|
12115
12186
|
exception = AcquireExceptionInfo();
|
|
12116
12187
|
#if defined(IMAGEMAGICK_7)
|
|
12117
|
-
|
|
12118
|
-
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 };
|
|
12119
12189
|
new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ResampleImage), &args);
|
|
12120
|
-
|
|
12190
|
+
if (source != image)
|
|
12191
|
+
{
|
|
12192
|
+
if (new_image)
|
|
12193
|
+
{
|
|
12194
|
+
restore_filter_blur(new_image, image);
|
|
12195
|
+
}
|
|
12196
|
+
DestroyImage(source);
|
|
12197
|
+
}
|
|
12121
12198
|
#else
|
|
12122
12199
|
GVL_STRUCT_TYPE(ResampleImage) args = { image, x_resolution, y_resolution, filter, blur, exception };
|
|
12123
12200
|
new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ResampleImage), &args);
|
|
@@ -12147,12 +12224,12 @@ resample(int bang, int argc, VALUE *argv, VALUE self)
|
|
|
12147
12224
|
* the original resolution of the image must be specified via the density attribute prior to
|
|
12148
12225
|
* specifying the resample resolution.
|
|
12149
12226
|
*
|
|
12150
|
-
* @overload resample(x_resolution = 72.0, y_resolution =
|
|
12227
|
+
* @overload resample(x_resolution = 72.0, y_resolution = x_resolution, filter = self.filter, blur = 1.0)
|
|
12151
12228
|
* @param x_resolution [Numeric] the target horizontal resolution.
|
|
12152
12229
|
* @param y_resolution [Numeric] the target vertical resolution.
|
|
12153
12230
|
* @param filter [Magick::FilterType] the filter type
|
|
12154
|
-
* @param blur [Numeric] the blur
|
|
12155
|
-
* @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
|
|
12156
12233
|
* @see Image#resample!
|
|
12157
12234
|
*/
|
|
12158
12235
|
VALUE
|
|
@@ -12167,12 +12244,12 @@ Image_resample(int argc, VALUE *argv, VALUE self)
|
|
|
12167
12244
|
* Resample image to specified horizontal resolution, vertical resolution, filter and blur factor.
|
|
12168
12245
|
* In-place form of {Image#resample}.
|
|
12169
12246
|
*
|
|
12170
|
-
* @overload resample!(x_resolution = 72.0, y_resolution =
|
|
12247
|
+
* @overload resample!(x_resolution = 72.0, y_resolution = x_resolution, filter = self.filter, blur = 1.0)
|
|
12171
12248
|
* @param x_resolution [Numeric] the target horizontal resolution.
|
|
12172
12249
|
* @param y_resolution [Numeric] the target vertical resolution.
|
|
12173
12250
|
* @param filter [Magick::FilterType] the filter type
|
|
12174
|
-
* @param blur [Numeric] the blur
|
|
12175
|
-
* @return [Magick]
|
|
12251
|
+
* @param blur [Numeric] the blur factor of the filter: > 1.0 blurs and < 1.0 sharpens
|
|
12252
|
+
* @return [Magick::Image] self
|
|
12176
12253
|
* @see Image#resample
|
|
12177
12254
|
*/
|
|
12178
12255
|
VALUE
|
|
@@ -12253,14 +12330,21 @@ resize(int bang, int argc, VALUE *argv, VALUE self)
|
|
|
12253
12330
|
break;
|
|
12254
12331
|
}
|
|
12255
12332
|
|
|
12333
|
+
#if defined(IMAGEMAGICK_7)
|
|
12334
|
+
// Before AcquireExceptionInfo(), since it can raise
|
|
12335
|
+
Image *source = image_with_filter_blur(image, blur);
|
|
12336
|
+
#endif
|
|
12256
12337
|
exception = AcquireExceptionInfo();
|
|
12257
12338
|
#if defined(IMAGEMAGICK_7)
|
|
12258
|
-
|
|
12259
|
-
GVL_STRUCT_TYPE(ResizeImage) args = { preprocess, columns, rows, filter, exception };
|
|
12339
|
+
GVL_STRUCT_TYPE(ResizeImage) args = { source, columns, rows, filter, exception };
|
|
12260
12340
|
new_image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ResizeImage), &args);
|
|
12261
|
-
if (
|
|
12341
|
+
if (source != image)
|
|
12262
12342
|
{
|
|
12263
|
-
|
|
12343
|
+
if (new_image)
|
|
12344
|
+
{
|
|
12345
|
+
restore_filter_blur(new_image, image);
|
|
12346
|
+
}
|
|
12347
|
+
DestroyImage(source);
|
|
12264
12348
|
}
|
|
12265
12349
|
#else
|
|
12266
12350
|
GVL_STRUCT_TYPE(ResizeImage) args = { image, columns, rows, filter, blur, exception };
|
|
@@ -12293,7 +12377,7 @@ resize(int bang, int argc, VALUE *argv, VALUE self)
|
|
|
12293
12377
|
* @param cols [Numeric] The desired width
|
|
12294
12378
|
* @param rows [Numeric] The desired height.
|
|
12295
12379
|
* @param filter [Magick::FilterType] the filter type
|
|
12296
|
-
* @param blur [Numeric] the blur
|
|
12380
|
+
* @param blur [Numeric] the blur factor of the filter: > 1.0 blurs and < 1.0 sharpens
|
|
12297
12381
|
*
|
|
12298
12382
|
* @return [Magick::Image] a new image
|
|
12299
12383
|
* @see Image#resize!
|
|
@@ -12319,7 +12403,7 @@ Image_resize(int argc, VALUE *argv, VALUE self)
|
|
|
12319
12403
|
* @param cols [Numeric] The desired width
|
|
12320
12404
|
* @param rows [Numeric] The desired height.
|
|
12321
12405
|
* @param filter [Magick::FilterType] the filter type
|
|
12322
|
-
* @param blur [Numeric] the blur
|
|
12406
|
+
* @param blur [Numeric] the blur factor of the filter: > 1.0 blurs and < 1.0 sharpens
|
|
12323
12407
|
*
|
|
12324
12408
|
* @return [Magick::Image] a new image
|
|
12325
12409
|
* @see Image#resize!
|
|
@@ -14537,8 +14621,8 @@ Image_ticks_per_second_eq(VALUE self, VALUE tps)
|
|
|
14537
14621
|
* @param red_alpha [Numeric] the red value
|
|
14538
14622
|
* @param green_alpha [Numeric] the green value
|
|
14539
14623
|
* @param blue_alpha [Numeric] the blue value
|
|
14540
|
-
* @param alpha_alpha [Numeric] the alpha
|
|
14541
|
-
* @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
|
|
14542
14626
|
*/
|
|
14543
14627
|
VALUE
|
|
14544
14628
|
Image_tint(int argc, VALUE *argv, VALUE self)
|
|
@@ -15189,7 +15273,8 @@ VALUE Image_image_type_eq(VALUE self, VALUE image_type)
|
|
|
15189
15273
|
|
|
15190
15274
|
|
|
15191
15275
|
/**
|
|
15192
|
-
* Removes an artifact from the image
|
|
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.
|
|
15193
15278
|
*
|
|
15194
15279
|
* @param artifact [String] the artifact
|
|
15195
15280
|
* @return [Magick::Image] self
|