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/rminfo.cpp
CHANGED
|
@@ -47,6 +47,25 @@ get_option(VALUE self, const char *key)
|
|
|
47
47
|
return Qnil;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Raise ArgumentError if the option is one that ReadImage runs through
|
|
52
|
+
* InterpretImageProperties() and the value would make it read the file it names.
|
|
53
|
+
*
|
|
54
|
+
* No Ruby usage (internal function)
|
|
55
|
+
*
|
|
56
|
+
* @param key the option key
|
|
57
|
+
* @param value the value
|
|
58
|
+
*/
|
|
59
|
+
static void
|
|
60
|
+
check_interpreted_option(const char *key, const char *value)
|
|
61
|
+
{
|
|
62
|
+
if ((rm_strcasecmp(key, "caption") == 0 || rm_strcasecmp(key, "comment") == 0 || rm_strcasecmp(key, "label") == 0)
|
|
63
|
+
&& rm_has_file_reference(value))
|
|
64
|
+
{
|
|
65
|
+
rb_raise(rb_eArgError, "the %s option must not name a file with '@'", key);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
50
69
|
/**
|
|
51
70
|
* Set the specified option to this value. If the value is nil just unset any
|
|
52
71
|
* current value.
|
|
@@ -74,6 +93,7 @@ set_option(VALUE self, const char *key, VALUE string)
|
|
|
74
93
|
char *value;
|
|
75
94
|
|
|
76
95
|
value = StringValueCStr(string);
|
|
96
|
+
check_interpreted_option(key, value);
|
|
77
97
|
SetImageOption(info, key, value);
|
|
78
98
|
}
|
|
79
99
|
return string;
|
|
@@ -306,6 +326,9 @@ Info_aref(int argc, VALUE *argv, VALUE self)
|
|
|
306
326
|
*
|
|
307
327
|
* - Essentially the same function as {Info#define} but paired with {Info#[]}
|
|
308
328
|
* - If the value is nil it is equivalent to {Info#undefine}.
|
|
329
|
+
* - A value whose first non-blank character is '@', or that contains a %[fx:@...], %[hex:@...] or
|
|
330
|
+
* %[pixel:@...] escape, is rejected for the "caption", "comment" and "label" keys because
|
|
331
|
+
* ImageMagick reads the file it names.
|
|
309
332
|
*
|
|
310
333
|
* @overload []=(format, key)
|
|
311
334
|
* @param format [String] An image format name such as "ps" or "tiff".
|
|
@@ -315,6 +338,7 @@ Info_aref(int argc, VALUE *argv, VALUE self)
|
|
|
315
338
|
* @param key [String] A string that identifies the option.
|
|
316
339
|
*
|
|
317
340
|
* @return [Magick::Image::Info] self
|
|
341
|
+
* @raise [ArgumentError] if the "caption", "comment" or "label" value names a file with '@'
|
|
318
342
|
* @see #[]
|
|
319
343
|
* @see #define
|
|
320
344
|
* @see #undefine
|
|
@@ -368,6 +392,7 @@ Info_aset(int argc, VALUE *argv, VALUE self)
|
|
|
368
392
|
/* Allow any argument that supports to_s */
|
|
369
393
|
value = rb_String(value);
|
|
370
394
|
value_p = StringValueCStr(value);
|
|
395
|
+
check_interpreted_option(ckey, value_p);
|
|
371
396
|
|
|
372
397
|
okay = SetImageOption(info, ckey, value_p);
|
|
373
398
|
if (!okay)
|
|
@@ -552,10 +577,13 @@ Info_caption(VALUE self)
|
|
|
552
577
|
|
|
553
578
|
|
|
554
579
|
/**
|
|
555
|
-
* Assigns a caption to an image.
|
|
580
|
+
* Assigns a caption to an image. A caption whose first non-blank character is '@', or that
|
|
581
|
+
* contains a %[fx:@...], %[hex:@...] or %[pixel:@...] escape, is rejected because ImageMagick
|
|
582
|
+
* reads the file it names.
|
|
556
583
|
*
|
|
557
584
|
* @param caption [String] the caption
|
|
558
585
|
* @return [String] the given value
|
|
586
|
+
* @raise [ArgumentError] if the caption names a file with '@'
|
|
559
587
|
*/
|
|
560
588
|
VALUE
|
|
561
589
|
Info_caption_eq(VALUE self, VALUE caption)
|
|
@@ -637,10 +665,13 @@ VALUE Info_comment(VALUE self)
|
|
|
637
665
|
}
|
|
638
666
|
|
|
639
667
|
/**
|
|
640
|
-
* Set the comment
|
|
668
|
+
* Set the comment. A comment whose first non-blank character is '@', or that contains a
|
|
669
|
+
* %[fx:@...], %[hex:@...] or %[pixel:@...] escape, is rejected because ImageMagick reads the
|
|
670
|
+
* file it names.
|
|
641
671
|
*
|
|
642
672
|
* @param string [String] the comment
|
|
643
673
|
* @return [String] the given comment
|
|
674
|
+
* @raise [ArgumentError] if the comment names a file with '@'
|
|
644
675
|
*/
|
|
645
676
|
VALUE Info_comment_eq(VALUE self, VALUE string)
|
|
646
677
|
{
|
|
@@ -1529,10 +1560,13 @@ VALUE Info_label(VALUE self)
|
|
|
1529
1560
|
}
|
|
1530
1561
|
|
|
1531
1562
|
/**
|
|
1532
|
-
* Set the label.
|
|
1563
|
+
* Set the label. A label whose first non-blank character is '@', or that contains a
|
|
1564
|
+
* %[fx:@...], %[hex:@...] or %[pixel:@...] escape, is rejected because ImageMagick reads the
|
|
1565
|
+
* file it names.
|
|
1533
1566
|
*
|
|
1534
1567
|
* @param string [String] the label
|
|
1535
1568
|
* @return [String] the given label
|
|
1569
|
+
* @raise [ArgumentError] if the label names a file with '@'
|
|
1536
1570
|
*/
|
|
1537
1571
|
VALUE Info_label_eq(VALUE self, VALUE string)
|
|
1538
1572
|
{
|
data/ext/RMagick/rmkinfo.cpp
CHANGED
|
@@ -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
|
|
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 = {
|
|
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]
|
|
168
|
-
*
|
|
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 = {
|
|
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 = {
|
|
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
|
-
*
|
|
241
|
+
* Initialize a copy made by clone or dup with a copy of the kernel of the original.
|
|
203
242
|
*
|
|
204
|
-
* @
|
|
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
|
-
|
|
248
|
+
KernelInfo_init_copy(VALUE self, VALUE orig)
|
|
208
249
|
{
|
|
209
|
-
KernelInfo *kernel
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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");
|
data/ext/RMagick/rmmain.cpp
CHANGED
|
@@ -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, "
|
|
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
|
|
data/ext/RMagick/rmmontage.cpp
CHANGED
|
@@ -442,18 +442,29 @@ Montage_tile_eq(VALUE self, VALUE tile_arg)
|
|
|
442
442
|
|
|
443
443
|
|
|
444
444
|
/**
|
|
445
|
-
* Set title value.
|
|
445
|
+
* Set title value. A title whose first non-blank character is '@', or that contains a
|
|
446
|
+
* %[fx:@...], %[hex:@...] or %[pixel:@...] escape, is rejected because ImageMagick reads the
|
|
447
|
+
* file it names.
|
|
446
448
|
*
|
|
447
449
|
* @param title [String] the title
|
|
448
450
|
* @return [String] the given title
|
|
451
|
+
* @raise [ArgumentError] if the title names a file with '@'
|
|
449
452
|
*/
|
|
450
453
|
VALUE
|
|
451
454
|
Montage_title_eq(VALUE self, VALUE title)
|
|
452
455
|
{
|
|
453
456
|
Montage *montage;
|
|
457
|
+
const char *title_cstr;
|
|
454
458
|
|
|
455
459
|
TypedData_Get_Struct(self, Montage, &rm_montage_data_type, montage);
|
|
456
|
-
|
|
460
|
+
title_cstr = StringValueCStr(title);
|
|
461
|
+
|
|
462
|
+
if (rm_has_file_reference(title_cstr))
|
|
463
|
+
{
|
|
464
|
+
rb_raise(rb_eArgError, "the title must not name a file with '@'");
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
magick_clone_string(&montage->info->title, title_cstr);
|
|
457
468
|
return title;
|
|
458
469
|
}
|
|
459
470
|
|
data/ext/RMagick/rmpixel.cpp
CHANGED
|
@@ -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
|
/**
|
data/ext/RMagick/rmstruct.cpp
CHANGED
|
@@ -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->
|
|
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);
|
data/ext/RMagick/rmutil.cpp
CHANGED
|
@@ -221,6 +221,50 @@ rm_strnlen_s(const char *str, size_t strsz)
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Return true if InterpretImageProperties() would read a file the string names, that is, if its
|
|
226
|
+
* first non-blank character is '@', or if it contains a %[fx:...], %[hex:...] or %[pixel:...]
|
|
227
|
+
* escape whose expression begins with '@'.
|
|
228
|
+
*
|
|
229
|
+
* ImageMagick 7 reads such an expression from the file it names, with no blank skipped before
|
|
230
|
+
* the '@'. It also interprets a %[...] inside an fx expression, even after "%%" since '%' is the
|
|
231
|
+
* modulo operator there, so every "%[" in the string is checked. The prefixes are compared with
|
|
232
|
+
* LocaleNCompare() as ImageMagick does. ImageMagick 6 does not read these expressions, but the
|
|
233
|
+
* check is the same for both.
|
|
234
|
+
*
|
|
235
|
+
* No Ruby usage (internal function)
|
|
236
|
+
*
|
|
237
|
+
* @param str the string
|
|
238
|
+
* @return true if the string names a file to read, otherwise false
|
|
239
|
+
*/
|
|
240
|
+
bool
|
|
241
|
+
rm_has_file_reference(const char *str)
|
|
242
|
+
{
|
|
243
|
+
const char *p;
|
|
244
|
+
|
|
245
|
+
p = str;
|
|
246
|
+
while (isspace((int) ((unsigned char) *p)))
|
|
247
|
+
{
|
|
248
|
+
p++;
|
|
249
|
+
}
|
|
250
|
+
if (*p == '@')
|
|
251
|
+
{
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
for (p = strstr(str, "%["); p != NULL; p = strstr(p + 2, "%["))
|
|
256
|
+
{
|
|
257
|
+
if (LocaleNCompare(p + 2, "fx:@", 4) == 0
|
|
258
|
+
|| LocaleNCompare(p + 2, "hex:@", 5) == 0
|
|
259
|
+
|| LocaleNCompare(p + 2, "pixel:@", 7) == 0)
|
|
260
|
+
{
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
|
|
224
268
|
/**
|
|
225
269
|
* Raise exception if array too short.
|
|
226
270
|
*
|
data/lib/rmagick/version.rb
CHANGED
data/lib/rmagick_internal.rb
CHANGED
|
@@ -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
|