rmagick 7.0.3 → 7.0.5
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 +20 -0
- data/README.md +1 -0
- data/ext/RMagick/rmdraw.cpp +59 -29
- data/ext/RMagick/rmimage.cpp +60 -10
- data/ext/RMagick/rmkinfo.cpp +45 -5
- data/ext/RMagick/rmpixel.cpp +18 -11
- data/lib/rmagick/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6a209cf0d468a316b82b18e0dc8cdfe37d07e3a9a89a54750303c48fddbc4721
|
|
4
|
+
data.tar.gz: ec494eed858ad482b7fbc1a3784c471bed373ab2ad1cd3835c99b3c998548736
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8879e76297539f5ab7816fb3ba4894530141292fdd828277774d5631655176c717f0888f4624d22f6b7006e9d1b544f7065705220d06df77eadbb428216d6dce
|
|
7
|
+
data.tar.gz: 67e8ff6082884e98cf7cf3dfc35eee092377fc2e4a1d60cc6679b9872dc4c52effc6a6ad6b95966a552eb6f15c2b0264ee2580d768dfce0b71a9aa1ee90b866a
|
data/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,26 @@
|
|
|
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.0.5
|
|
7
|
+
|
|
8
|
+
Bug Fixes
|
|
9
|
+
|
|
10
|
+
* Fix heap overflow from integer overflow in dispatch/export_pixels geometry (#1816)
|
|
11
|
+
* Fix SEGV in Image/Pixel/Draw #marshal_load on a non-collection argument (#1815)
|
|
12
|
+
* Fix SEGV when a Draw method is called on an uninitialized object (#1814)
|
|
13
|
+
* Fix SEGV in Draw#primitive on non-String argument (#1813)
|
|
14
|
+
|
|
15
|
+
## RMagick 7.0.4
|
|
16
|
+
|
|
17
|
+
Bug Fixes
|
|
18
|
+
|
|
19
|
+
* Fix report size in rm_kernel_info_memsize (#1808)
|
|
20
|
+
* Fix NULL dereference in KernelInfo instance methods (#1807)
|
|
21
|
+
* Fix memory leak and NULL deref in Image#properties (#1806)
|
|
22
|
+
* Fix memory leak when string conversion raises (#1805)
|
|
23
|
+
* Fix error handling in Pixel#to_color when QueryColorname fails (#1800)
|
|
24
|
+
* Reject NAN in Pixel#from_hsla() (#1798)
|
|
25
|
+
|
|
6
26
|
## RMagick 7.0.3
|
|
7
27
|
|
|
8
28
|
Bug Fixes
|
data/README.md
CHANGED
|
@@ -3,6 +3,7 @@ RMagick
|
|
|
3
3
|
|
|
4
4
|
[](https://rubygems.org/gems/rmagick)
|
|
5
5
|

|
|
6
|
+
[](https://deepwiki.com/rmagick/rmagick)
|
|
6
7
|
|
|
7
8
|
Table of Contents
|
|
8
9
|
-----------------
|
data/ext/RMagick/rmdraw.cpp
CHANGED
|
@@ -47,6 +47,33 @@ DEFINE_GVL_STUB3(GetTypeMetrics, Image *, const DrawInfo *, TypeMetric *);
|
|
|
47
47
|
#endif
|
|
48
48
|
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Fetch the Draw struct and ensure it has been initialized (draw->info != NULL).
|
|
52
|
+
*
|
|
53
|
+
* Draw_alloc() leaves draw->info NULL until #initialize runs, so a Draw obtained
|
|
54
|
+
* via .allocate (or a subclass whose #initialize skips super) would otherwise
|
|
55
|
+
* dereference a NULL DrawInfo and crash the process. Raise instead.
|
|
56
|
+
*
|
|
57
|
+
* No Ruby usage (internal function)
|
|
58
|
+
*
|
|
59
|
+
* @param self the Draw object
|
|
60
|
+
* @return the initialized Draw struct
|
|
61
|
+
* @throw RuntimeError if the Draw object has not been initialized
|
|
62
|
+
*/
|
|
63
|
+
static Draw *
|
|
64
|
+
get_draw(VALUE self)
|
|
65
|
+
{
|
|
66
|
+
Draw *draw;
|
|
67
|
+
|
|
68
|
+
TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
|
|
69
|
+
if (!draw->info)
|
|
70
|
+
{
|
|
71
|
+
rb_raise(rb_eRuntimeError, "%s has not been initialized", rb_obj_classname(self));
|
|
72
|
+
}
|
|
73
|
+
return draw;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
50
77
|
/**
|
|
51
78
|
* Set the affine matrix from an {Magick::AffineMatrix}.
|
|
52
79
|
*
|
|
@@ -59,7 +86,7 @@ Draw_affine_eq(VALUE self, VALUE matrix)
|
|
|
59
86
|
Draw *draw;
|
|
60
87
|
|
|
61
88
|
rb_check_frozen(self);
|
|
62
|
-
|
|
89
|
+
draw = get_draw(self);
|
|
63
90
|
Export_AffineMatrix(&draw->info->affine, matrix);
|
|
64
91
|
return matrix;
|
|
65
92
|
}
|
|
@@ -77,7 +104,7 @@ Draw_align_eq(VALUE self, VALUE align)
|
|
|
77
104
|
Draw *draw;
|
|
78
105
|
|
|
79
106
|
rb_check_frozen(self);
|
|
80
|
-
|
|
107
|
+
draw = get_draw(self);
|
|
81
108
|
VALUE_TO_ENUM(align, draw->info->align, AlignType);
|
|
82
109
|
return align;
|
|
83
110
|
}
|
|
@@ -95,7 +122,7 @@ Draw_decorate_eq(VALUE self, VALUE decorate)
|
|
|
95
122
|
Draw *draw;
|
|
96
123
|
|
|
97
124
|
rb_check_frozen(self);
|
|
98
|
-
|
|
125
|
+
draw = get_draw(self);
|
|
99
126
|
VALUE_TO_ENUM(decorate, draw->info->decorate, DecorationType);
|
|
100
127
|
return decorate;
|
|
101
128
|
}
|
|
@@ -113,7 +140,7 @@ Draw_density_eq(VALUE self, VALUE density)
|
|
|
113
140
|
Draw *draw;
|
|
114
141
|
|
|
115
142
|
rb_check_frozen(self);
|
|
116
|
-
|
|
143
|
+
draw = get_draw(self);
|
|
117
144
|
magick_clone_string(&draw->info->density, StringValueCStr(density));
|
|
118
145
|
|
|
119
146
|
return density;
|
|
@@ -132,7 +159,7 @@ Draw_encoding_eq(VALUE self, VALUE encoding)
|
|
|
132
159
|
Draw *draw;
|
|
133
160
|
|
|
134
161
|
rb_check_frozen(self);
|
|
135
|
-
|
|
162
|
+
draw = get_draw(self);
|
|
136
163
|
magick_clone_string(&draw->info->encoding, StringValueCStr(encoding));
|
|
137
164
|
|
|
138
165
|
return encoding;
|
|
@@ -151,7 +178,7 @@ Draw_fill_eq(VALUE self, VALUE fill)
|
|
|
151
178
|
Draw *draw;
|
|
152
179
|
|
|
153
180
|
rb_check_frozen(self);
|
|
154
|
-
|
|
181
|
+
draw = get_draw(self);
|
|
155
182
|
Color_to_PixelColor(&draw->info->fill, fill);
|
|
156
183
|
return fill;
|
|
157
184
|
}
|
|
@@ -172,7 +199,7 @@ Draw_fill_pattern_eq(VALUE self, VALUE pattern)
|
|
|
172
199
|
Draw *draw;
|
|
173
200
|
|
|
174
201
|
rb_check_frozen(self);
|
|
175
|
-
|
|
202
|
+
draw = get_draw(self);
|
|
176
203
|
|
|
177
204
|
if (draw->info->fill_pattern != NULL)
|
|
178
205
|
{
|
|
@@ -207,7 +234,7 @@ Draw_font_eq(VALUE self, VALUE font)
|
|
|
207
234
|
Draw *draw;
|
|
208
235
|
|
|
209
236
|
rb_check_frozen(self);
|
|
210
|
-
|
|
237
|
+
draw = get_draw(self);
|
|
211
238
|
magick_clone_string(&draw->info->font, StringValueCStr(font));
|
|
212
239
|
|
|
213
240
|
return font;
|
|
@@ -226,7 +253,7 @@ Draw_font_family_eq(VALUE self, VALUE family)
|
|
|
226
253
|
Draw *draw;
|
|
227
254
|
|
|
228
255
|
rb_check_frozen(self);
|
|
229
|
-
|
|
256
|
+
draw = get_draw(self);
|
|
230
257
|
magick_clone_string(&draw->info->family, StringValueCStr(family));
|
|
231
258
|
|
|
232
259
|
return family;
|
|
@@ -245,7 +272,7 @@ Draw_font_stretch_eq(VALUE self, VALUE stretch)
|
|
|
245
272
|
Draw *draw;
|
|
246
273
|
|
|
247
274
|
rb_check_frozen(self);
|
|
248
|
-
|
|
275
|
+
draw = get_draw(self);
|
|
249
276
|
VALUE_TO_ENUM(stretch, draw->info->stretch, StretchType);
|
|
250
277
|
return stretch;
|
|
251
278
|
}
|
|
@@ -263,7 +290,7 @@ Draw_font_style_eq(VALUE self, VALUE style)
|
|
|
263
290
|
Draw *draw;
|
|
264
291
|
|
|
265
292
|
rb_check_frozen(self);
|
|
266
|
-
|
|
293
|
+
draw = get_draw(self);
|
|
267
294
|
VALUE_TO_ENUM(style, draw->info->style, StyleType);
|
|
268
295
|
return style;
|
|
269
296
|
}
|
|
@@ -283,7 +310,7 @@ Draw_font_weight_eq(VALUE self, VALUE weight)
|
|
|
283
310
|
size_t w;
|
|
284
311
|
|
|
285
312
|
rb_check_frozen(self);
|
|
286
|
-
|
|
313
|
+
draw = get_draw(self);
|
|
287
314
|
|
|
288
315
|
if (FIXNUM_P(weight))
|
|
289
316
|
{
|
|
@@ -349,7 +376,7 @@ Draw_gravity_eq(VALUE self, VALUE grav)
|
|
|
349
376
|
Draw *draw;
|
|
350
377
|
|
|
351
378
|
rb_check_frozen(self);
|
|
352
|
-
|
|
379
|
+
draw = get_draw(self);
|
|
353
380
|
VALUE_TO_ENUM(grav, draw->info->gravity, GravityType);
|
|
354
381
|
|
|
355
382
|
return grav;
|
|
@@ -368,7 +395,7 @@ Draw_kerning_eq(VALUE self, VALUE kerning)
|
|
|
368
395
|
Draw *draw;
|
|
369
396
|
|
|
370
397
|
rb_check_frozen(self);
|
|
371
|
-
|
|
398
|
+
draw = get_draw(self);
|
|
372
399
|
draw->info->kerning = NUM2DBL(kerning);
|
|
373
400
|
return kerning;
|
|
374
401
|
}
|
|
@@ -386,7 +413,7 @@ Draw_interline_spacing_eq(VALUE self, VALUE spacing)
|
|
|
386
413
|
Draw *draw;
|
|
387
414
|
|
|
388
415
|
rb_check_frozen(self);
|
|
389
|
-
|
|
416
|
+
draw = get_draw(self);
|
|
390
417
|
draw->info->interline_spacing = NUM2DBL(spacing);
|
|
391
418
|
return spacing;
|
|
392
419
|
}
|
|
@@ -404,7 +431,7 @@ Draw_interword_spacing_eq(VALUE self, VALUE spacing)
|
|
|
404
431
|
Draw *draw;
|
|
405
432
|
|
|
406
433
|
rb_check_frozen(self);
|
|
407
|
-
|
|
434
|
+
draw = get_draw(self);
|
|
408
435
|
draw->info->interword_spacing = NUM2DBL(spacing);
|
|
409
436
|
return spacing;
|
|
410
437
|
}
|
|
@@ -505,7 +532,7 @@ Draw_marshal_dump(VALUE self)
|
|
|
505
532
|
Draw *draw;
|
|
506
533
|
VALUE ddraw;
|
|
507
534
|
|
|
508
|
-
|
|
535
|
+
draw = get_draw(self);
|
|
509
536
|
|
|
510
537
|
// Raise an exception if the Draw has a non-NULL gradient or element_reference field
|
|
511
538
|
if (draw->info->element_reference.type != UndefinedReference
|
|
@@ -566,6 +593,8 @@ Draw_marshal_load(VALUE self, VALUE ddraw)
|
|
|
566
593
|
|
|
567
594
|
TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
|
|
568
595
|
|
|
596
|
+
Check_Type(ddraw, T_HASH);
|
|
597
|
+
|
|
569
598
|
if (draw->info == NULL)
|
|
570
599
|
{
|
|
571
600
|
ImageInfo *image_info;
|
|
@@ -636,7 +665,7 @@ Draw_pointsize_eq(VALUE self, VALUE pointsize)
|
|
|
636
665
|
Draw *draw;
|
|
637
666
|
|
|
638
667
|
rb_check_frozen(self);
|
|
639
|
-
|
|
668
|
+
draw = get_draw(self);
|
|
640
669
|
draw->info->pointsize = NUM2DBL(pointsize);
|
|
641
670
|
return pointsize;
|
|
642
671
|
}
|
|
@@ -656,7 +685,7 @@ Draw_rotation_eq(VALUE self, VALUE deg)
|
|
|
656
685
|
AffineMatrix affine, current;
|
|
657
686
|
|
|
658
687
|
rb_check_frozen(self);
|
|
659
|
-
|
|
688
|
+
draw = get_draw(self);
|
|
660
689
|
|
|
661
690
|
degrees = NUM2DBL(deg);
|
|
662
691
|
if (fabs(degrees) > DBL_EPSILON)
|
|
@@ -692,7 +721,7 @@ Draw_stroke_eq(VALUE self, VALUE stroke)
|
|
|
692
721
|
Draw *draw;
|
|
693
722
|
|
|
694
723
|
rb_check_frozen(self);
|
|
695
|
-
|
|
724
|
+
draw = get_draw(self);
|
|
696
725
|
Color_to_PixelColor(&draw->info->stroke, stroke);
|
|
697
726
|
return stroke;
|
|
698
727
|
}
|
|
@@ -712,7 +741,7 @@ Draw_stroke_pattern_eq(VALUE self, VALUE pattern)
|
|
|
712
741
|
Draw *draw;
|
|
713
742
|
|
|
714
743
|
rb_check_frozen(self);
|
|
715
|
-
|
|
744
|
+
draw = get_draw(self);
|
|
716
745
|
|
|
717
746
|
if (draw->info->stroke_pattern != NULL)
|
|
718
747
|
{
|
|
@@ -748,7 +777,7 @@ Draw_stroke_width_eq(VALUE self, VALUE stroke_width)
|
|
|
748
777
|
Draw *draw;
|
|
749
778
|
|
|
750
779
|
rb_check_frozen(self);
|
|
751
|
-
|
|
780
|
+
draw = get_draw(self);
|
|
752
781
|
draw->info->stroke_width = NUM2DBL(stroke_width);
|
|
753
782
|
return stroke_width;
|
|
754
783
|
}
|
|
@@ -766,7 +795,7 @@ Draw_text_antialias_eq(VALUE self, VALUE text_antialias)
|
|
|
766
795
|
Draw *draw;
|
|
767
796
|
|
|
768
797
|
rb_check_frozen(self);
|
|
769
|
-
|
|
798
|
+
draw = get_draw(self);
|
|
770
799
|
draw->info->text_antialias = (MagickBooleanType) RTEST(text_antialias);
|
|
771
800
|
return text_antialias;
|
|
772
801
|
}
|
|
@@ -797,7 +826,7 @@ Draw_undercolor_eq(VALUE self, VALUE undercolor)
|
|
|
797
826
|
Draw *draw;
|
|
798
827
|
|
|
799
828
|
rb_check_frozen(self);
|
|
800
|
-
|
|
829
|
+
draw = get_draw(self);
|
|
801
830
|
Color_to_PixelColor(&draw->info->undercolor, undercolor);
|
|
802
831
|
return undercolor;
|
|
803
832
|
}
|
|
@@ -840,7 +869,7 @@ VALUE Draw_annotate(
|
|
|
840
869
|
|
|
841
870
|
// Save the affine matrix in case it is modified by
|
|
842
871
|
// Draw#rotation=
|
|
843
|
-
|
|
872
|
+
draw = get_draw(self);
|
|
844
873
|
keep = draw->info->affine;
|
|
845
874
|
|
|
846
875
|
image_arg = rm_cur_image(image_arg);
|
|
@@ -1050,7 +1079,7 @@ Draw_draw(VALUE self, VALUE image_arg)
|
|
|
1050
1079
|
image_arg = rm_cur_image(image_arg);
|
|
1051
1080
|
image = rm_check_frozen(image_arg);
|
|
1052
1081
|
|
|
1053
|
-
|
|
1082
|
+
draw = get_draw(self);
|
|
1054
1083
|
if (draw->primitives == 0)
|
|
1055
1084
|
{
|
|
1056
1085
|
rb_raise(rb_eArgError, "nothing to draw");
|
|
@@ -1257,6 +1286,7 @@ Draw_primitive(VALUE self, VALUE primitive)
|
|
|
1257
1286
|
Draw *draw;
|
|
1258
1287
|
|
|
1259
1288
|
rb_check_frozen(self);
|
|
1289
|
+
StringValue(primitive);
|
|
1260
1290
|
TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
|
|
1261
1291
|
|
|
1262
1292
|
if (draw->primitives == (VALUE)0)
|
|
@@ -1463,7 +1493,7 @@ PolaroidOptions_initialize(VALUE self)
|
|
|
1463
1493
|
ExceptionInfo *exception;
|
|
1464
1494
|
|
|
1465
1495
|
// Default shadow color
|
|
1466
|
-
|
|
1496
|
+
draw = get_draw(self);
|
|
1467
1497
|
|
|
1468
1498
|
exception = AcquireExceptionInfo();
|
|
1469
1499
|
QueryColorCompliance("gray75", AllCompliance, &draw->shadow_color, exception);
|
|
@@ -1525,7 +1555,7 @@ PolaroidOptions_border_color_eq(VALUE self, VALUE border)
|
|
|
1525
1555
|
Draw *draw;
|
|
1526
1556
|
|
|
1527
1557
|
rb_check_frozen(self);
|
|
1528
|
-
|
|
1558
|
+
draw = get_draw(self);
|
|
1529
1559
|
Color_to_PixelColor(&draw->info->border_color, border);
|
|
1530
1560
|
return border;
|
|
1531
1561
|
}
|
|
@@ -1628,7 +1658,7 @@ get_type_metrics(int argc, VALUE *argv, VALUE self, gvl_function_t fp)
|
|
|
1628
1658
|
rb_raise(rb_eArgError, "no text to measure");
|
|
1629
1659
|
}
|
|
1630
1660
|
|
|
1631
|
-
|
|
1661
|
+
draw = get_draw(self);
|
|
1632
1662
|
#if defined(IMAGEMAGICK_7)
|
|
1633
1663
|
exception = AcquireExceptionInfo();
|
|
1634
1664
|
draw->info->text = InterpretImageProperties(NULL, image, text, exception);
|
data/ext/RMagick/rmimage.cpp
CHANGED
|
@@ -5355,16 +5355,17 @@ VALUE
|
|
|
5355
5355
|
Image_delete_profile(VALUE self, VALUE name)
|
|
5356
5356
|
{
|
|
5357
5357
|
Image *image = rm_check_frozen(self);
|
|
5358
|
+
char *profile_name = StringValueCStr(name);
|
|
5358
5359
|
|
|
5359
5360
|
#if defined(IMAGEMAGICK_7)
|
|
5360
5361
|
ExceptionInfo *exception = AcquireExceptionInfo();
|
|
5361
5362
|
|
|
5362
|
-
GVL_STRUCT_TYPE(ProfileImage) args = { image,
|
|
5363
|
+
GVL_STRUCT_TYPE(ProfileImage) args = { image, profile_name, NULL, 0, exception };
|
|
5363
5364
|
CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ProfileImage), &args);
|
|
5364
5365
|
CHECK_EXCEPTION();
|
|
5365
5366
|
DestroyExceptionInfo(exception);
|
|
5366
5367
|
#else
|
|
5367
|
-
GVL_STRUCT_TYPE(ProfileImage) args = { image,
|
|
5368
|
+
GVL_STRUCT_TYPE(ProfileImage) args = { image, profile_name, NULL, 0, MagickTrue };
|
|
5368
5369
|
CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ProfileImage), &args);
|
|
5369
5370
|
#endif
|
|
5370
5371
|
return self;
|
|
@@ -5629,6 +5630,41 @@ Image_displace(int argc, VALUE *argv, VALUE self)
|
|
|
5629
5630
|
}
|
|
5630
5631
|
|
|
5631
5632
|
|
|
5633
|
+
/**
|
|
5634
|
+
* Compute columns * rows * map_length for a pixel buffer, raising RangeError on
|
|
5635
|
+
* overflow.
|
|
5636
|
+
*
|
|
5637
|
+
* The product is used to size the buffer that ImageMagick fills based on the
|
|
5638
|
+
* (caller-supplied) columns and rows. If the multiplication wrapped around, the
|
|
5639
|
+
* buffer would be allocated too small and ImageMagick would write out of bounds.
|
|
5640
|
+
*
|
|
5641
|
+
* No Ruby usage (internal function)
|
|
5642
|
+
*
|
|
5643
|
+
* @param columns the number of columns
|
|
5644
|
+
* @param rows the number of rows
|
|
5645
|
+
* @param map_length the number of channels per pixel (length of the map string)
|
|
5646
|
+
* @return columns * rows * map_length
|
|
5647
|
+
* @throw RangeError if the multiplication overflows
|
|
5648
|
+
*/
|
|
5649
|
+
static size_t
|
|
5650
|
+
pixel_buffer_count(size_t columns, size_t rows, size_t map_length)
|
|
5651
|
+
{
|
|
5652
|
+
size_t pixels;
|
|
5653
|
+
|
|
5654
|
+
if (columns != 0 && rows > SIZE_MAX / columns)
|
|
5655
|
+
{
|
|
5656
|
+
rb_raise(rb_eRangeError, "pixel buffer dimensions too large (%" RMIuSIZE "x%" RMIuSIZE ")", columns, rows);
|
|
5657
|
+
}
|
|
5658
|
+
pixels = columns * rows;
|
|
5659
|
+
if (map_length != 0 && pixels > SIZE_MAX / map_length)
|
|
5660
|
+
{
|
|
5661
|
+
rb_raise(rb_eRangeError, "pixel buffer dimensions too large (%" RMIuSIZE "x%" RMIuSIZE " map=%" RMIuSIZE ")",
|
|
5662
|
+
columns, rows, map_length);
|
|
5663
|
+
}
|
|
5664
|
+
return pixels * map_length;
|
|
5665
|
+
}
|
|
5666
|
+
|
|
5667
|
+
|
|
5632
5668
|
/**
|
|
5633
5669
|
* Extract pixel data from the image and returns it as an array of pixels. The "x", "y", "width" and
|
|
5634
5670
|
* "height" parameters specify the rectangle to be extracted. The "map" parameter reflects the
|
|
@@ -5684,7 +5720,7 @@ Image_dispatch(int argc, VALUE *argv, VALUE self)
|
|
|
5684
5720
|
}
|
|
5685
5721
|
|
|
5686
5722
|
// Compute the size of the pixel array and allocate the memory.
|
|
5687
|
-
npixels = columns
|
|
5723
|
+
npixels = pixel_buffer_count(columns, rows, mapL);
|
|
5688
5724
|
pixels.v = stg_type == QuantumPixel ? (void *) ALLOC_N(Quantum, npixels)
|
|
5689
5725
|
: (void *) ALLOC_N(double, npixels);
|
|
5690
5726
|
|
|
@@ -6635,7 +6671,7 @@ Image_export_pixels(int argc, VALUE *argv, VALUE self)
|
|
|
6635
6671
|
}
|
|
6636
6672
|
|
|
6637
6673
|
|
|
6638
|
-
npixels = (long)(cols
|
|
6674
|
+
npixels = (long)pixel_buffer_count(cols, rows, strlen(map));
|
|
6639
6675
|
pixels = ALLOC_N(Quantum, npixels);
|
|
6640
6676
|
if (!pixels) // app recovered from exception
|
|
6641
6677
|
{
|
|
@@ -6803,7 +6839,7 @@ Image_export_pixels_to_str(int argc, VALUE *argv, VALUE self)
|
|
|
6803
6839
|
}
|
|
6804
6840
|
|
|
6805
6841
|
|
|
6806
|
-
npixels = cols
|
|
6842
|
+
npixels = pixel_buffer_count(cols, rows, strlen(map));
|
|
6807
6843
|
switch (type)
|
|
6808
6844
|
{
|
|
6809
6845
|
case CharPixel:
|
|
@@ -6832,6 +6868,10 @@ Image_export_pixels_to_str(int argc, VALUE *argv, VALUE self)
|
|
|
6832
6868
|
|
|
6833
6869
|
// Allocate a string long enough to hold the exported pixel data.
|
|
6834
6870
|
// Get a pointer to the buffer.
|
|
6871
|
+
if (npixels != 0 && sz > (size_t)LONG_MAX / npixels)
|
|
6872
|
+
{
|
|
6873
|
+
rb_raise(rb_eRangeError, "pixel buffer dimensions too large");
|
|
6874
|
+
}
|
|
6835
6875
|
string = rb_str_new2("");
|
|
6836
6876
|
rb_str_resize(string, (long)(sz * npixels));
|
|
6837
6877
|
|
|
@@ -9055,6 +9095,8 @@ Image_marshal_load(VALUE self, VALUE ary)
|
|
|
9055
9095
|
|
|
9056
9096
|
TypedData_Get_Struct(self, Image, &rm_image_data_type, image);
|
|
9057
9097
|
|
|
9098
|
+
Check_Type(ary, T_ARRAY);
|
|
9099
|
+
|
|
9058
9100
|
filename = rb_ary_shift(ary);
|
|
9059
9101
|
blob = rb_ary_shift(ary);
|
|
9060
9102
|
|
|
@@ -12838,7 +12880,12 @@ Image_properties(VALUE self)
|
|
|
12838
12880
|
|
|
12839
12881
|
if (rb_block_given_p())
|
|
12840
12882
|
{
|
|
12841
|
-
|
|
12883
|
+
long i;
|
|
12884
|
+
|
|
12885
|
+
// Collect the properties first so that neither the ExceptionInfo nor
|
|
12886
|
+
// the property iterator is held across rb_yield. The block may break
|
|
12887
|
+
// or raise, which would otherwise leak the ExceptionInfo.
|
|
12888
|
+
ary = rb_ary_new();
|
|
12842
12889
|
|
|
12843
12890
|
ResetImagePropertyIterator(image);
|
|
12844
12891
|
property = GetNextImageProperty(image);
|
|
@@ -12849,9 +12896,7 @@ Image_properties(VALUE self)
|
|
|
12849
12896
|
#else
|
|
12850
12897
|
value = GetImageProperty(image, property);
|
|
12851
12898
|
#endif
|
|
12852
|
-
|
|
12853
|
-
rb_ary_store(ary, 1, rb_str_new2(value));
|
|
12854
|
-
rb_yield(ary);
|
|
12899
|
+
rb_ary_push(ary, rb_assoc_new(rb_str_new2(property), value ? rb_str_new2(value) : Qnil));
|
|
12855
12900
|
property = GetNextImageProperty(image);
|
|
12856
12901
|
}
|
|
12857
12902
|
#if defined(IMAGEMAGICK_7)
|
|
@@ -12861,6 +12906,11 @@ Image_properties(VALUE self)
|
|
|
12861
12906
|
rm_check_image_exception(image, RetainOnError);
|
|
12862
12907
|
#endif
|
|
12863
12908
|
|
|
12909
|
+
for (i = 0; i < RARRAY_LEN(ary); i++)
|
|
12910
|
+
{
|
|
12911
|
+
rb_yield(rb_ary_entry(ary, i));
|
|
12912
|
+
}
|
|
12913
|
+
|
|
12864
12914
|
RB_GC_GUARD(ary);
|
|
12865
12915
|
|
|
12866
12916
|
return self;
|
|
@@ -12879,7 +12929,7 @@ Image_properties(VALUE self)
|
|
|
12879
12929
|
#else
|
|
12880
12930
|
value = GetImageProperty(image, property);
|
|
12881
12931
|
#endif
|
|
12882
|
-
rb_hash_aset(attr_hash, rb_str_new2(property), rb_str_new2(value));
|
|
12932
|
+
rb_hash_aset(attr_hash, rb_str_new2(property), value ? rb_str_new2(value) : Qnil);
|
|
12883
12933
|
property = GetNextImageProperty(image);
|
|
12884
12934
|
}
|
|
12885
12935
|
#if defined(IMAGEMAGICK_7)
|
data/ext/RMagick/rmkinfo.cpp
CHANGED
|
@@ -51,7 +51,21 @@ rm_kernel_info_destroy(void *kernel)
|
|
|
51
51
|
static size_t
|
|
52
52
|
rm_kernel_info_memsize(const void *ptr)
|
|
53
53
|
{
|
|
54
|
-
|
|
54
|
+
const KernelInfo *kernel = (const KernelInfo *)ptr;
|
|
55
|
+
size_t size = 0;
|
|
56
|
+
|
|
57
|
+
// A KernelInfo may be a linked list of kernels, each owning a values array.
|
|
58
|
+
while (kernel)
|
|
59
|
+
{
|
|
60
|
+
size += sizeof(KernelInfo);
|
|
61
|
+
if (kernel->values)
|
|
62
|
+
{
|
|
63
|
+
size += kernel->width * kernel->height * sizeof(*kernel->values);
|
|
64
|
+
}
|
|
65
|
+
kernel = kernel->next;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return size;
|
|
55
69
|
}
|
|
56
70
|
|
|
57
71
|
/**
|
|
@@ -105,6 +119,32 @@ KernelInfo_initialize(VALUE self, VALUE kernel_string)
|
|
|
105
119
|
}
|
|
106
120
|
|
|
107
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Return the KernelInfo struct associated with the object, raising an
|
|
124
|
+
* exception if the object has not been initialized (for example, when it was
|
|
125
|
+
* created with KernelInfo.allocate or a previous initialize failed). Without
|
|
126
|
+
* this guard a NULL pointer would be handed to ImageMagick, causing a crash.
|
|
127
|
+
*
|
|
128
|
+
* No Ruby usage (internal function)
|
|
129
|
+
*
|
|
130
|
+
* @param self the KernelInfo object
|
|
131
|
+
* @return the KernelInfo struct
|
|
132
|
+
* @throw RuntimeError if the kernel has not been initialized
|
|
133
|
+
*/
|
|
134
|
+
static KernelInfo *
|
|
135
|
+
get_kernel_info(VALUE self)
|
|
136
|
+
{
|
|
137
|
+
KernelInfo *kernel;
|
|
138
|
+
|
|
139
|
+
TypedData_Get_Struct(self, KernelInfo, &rm_kernel_info_data_type, kernel);
|
|
140
|
+
if (!kernel)
|
|
141
|
+
{
|
|
142
|
+
rb_raise(rb_eRuntimeError, "KernelInfo has not been initialized");
|
|
143
|
+
}
|
|
144
|
+
return kernel;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
108
148
|
/**
|
|
109
149
|
* Adds a given amount of the 'Unity' Convolution Kernel to the given pre-scaled and normalized Kernel.
|
|
110
150
|
*
|
|
@@ -113,7 +153,7 @@ KernelInfo_initialize(VALUE self, VALUE kernel_string)
|
|
|
113
153
|
VALUE
|
|
114
154
|
KernelInfo_unity_add(VALUE self, VALUE scale)
|
|
115
155
|
{
|
|
116
|
-
GVL_STRUCT_TYPE(UnityAddKernelInfo) args = { (
|
|
156
|
+
GVL_STRUCT_TYPE(UnityAddKernelInfo) args = { get_kernel_info(self), NUM2DBL(scale) };
|
|
117
157
|
CALL_FUNC_WITHOUT_GVL(GVL_FUNC(UnityAddKernelInfo), &args);
|
|
118
158
|
return Qnil;
|
|
119
159
|
}
|
|
@@ -134,7 +174,7 @@ KernelInfo_scale(VALUE self, VALUE scale, VALUE flags)
|
|
|
134
174
|
|
|
135
175
|
VALUE_TO_ENUM(flags, geoflags, GeometryFlags);
|
|
136
176
|
|
|
137
|
-
GVL_STRUCT_TYPE(ScaleKernelInfo) args = { (
|
|
177
|
+
GVL_STRUCT_TYPE(ScaleKernelInfo) args = { get_kernel_info(self), NUM2DBL(scale), geoflags };
|
|
138
178
|
CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ScaleKernelInfo), &args);
|
|
139
179
|
return Qnil;
|
|
140
180
|
}
|
|
@@ -148,7 +188,7 @@ KernelInfo_scale(VALUE self, VALUE scale, VALUE flags)
|
|
|
148
188
|
VALUE
|
|
149
189
|
KernelInfo_scale_geometry(VALUE self, VALUE geometry)
|
|
150
190
|
{
|
|
151
|
-
GVL_STRUCT_TYPE(ScaleGeometryKernelInfo) args = { (
|
|
191
|
+
GVL_STRUCT_TYPE(ScaleGeometryKernelInfo) args = { get_kernel_info(self), StringValueCStr(geometry) };
|
|
152
192
|
CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ScaleGeometryKernelInfo), &args);
|
|
153
193
|
return Qnil;
|
|
154
194
|
}
|
|
@@ -161,7 +201,7 @@ KernelInfo_scale_geometry(VALUE self, VALUE geometry)
|
|
|
161
201
|
VALUE
|
|
162
202
|
KernelInfo_clone(VALUE self)
|
|
163
203
|
{
|
|
164
|
-
KernelInfo *kernel = CloneKernelInfo((
|
|
204
|
+
KernelInfo *kernel = CloneKernelInfo(get_kernel_info(self));
|
|
165
205
|
if (!kernel)
|
|
166
206
|
{
|
|
167
207
|
rb_raise(rb_eNoMemError, "not enough memory to continue");
|
data/ext/RMagick/rmpixel.cpp
CHANGED
|
@@ -473,8 +473,8 @@ Color_Name_to_PixelColor(PixelColor *color, VALUE name_arg)
|
|
|
473
473
|
char *name;
|
|
474
474
|
ExceptionInfo *exception;
|
|
475
475
|
|
|
476
|
-
exception = AcquireExceptionInfo();
|
|
477
476
|
name = StringValueCStr(name_arg);
|
|
477
|
+
exception = AcquireExceptionInfo();
|
|
478
478
|
okay = QueryColorCompliance(name, AllCompliance, color, exception);
|
|
479
479
|
DestroyExceptionInfo(exception);
|
|
480
480
|
if (!okay)
|
|
@@ -683,15 +683,16 @@ Pixel_from_color(VALUE klass ATTRIBUTE_UNUSED, VALUE name)
|
|
|
683
683
|
PixelColor pp;
|
|
684
684
|
ExceptionInfo *exception;
|
|
685
685
|
MagickBooleanType okay;
|
|
686
|
+
char *color = StringValueCStr(name);
|
|
686
687
|
|
|
687
688
|
exception = AcquireExceptionInfo();
|
|
688
|
-
okay = QueryColorCompliance(
|
|
689
|
+
okay = QueryColorCompliance(color, AllCompliance, &pp, exception);
|
|
689
690
|
CHECK_EXCEPTION();
|
|
690
691
|
DestroyExceptionInfo(exception);
|
|
691
692
|
|
|
692
693
|
if (!okay)
|
|
693
694
|
{
|
|
694
|
-
rb_raise(rb_eArgError, "invalid color name: %s",
|
|
695
|
+
rb_raise(rb_eArgError, "invalid color name: %s", color);
|
|
695
696
|
}
|
|
696
697
|
|
|
697
698
|
return Pixel_from_PixelColor(&pp);
|
|
@@ -739,19 +740,19 @@ Pixel_from_hsla(int argc, VALUE *argv, VALUE klass ATTRIBUTE_UNUSED)
|
|
|
739
740
|
break;
|
|
740
741
|
}
|
|
741
742
|
|
|
742
|
-
if (alpha && (a
|
|
743
|
+
if (alpha && !(a >= 0.0 && a <= 1.0))
|
|
743
744
|
{
|
|
744
745
|
rb_raise(rb_eRangeError, "alpha %g out of range [0.0, 1.0]", a);
|
|
745
746
|
}
|
|
746
|
-
if (l
|
|
747
|
+
if (!(l >= 0.0 && l <= 255.0))
|
|
747
748
|
{
|
|
748
749
|
rb_raise(rb_eRangeError, "lightness %g out of range [0.0, 255.0]", l);
|
|
749
750
|
}
|
|
750
|
-
if (s
|
|
751
|
+
if (!(s >= 0.0 && s <= 255.0))
|
|
751
752
|
{
|
|
752
753
|
rb_raise(rb_eRangeError, "saturation %g out of range [0.0, 255.0]", s);
|
|
753
754
|
}
|
|
754
|
-
if (h
|
|
755
|
+
if (!(h >= 0.0 && h < 360.0))
|
|
755
756
|
{
|
|
756
757
|
rb_raise(rb_eRangeError, "hue %g out of range [0.0, 360.0)", h);
|
|
757
758
|
}
|
|
@@ -1045,6 +1046,9 @@ Pixel_marshal_load(VALUE self, VALUE dpixel)
|
|
|
1045
1046
|
Pixel *pixel;
|
|
1046
1047
|
|
|
1047
1048
|
TypedData_Get_Struct(self, Pixel, &rm_pixel_data_type, pixel);
|
|
1049
|
+
|
|
1050
|
+
Check_Type(dpixel, T_HASH);
|
|
1051
|
+
|
|
1048
1052
|
pixel->red = NUM2QUANTUM(rb_hash_aref(dpixel, CSTR2SYM("red")));
|
|
1049
1053
|
pixel->green = NUM2QUANTUM(rb_hash_aref(dpixel, CSTR2SYM("green")));
|
|
1050
1054
|
pixel->blue = NUM2QUANTUM(rb_hash_aref(dpixel, CSTR2SYM("blue")));
|
|
@@ -1269,8 +1273,7 @@ Pixel_to_color(int argc, VALUE *argv, VALUE self)
|
|
|
1269
1273
|
rm_init_magickpixel(image, &mpp);
|
|
1270
1274
|
rm_set_magick_pixel_packet(pixel, &mpp);
|
|
1271
1275
|
|
|
1272
|
-
|
|
1273
|
-
// in 6.4.1-9. The 'hex' argument was removed as well.
|
|
1276
|
+
MagickBooleanType okay = MagickTrue;
|
|
1274
1277
|
if (hex)
|
|
1275
1278
|
{
|
|
1276
1279
|
if (compliance == XPMCompliance)
|
|
@@ -1286,14 +1289,18 @@ Pixel_to_color(int argc, VALUE *argv, VALUE self)
|
|
|
1286
1289
|
}
|
|
1287
1290
|
else
|
|
1288
1291
|
{
|
|
1289
|
-
QueryColorname(image, &mpp, compliance, name, exception);
|
|
1292
|
+
okay = QueryColorname(image, &mpp, compliance, name, exception);
|
|
1290
1293
|
}
|
|
1291
1294
|
|
|
1292
1295
|
DestroyImage(image);
|
|
1293
1296
|
CHECK_EXCEPTION();
|
|
1294
1297
|
DestroyExceptionInfo(exception);
|
|
1295
1298
|
|
|
1296
|
-
|
|
1299
|
+
if (!okay)
|
|
1300
|
+
{
|
|
1301
|
+
rb_raise(Class_ImageMagickError, "QueryColorname failed (unsupported colorspace)");
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1297
1304
|
return rb_str_new2(name);
|
|
1298
1305
|
}
|
|
1299
1306
|
|
data/lib/rmagick/version.rb
CHANGED
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.0.
|
|
4
|
+
version: 7.0.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tim Hunter
|
|
@@ -143,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
143
143
|
version: '0'
|
|
144
144
|
requirements:
|
|
145
145
|
- ImageMagick 6.9.0+ (for ImageMagick 6) or 7.1.0+ (for ImageMagick 7)
|
|
146
|
-
rubygems_version: 4.0.
|
|
146
|
+
rubygems_version: 4.0.15
|
|
147
147
|
specification_version: 4
|
|
148
148
|
summary: Ruby binding to ImageMagick
|
|
149
149
|
test_files: []
|