rmagick 1.9.3 → 1.10.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rmagick might be problematic. Click here for more details.
- data/ChangeLog +18 -0
- data/README.html +12 -12
- data/README.txt +10 -10
- data/configure +728 -367
- data/configure.ac +134 -69
- data/doc/comtasks.html +11 -3
- data/doc/constants.html +162 -40
- data/doc/draw.html +2 -2
- data/doc/ex/crop_resized.rb +10 -0
- data/doc/ex/get_type_metrics.rb +26 -22
- data/doc/ex/vignette.rb +19 -0
- data/doc/ilist.html +0 -5
- data/doc/image1.html +219 -49
- data/doc/image2.html +115 -47
- data/doc/image3.html +105 -23
- data/doc/imageattrs.html +4 -23
- data/doc/imusage.html +1 -1
- data/doc/index.html +8 -9
- data/doc/info.html +23 -3
- data/doc/magick.html +1 -1
- data/doc/rvg.html +1 -1
- data/doc/rvgclip.html +1 -1
- data/doc/rvggroup.html +1 -1
- data/doc/rvgimage.html +1 -1
- data/doc/rvgpattern.html +1 -1
- data/doc/rvgshape.html +1 -1
- data/doc/rvgstyle.html +1 -1
- data/doc/rvgtext.html +3 -3
- data/doc/rvgtspan.html +1 -1
- data/doc/rvgtut.html +119 -101
- data/doc/rvguse.html +1 -1
- data/doc/rvgxform.html +1 -1
- data/doc/struct.html +17 -11
- data/doc/usage.html +22 -4
- data/examples/histogram.rb +48 -12
- data/examples/spinner.rb +49 -0
- data/ext/RMagick/MANIFEST +4 -1
- data/ext/RMagick/rmagick.h +62 -33
- data/ext/RMagick/rmagick_config.h.in +28 -31
- data/ext/RMagick/rmdraw.c +14 -6
- data/ext/RMagick/rmfill.c +2 -2
- data/ext/RMagick/rmilist.c +8 -36
- data/ext/RMagick/rmimage.c +370 -97
- data/ext/RMagick/rminfo.c +6 -6
- data/ext/RMagick/rmmain.c +114 -25
- data/ext/RMagick/rmutil.c +98 -35
- data/lib/RMagick.rb +17 -2
- data/lib/rvg/clippath.rb +2 -2
- data/lib/rvg/container.rb +2 -2
- data/lib/rvg/describable.rb +2 -2
- data/lib/rvg/embellishable.rb +2 -2
- data/lib/rvg/misc.rb +3 -3
- data/lib/rvg/paint.rb +2 -2
- data/lib/rvg/pathdata.rb +2 -2
- data/lib/rvg/rvg.rb +2 -2
- data/lib/rvg/stretchable.rb +2 -2
- data/lib/rvg/stylable.rb +2 -2
- data/lib/rvg/text.rb +2 -2
- data/lib/rvg/transformable.rb +2 -2
- data/lib/rvg/units.rb +2 -2
- data/rmagick.gemspec +1 -1
- metadata +362 -353
@@ -3,20 +3,20 @@
|
|
3
3
|
#undef HAVE_ACQUIREMAGICKMEMORY
|
4
4
|
/* Introduced in IM 6.0.0 */
|
5
5
|
#undef HAVE_ACQUIRESTRINGINFO
|
6
|
-
/*
|
7
|
-
#undef HAVE_ADAPTIVETHRESHOLDIMAGE
|
8
|
-
/* Introduced in GM 1.1 */
|
6
|
+
/* GraphicsMagick only */
|
9
7
|
#undef HAVE_ADDDEFINITIONS
|
8
|
+
/* Introduced in IM 6.2.5 */
|
9
|
+
#undef HAVE_ADDNOISEIMAGECHANNEL
|
10
10
|
/* Introduced in IM 6.0.0, GM 1.1 */
|
11
11
|
#undef HAVE_ALLCHANNELS
|
12
|
-
/* Introduced in IM 5.5.2, GM 1.0 */
|
13
|
-
#undef HAVE_APPENDIMAGETOLIST
|
14
12
|
/* Introduced in IM 6.0.0 */
|
15
13
|
#undef HAVE_BILEVELIMAGECHANNEL
|
16
14
|
/* Introduced in IM 5.5.7, GM 1.1 */
|
17
15
|
#undef HAVE_BLACKTHRESHOLDIMAGE
|
18
16
|
/* Introduced in IM 6.0.1 */
|
19
17
|
#undef HAVE_BLURIMAGECHANNEL
|
18
|
+
/* Introduced in GM 1.2 */
|
19
|
+
#undef HAVE_CINEONLOGRGBCOLORSPACE
|
20
20
|
/* Introduced in IM 6.0.0 */
|
21
21
|
#undef HAVE_COLORDODGECOMPOSITEOP
|
22
22
|
/* Introduced in IM 6.0.0, GM 1.1 */
|
@@ -25,8 +25,6 @@
|
|
25
25
|
#undef HAVE_CONVOLVEIMAGECHANNEL
|
26
26
|
/* Introduced in IM 5.5.7, GM 1.1 */
|
27
27
|
#undef HAVE_COPYCYANCOMPOSITEOP
|
28
|
-
/* Introduced in IM 5.5.1, GM 1.0 */
|
29
|
-
#undef HAVE_DISPOSETYPE
|
30
28
|
/* Introduced in IM 6.0.0 */
|
31
29
|
#undef HAVE_DSTCOMPOSITEOP
|
32
30
|
/* Introduced in IM 6.0.1 */
|
@@ -39,7 +37,7 @@
|
|
39
37
|
/* Introduced in IM 5.5.2, deprecated in IM 6.0.0 */
|
40
38
|
#undef HAVE_EXTENDEDSIGNEDINTEGRALTYPE
|
41
39
|
#undef HAVE_EXTENDEDUNSIGNEDINTEGRALTYPE
|
42
|
-
/* Introduced in IM 5.5.5 */
|
40
|
+
/* Introduced in IM 5.5.5 - Not defined in GraphicsMagick */
|
43
41
|
#undef HAVE_FUZZYCOLORCOMPARE
|
44
42
|
/* Introduced in IM 6.0.0, GM 1.1 */
|
45
43
|
#undef HAVE_GAMMAIMAGECHANNEL
|
@@ -73,10 +71,6 @@
|
|
73
71
|
#undef HAVE_OLD_GETIMAGEQUANTUMDEPTH
|
74
72
|
/* Introduced in GM 1.1 */
|
75
73
|
#undef HAVE_GETIMAGESTATISTICS
|
76
|
-
/* Introduced in IM 5.5.2, GM 1.0 */
|
77
|
-
#undef HAVE_GETLOCALEEXCEPTIONMESSAGE
|
78
|
-
/* Introduced in IM 5.5.1, GM 1.0 */
|
79
|
-
#undef HAVE_GETMAGICKGEOMETRY
|
80
74
|
/* Introduced in GM 1.1 */
|
81
75
|
#undef HAVE_GETMAGICKINFOARRAY
|
82
76
|
/* Introduced in IM 6.0.1 */
|
@@ -85,8 +79,8 @@
|
|
85
79
|
#undef HAVE_GETMULTILINETYPEMETRICS
|
86
80
|
/* API changed in IM 6.1.3 */
|
87
81
|
#undef HAVE_OLD_GETMAGICKINFOLIST
|
82
|
+
/* Introduced in IM 6.2.1 */
|
88
83
|
#undef HAVE_GETNEXTIMAGEATTRIBUTE
|
89
|
-
#undef HAVE_GETNEXTIMAGEINLIST
|
90
84
|
/* Introduced in IM 6.0.0 */
|
91
85
|
#undef HAVE_GETNEXTIMAGEPROFILE
|
92
86
|
/* Introduced in IM 6.0.1 */
|
@@ -96,31 +90,29 @@
|
|
96
90
|
#undef HAVE_GRAYCHANNEL
|
97
91
|
/* Introduced in GM 1.0 */
|
98
92
|
#undef HAVE_GRAYSCALEPSEUDOCLASSIMAGE
|
99
|
-
/* Introduced in IM 6.0.0 */
|
93
|
+
/* Introduced in IM 6.0.0 - Not available in GM */
|
100
94
|
#undef HAVE_HSBCOLORSPACE
|
101
|
-
/* Introduced in IM 5.5.7, GM 1.0 */
|
102
|
-
#undef HAVE_HSLCOLORSPACE
|
103
|
-
/* Introduced in IM 5.5.7, GM 1.0 */
|
104
|
-
#undef HAVE_HWBCOLORSPACE
|
105
|
-
/* Introduced in IM 6.0.0, GM 1.1 */
|
106
95
|
#undef HAVE_INDEXCHANNEL
|
107
|
-
/* Introduced in IM 5.5.6 */
|
96
|
+
/* Introduced in IM 5.5.6 - Not available in GM */
|
108
97
|
#undef HAVE_IMAGE_EXTRACT_INFO
|
109
98
|
/* Introduced in IM 6.0.0 */
|
110
99
|
#undef HAVE_IMAGE_QUALITY
|
111
100
|
/* Introduced in IM 6.0.0 */
|
112
101
|
#undef HAVE_IMAGE_ORIENTATION
|
102
|
+
#undef HAVE_IMAGEINFO_ORIENTATION
|
113
103
|
/* Introduced in IM 6.2.4 */
|
114
104
|
#undef HAVE_IMAGE_TICKS_PER_SECOND
|
115
|
-
/* Introduced in IM 5.5.6 */
|
116
|
-
#undef HAVE_IMAGEINFO_NUMBER_SCENES
|
117
105
|
/* Introduced in IM 5.5.7, GM 1.1 */
|
118
106
|
#undef HAVE_IMPORTIMAGEPIXELS
|
119
107
|
#undef HAVE_INTTYPES_H
|
108
|
+
/* Introduced in IM 6.2.5 */
|
109
|
+
#undef HAVE_ISCOLORSIMILAR
|
120
110
|
/* Introduced in IM 6.2.2 */
|
121
111
|
#undef HAVE_JPEG2000COMPRESSION
|
122
|
-
/* Introduced in
|
123
|
-
#undef
|
112
|
+
/* Introduced in GM 1.2 */
|
113
|
+
#undef HAVE_LABCOLORSPACE
|
114
|
+
/* Introduced in IM 6.2.3 */
|
115
|
+
#undef HAVE_LOGCOLORSPACE
|
124
116
|
/* Introduced in IM 6.0.2 */
|
125
117
|
#undef HAVE_MAGICKBOOLEANTYPE
|
126
118
|
/* Introduced in IM 5.5.3, GM 1.0 */
|
@@ -133,36 +125,40 @@
|
|
133
125
|
#undef HAVE_MEMORY_H
|
134
126
|
/* Introduced in IM 6.0.0, GM 1.1 */
|
135
127
|
#undef HAVE_NEGATEIMAGECHANNEL
|
136
|
-
/* Introduced in IM 5.5.1, GM 1.0 */
|
137
|
-
#undef HAVE_NOCOMPLIANCE
|
138
128
|
/* Introduced in IM 6.1.0 */
|
139
129
|
#undef HAVE_NORMALIZEIMAGECHANNEL
|
140
|
-
/* Introduced in IM 5.5.4 */
|
130
|
+
/* Introduced in IM 5.5.4 - Not available in GM */
|
141
131
|
#undef HAVE_PARSESIZEGEOMETRY
|
142
132
|
/* Introduced in IM 6.0.0 */
|
143
133
|
#undef HAVE_POSTERIZEIMAGE
|
144
|
-
/* Introduced in IM 5.5.1
|
134
|
+
/* Introduced in IM 5.5.1? Not available in GM */
|
145
135
|
#undef HAVE_PREVIEWIMAGE
|
146
136
|
#undef HAVE_QUANTUMOPERATORREGIONIMAGE
|
147
137
|
/* Introduced in IM 6.2.0 */
|
148
138
|
#undef HAVE_QUANTUMPIXEL
|
139
|
+
/* Not available in GM */
|
149
140
|
#undef HAVE_RADIALBLURIMAGE
|
150
141
|
#undef HAVE_RANDOMCHANNELTHRESHOLDIMAGE
|
151
142
|
#undef HAVE_RANDOMTHRESHOLDIMAGECHANNEL
|
152
|
-
|
143
|
+
/* Introduced in GM 1.2 & IM 6.2.2 */
|
144
|
+
#undef HAVE_REC601LUMACOLORSPACE
|
145
|
+
#undef HAVE_REC601YCBCRCOLORSPACE
|
146
|
+
#undef HAVE_REC709LUMACOLORSPACE
|
147
|
+
#undef HAVE_REC709YCBCRCOLORSPACE
|
153
148
|
/* Introduced in IM 6.2.1 */
|
154
149
|
#undef HAVE_NEW_REMOVEIMAGEPROFILE
|
155
150
|
#undef HAVE_REPLACECOMPOSITEOP
|
156
151
|
#undef HAVE_SEPARATEIMAGECHANNEL
|
157
152
|
/* Introduced in IM 6.2.1 */
|
158
153
|
#undef HAVE_SEPIATONEIMAGE
|
154
|
+
/* Introduced in IM 6.2.1 */
|
155
|
+
#undef HAVE_SETIMAGEBACKGROUNDCOLOR
|
159
156
|
#undef HAVE_SETIMAGECOLORSPACE
|
160
157
|
/* Introduced in IM 6.0.0, GM 1.1 */
|
161
158
|
#undef HAVE_SETIMAGECHANNELDEPTH
|
162
159
|
#undef HAVE_SETIMAGEOPTION
|
163
160
|
/* Introduced in IM 6.1.0 */
|
164
161
|
#undef HAVE_SETIMAGEPROGRESSMONITOR
|
165
|
-
#undef HAVE_SETLOGFORMAT
|
166
162
|
/* Introduced in IM 6.1.7 */
|
167
163
|
#undef HAVE_SHADOWIMAGE
|
168
164
|
/* Introduced in IM 6.0.1 */
|
@@ -179,7 +175,6 @@
|
|
179
175
|
#undef HAVE_SYS_STAT_H
|
180
176
|
#undef HAVE_SYS_TYPES_H
|
181
177
|
#undef HAVE_THRESHOLDIMAGECHANNEL
|
182
|
-
#undef HAVE_THUMBNAILIMAGE
|
183
178
|
#undef HAVE_TINTIMAGE
|
184
179
|
/* Introduced in IM 6.2.4 */
|
185
180
|
#undef HAVE_TRANSPARENTVIRTUALPIXELMETHOD
|
@@ -189,6 +184,8 @@
|
|
189
184
|
/* Introduced in IM 6.1.0 */
|
190
185
|
#undef HAVE_UNSHARPMASKIMAGECHANNEL
|
191
186
|
#undef HAVE_WHITETHRESHOLDIMAGE
|
187
|
+
/* Introduced in IM 6.2.6 */
|
188
|
+
#undef HAVE_VIGNETTEIMAGE
|
192
189
|
#undef HAVE_XIMPORTIMAGE
|
193
190
|
#undef MAGICKNAME
|
194
191
|
#undef PACKAGE_BUGREPORT
|
data/ext/RMagick/rmdraw.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
/* $Id: rmdraw.c,v 1.
|
1
|
+
/* $Id: rmdraw.c,v 1.27 2005/12/31 14:40:50 rmagick Exp $ */
|
2
2
|
/*============================================================================\
|
3
|
-
| Copyright (C)
|
3
|
+
| Copyright (C) 2006 by Timothy P. Hunter
|
4
4
|
| Name: rmdraw.c
|
5
5
|
| Author: Tim Hunter
|
6
6
|
| Purpose: Contains Draw class methods.
|
@@ -412,8 +412,12 @@ VALUE Draw_annotate(
|
|
412
412
|
rm_check_frozen(ImageList_cur_image(image_arg));
|
413
413
|
Data_Get_Struct(ImageList_cur_image(image_arg), Image, image);
|
414
414
|
|
415
|
-
//
|
416
|
-
|
415
|
+
// Translate & store in Draw structure
|
416
|
+
draw->info->text = TranslateText(NULL, image, STRING_PTR(text));
|
417
|
+
if (!draw->info->text)
|
418
|
+
{
|
419
|
+
rb_raise(rb_eArgError, "no text");
|
420
|
+
}
|
417
421
|
|
418
422
|
// Create geometry string, copy to Draw structure, overriding
|
419
423
|
// any previously existing value.
|
@@ -1300,14 +1304,18 @@ get_type_metrics(
|
|
1300
1304
|
}
|
1301
1305
|
|
1302
1306
|
Data_Get_Struct(self, Draw, draw);
|
1303
|
-
|
1307
|
+
draw->info->text = TranslateText(NULL, image, text);
|
1308
|
+
if (!draw->info->text)
|
1309
|
+
{
|
1310
|
+
rb_raise(rb_eArgError, "no text to measure");
|
1311
|
+
}
|
1304
1312
|
|
1305
1313
|
okay = (*getter)(image, draw->info, &metrics);
|
1306
1314
|
|
1307
1315
|
if (!okay)
|
1308
1316
|
{
|
1309
1317
|
rb_raise(rb_eRuntimeError, "Can't measure text. Are the fonts installed? "
|
1310
|
-
"
|
1318
|
+
"Is the FreeType library installed?");
|
1311
1319
|
}
|
1312
1320
|
return TypeMetric_from_TypeMetric(&metrics);
|
1313
1321
|
}
|
data/ext/RMagick/rmfill.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
/* $Id: rmfill.c,v 1.
|
1
|
+
/* $Id: rmfill.c,v 1.13 2005/12/31 14:40:50 rmagick Exp $ */
|
2
2
|
/*============================================================================\
|
3
|
-
| Copyright (C)
|
3
|
+
| Copyright (C) 2006 by Timothy P. Hunter
|
4
4
|
| Name: rmfill.c
|
5
5
|
| Author: Tim Hunter
|
6
6
|
| Purpose: GradientFill, TextureFill class definitions for RMagick
|
data/ext/RMagick/rmilist.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
/* $Id: rmilist.c,v 1.
|
1
|
+
/* $Id: rmilist.c,v 1.30 2006/01/06 23:55:53 rmagick Exp $ */
|
2
2
|
/*============================================================================\
|
3
|
-
| Copyright (C)
|
3
|
+
| Copyright (C) 2006 by Timothy P. Hunter
|
4
4
|
| Name: rmilist.c
|
5
5
|
| Author: Tim Hunter
|
6
6
|
| Purpose: ImageList class method definitions for RMagick
|
@@ -36,7 +36,7 @@ ImageList_animate(int argc, VALUE *argv, VALUE self)
|
|
36
36
|
unsigned int delay;
|
37
37
|
|
38
38
|
delay = NUM2UINT(argv[0]);
|
39
|
-
for (img = images; img; img =
|
39
|
+
for (img = images; img; img = GetNextImageInList(img))
|
40
40
|
{
|
41
41
|
img->delay = delay;
|
42
42
|
}
|
@@ -275,7 +275,7 @@ ImageList_montage(VALUE self)
|
|
275
275
|
if (montage->compose != UndefinedCompositeOp)
|
276
276
|
{
|
277
277
|
Image *i;
|
278
|
-
for (i = image_list; i; i =
|
278
|
+
for (i = image_list; i; i = GetNextImageInList(i))
|
279
279
|
{
|
280
280
|
i->compose = montage->compose;
|
281
281
|
}
|
@@ -321,6 +321,7 @@ ImageList_morph(VALUE self, VALUE nimages)
|
|
321
321
|
images = rm_images_from_imagelist(self);
|
322
322
|
GetExceptionInfo(&exception);
|
323
323
|
new_images = MorphImages(images, (unsigned long)number_images, &exception);
|
324
|
+
rm_split(images);
|
324
325
|
HANDLE_ERROR
|
325
326
|
|
326
327
|
return rm_imagelist_from_images(new_images);
|
@@ -368,7 +369,6 @@ VALUE
|
|
368
369
|
rm_imagelist_from_images(Image *images)
|
369
370
|
{
|
370
371
|
volatile VALUE new_imagelist;
|
371
|
-
#if defined(HAVE_REMOVEFIRSTIMAGEFROMLIST)
|
372
372
|
Image *image;
|
373
373
|
|
374
374
|
new_imagelist = rm_imagelist_new();
|
@@ -378,18 +378,6 @@ rm_imagelist_from_images(Image *images)
|
|
378
378
|
image = RemoveFirstImageFromList(&images);
|
379
379
|
rm_imagelist_push(new_imagelist, rm_image_new(image));
|
380
380
|
}
|
381
|
-
#else
|
382
|
-
Image *image, *next;
|
383
|
-
|
384
|
-
new_imagelist = rm_imagelist_new();
|
385
|
-
|
386
|
-
for (image = images; image; image = next)
|
387
|
-
{
|
388
|
-
next = GET_NEXT_IMAGE(image);
|
389
|
-
image->previous = image->next = NULL;
|
390
|
-
rm_imagelist_push(new_imagelist, rm_image_new(image));
|
391
|
-
}
|
392
|
-
#endif
|
393
381
|
|
394
382
|
rb_iv_set(new_imagelist, "@scene", INT2FIX(0));
|
395
383
|
return new_imagelist;
|
@@ -407,9 +395,6 @@ rm_images_from_imagelist(VALUE imagelist)
|
|
407
395
|
{
|
408
396
|
long x, len;
|
409
397
|
Image *head = NULL;
|
410
|
-
#if !defined(HAVE_APPENDIMAGETOLIST)
|
411
|
-
Image *tail = NULL;
|
412
|
-
#endif
|
413
398
|
|
414
399
|
Check_Type(imagelist, T_ARRAY);
|
415
400
|
len = rm_imagelist_length(imagelist);
|
@@ -423,20 +408,7 @@ rm_images_from_imagelist(VALUE imagelist)
|
|
423
408
|
Image *image;
|
424
409
|
|
425
410
|
Data_Get_Struct(rb_ary_entry(imagelist, x), Image, image);
|
426
|
-
#if defined(HAVE_APPENDIMAGETOLIST)
|
427
411
|
AppendImageToList(&head, image);
|
428
|
-
#else
|
429
|
-
if (!head)
|
430
|
-
{
|
431
|
-
head = image;
|
432
|
-
}
|
433
|
-
else
|
434
|
-
{
|
435
|
-
image->previous = tail;
|
436
|
-
tail->next = image;
|
437
|
-
}
|
438
|
-
tail = image;
|
439
|
-
#endif
|
440
412
|
}
|
441
413
|
|
442
414
|
return head;
|
@@ -573,7 +545,7 @@ ImageList_to_blob(VALUE self)
|
|
573
545
|
if (*info->magick != '\0')
|
574
546
|
{
|
575
547
|
Image *img;
|
576
|
-
for (img = images; img; img =
|
548
|
+
for (img = images; img; img = GetNextImageInList(img))
|
577
549
|
{
|
578
550
|
strncpy(img->magick, info->magick, sizeof(info->magick)-1);
|
579
551
|
}
|
@@ -657,7 +629,7 @@ ImageList_write(VALUE self, VALUE file)
|
|
657
629
|
|
658
630
|
// Copy the filename into each images. Set a scene number to be used if
|
659
631
|
// writing multiple files. (Ref: ImageMagick's utilities/convert.c
|
660
|
-
for (scene = 0, img = images; img; img =
|
632
|
+
for (scene = 0, img = images; img; img = GetNextImageInList(img))
|
661
633
|
{
|
662
634
|
img->scene = scene++;
|
663
635
|
strcpy(img->filename, info->filename);
|
@@ -676,7 +648,7 @@ ImageList_write(VALUE self, VALUE file)
|
|
676
648
|
info->adjoin = True;
|
677
649
|
}
|
678
650
|
|
679
|
-
for (img = images; img; img =
|
651
|
+
for (img = images; img; img = GetNextImageInList(img))
|
680
652
|
{
|
681
653
|
(void) WriteImage(info, img);
|
682
654
|
// images will be split before raising an exception
|
data/ext/RMagick/rmimage.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
/* $Id: rmimage.c,v 1.
|
1
|
+
/* $Id: rmimage.c,v 1.139 2006/01/18 00:22:33 rmagick Exp $ */
|
2
2
|
/*============================================================================\
|
3
|
-
| Copyright (C)
|
3
|
+
| Copyright (C) 2006 by Timothy P. Hunter
|
4
4
|
| Name: rmimage.c
|
5
5
|
| Author: Tim Hunter
|
6
6
|
| Purpose: Image class method definitions for RMagick
|
@@ -26,7 +26,7 @@ typedef Image *(xformer_t)(const Image *, const RectangleInfo *, ExceptionInfo *
|
|
26
26
|
|
27
27
|
static VALUE effect_image(VALUE, int, VALUE *, effector_t *);
|
28
28
|
static VALUE rd_image(VALUE, VALUE, reader_t);
|
29
|
-
static VALUE
|
29
|
+
static VALUE scale(int, int, VALUE *, VALUE, scaler_t *);
|
30
30
|
static VALUE cropper(int, int, VALUE *, VALUE);
|
31
31
|
static VALUE xform_image(int, VALUE, VALUE, VALUE, VALUE, VALUE, xformer_t);
|
32
32
|
static VALUE threshold_image(int, VALUE *, VALUE, thresholder_t);
|
@@ -47,7 +47,6 @@ static ImageAttribute *Next_Attribute;
|
|
47
47
|
VALUE
|
48
48
|
Image_adaptive_threshold(int argc, VALUE *argv, VALUE self)
|
49
49
|
{
|
50
|
-
#ifdef HAVE_ADAPTIVETHRESHOLDIMAGE
|
51
50
|
Image *image, *new_image;
|
52
51
|
unsigned long width = 3, height = 3, offset = 0;
|
53
52
|
ExceptionInfo exception;
|
@@ -72,10 +71,6 @@ Image_adaptive_threshold(int argc, VALUE *argv, VALUE self)
|
|
72
71
|
new_image = AdaptiveThresholdImage(image, width, height, offset, &exception);
|
73
72
|
HANDLE_ERROR
|
74
73
|
return rm_image_new(new_image);
|
75
|
-
#else
|
76
|
-
rm_not_implemented();
|
77
|
-
return (VALUE)0;
|
78
|
-
#endif
|
79
74
|
}
|
80
75
|
|
81
76
|
/*
|
@@ -87,18 +82,60 @@ VALUE
|
|
87
82
|
Image_add_noise(VALUE self, VALUE noise)
|
88
83
|
{
|
89
84
|
Image *image, *new_image;
|
90
|
-
NoiseType
|
85
|
+
NoiseType noise_type;
|
91
86
|
ExceptionInfo exception;
|
92
87
|
|
93
88
|
Data_Get_Struct(self, Image, image);
|
89
|
+
|
94
90
|
GetExceptionInfo(&exception);
|
91
|
+
VALUE_TO_ENUM(noise, noise_type, NoiseType);
|
95
92
|
|
96
|
-
|
97
|
-
new_image = AddNoiseImage(image, nt, &exception);
|
93
|
+
new_image = AddNoiseImage(image, noise_type, &exception);
|
98
94
|
HANDLE_ERROR
|
99
95
|
return rm_image_new(new_image);
|
100
96
|
}
|
101
97
|
|
98
|
+
/*
|
99
|
+
Method: Image#add_noise_channel(noise_type[,channel...])
|
100
|
+
Purpose: add random noise to a copy of the image
|
101
|
+
Returns: a new image
|
102
|
+
*/
|
103
|
+
VALUE
|
104
|
+
Image_add_noise_channel(int argc, VALUE *argv, VALUE self)
|
105
|
+
{
|
106
|
+
#if defined(HAVE_ADDNOISEIMAGECHANNEL)
|
107
|
+
Image *image, *new_image;
|
108
|
+
NoiseType noise_type;
|
109
|
+
ExceptionInfo exception;
|
110
|
+
ChannelType channels;
|
111
|
+
|
112
|
+
channels = extract_channels(&argc, argv);
|
113
|
+
|
114
|
+
// There must be 1 remaining argument.
|
115
|
+
if (argc == 0)
|
116
|
+
{
|
117
|
+
rb_raise(rb_eArgError, "missing noise type argument");
|
118
|
+
}
|
119
|
+
else if (argc > 1)
|
120
|
+
{
|
121
|
+
raise_ChannelType_error(argv[argc-1]);
|
122
|
+
}
|
123
|
+
|
124
|
+
Data_Get_Struct(self, Image, image);
|
125
|
+
GetExceptionInfo(&exception);
|
126
|
+
VALUE_TO_ENUM(argv[0], noise_type, NoiseType);
|
127
|
+
channels &= ~OpacityChannel;
|
128
|
+
|
129
|
+
new_image = AddNoiseImageChannel(image, channels, noise_type, &exception);
|
130
|
+
HANDLE_ERROR
|
131
|
+
return rm_image_new(new_image);
|
132
|
+
|
133
|
+
#else
|
134
|
+
rm_not_implemented();
|
135
|
+
return (VALUE)0;
|
136
|
+
#endif
|
137
|
+
}
|
138
|
+
|
102
139
|
/*
|
103
140
|
Method: Image#affine_transform(affine_matrix)
|
104
141
|
Purpose: transforms an image as dictated by the affine matrix argument
|
@@ -634,7 +671,7 @@ Image_change_geometry(VALUE self, VALUE geom_arg)
|
|
634
671
|
|
635
672
|
return rb_yield(ary);
|
636
673
|
|
637
|
-
#
|
674
|
+
#else
|
638
675
|
Image *image;
|
639
676
|
char *geometry;
|
640
677
|
unsigned int flags;
|
@@ -663,9 +700,6 @@ Image_change_geometry(VALUE self, VALUE geom_arg)
|
|
663
700
|
|
664
701
|
return rb_yield(ary);
|
665
702
|
|
666
|
-
#else
|
667
|
-
rm_not_implemented();
|
668
|
-
return (VALUE)0;
|
669
703
|
#endif
|
670
704
|
}
|
671
705
|
|
@@ -1246,7 +1280,7 @@ Image_color_profile(VALUE self)
|
|
1246
1280
|
}
|
1247
1281
|
|
1248
1282
|
#else /* !defined(HAVE_ACQUIRESTRINGINFO) */
|
1249
|
-
const char *str;
|
1283
|
+
const unsigned char *str;
|
1250
1284
|
size_t length;
|
1251
1285
|
|
1252
1286
|
Data_Get_Struct(self, Image, image);
|
@@ -1256,7 +1290,7 @@ Image_color_profile(VALUE self)
|
|
1256
1290
|
str = GetImageProfile(image, "icc", &length);
|
1257
1291
|
if (str)
|
1258
1292
|
{
|
1259
|
-
profile = rb_str_new(str, length);
|
1293
|
+
profile = rb_str_new((char *)str, length);
|
1260
1294
|
}
|
1261
1295
|
|
1262
1296
|
#endif
|
@@ -1355,7 +1389,7 @@ Image_color_profile_eq(VALUE self, VALUE profile)
|
|
1355
1389
|
}
|
1356
1390
|
else
|
1357
1391
|
{
|
1358
|
-
prof = STRING_PTR_LEN(profile, prof_l);
|
1392
|
+
prof = (unsigned char *)STRING_PTR_LEN(profile, prof_l);
|
1359
1393
|
(void) SetImageProfile(image, "icc", prof, (size_t)prof_l);
|
1360
1394
|
}
|
1361
1395
|
#endif /* defined(HAVE_SETIMAGEPROFILE) */
|
@@ -2113,7 +2147,11 @@ Image_constitute(VALUE class, VALUE width_arg, VALUE height_arg
|
|
2113
2147
|
}
|
2114
2148
|
image->columns = width;
|
2115
2149
|
image->rows = height;
|
2150
|
+
#if defined(HAVE_SETIMAGEBACKGROUNDCOLOR)
|
2151
|
+
SetImageBackgroundColor(image);
|
2152
|
+
#else
|
2116
2153
|
SetImage(image, OpaqueOpacity);
|
2154
|
+
#endif
|
2117
2155
|
okay = ImportImagePixels(image, 0, 0, width, height, map, stg_type, (void *)pixels.v);
|
2118
2156
|
if (!okay)
|
2119
2157
|
{
|
@@ -2977,41 +3015,57 @@ Image_erase_bang(VALUE self)
|
|
2977
3015
|
|
2978
3016
|
rm_check_frozen(self);
|
2979
3017
|
Data_Get_Struct(self, Image, image);
|
3018
|
+
|
3019
|
+
#if defined(HAVE_SETIMAGEBACKGROUNDCOLOR)
|
3020
|
+
SetImageBackgroundColor(image);
|
3021
|
+
#else
|
2980
3022
|
SetImage(image, OpaqueOpacity);
|
3023
|
+
#endif
|
2981
3024
|
|
2982
3025
|
return self;
|
2983
3026
|
}
|
2984
3027
|
|
2985
3028
|
/*
|
2986
|
-
Method: Image#export_pixels
|
3029
|
+
Method: Image#export_pixels(x=0, y=0, cols=self.columns, rows=self.rows, map="RGB")
|
2987
3030
|
Purpose: extract image pixels in the form of an array
|
2988
3031
|
*/
|
2989
3032
|
VALUE
|
2990
|
-
Image_export_pixels(
|
2991
|
-
VALUE self,
|
2992
|
-
VALUE x_arg,
|
2993
|
-
VALUE y_arg,
|
2994
|
-
VALUE cols_arg,
|
2995
|
-
VALUE rows_arg,
|
2996
|
-
VALUE map_arg)
|
3033
|
+
Image_export_pixels(int argc, VALUE *argv, VALUE self)
|
2997
3034
|
{
|
2998
3035
|
#if defined(HAVE_EXPORTIMAGEPIXELS)
|
2999
3036
|
Image *image;
|
3000
|
-
long x_off, y_off;
|
3037
|
+
long x_off = 0L, y_off = 0L;
|
3001
3038
|
unsigned long cols, rows;
|
3002
3039
|
unsigned long n, npixels;
|
3003
3040
|
unsigned int okay;
|
3004
|
-
char *map;
|
3041
|
+
char *map = "RGB";
|
3005
3042
|
volatile unsigned int *pixels;
|
3006
3043
|
volatile VALUE ary;
|
3007
3044
|
ExceptionInfo exception;
|
3008
3045
|
|
3009
3046
|
|
3010
3047
|
Data_Get_Struct(self, Image, image);
|
3011
|
-
|
3012
|
-
|
3013
|
-
|
3014
|
-
|
3048
|
+
cols = image->columns;
|
3049
|
+
rows = image->rows;
|
3050
|
+
|
3051
|
+
switch (argc)
|
3052
|
+
{
|
3053
|
+
case 5:
|
3054
|
+
map = STRING_PTR(argv[4]);
|
3055
|
+
case 4:
|
3056
|
+
rows = NUM2ULONG(argv[3]);
|
3057
|
+
case 3:
|
3058
|
+
cols = NUM2ULONG(argv[2]);
|
3059
|
+
case 2:
|
3060
|
+
y_off = NUM2LONG(argv[1]);
|
3061
|
+
case 1:
|
3062
|
+
x_off = NUM2LONG(argv[0]);
|
3063
|
+
case 0:
|
3064
|
+
break;
|
3065
|
+
default:
|
3066
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 5)", argc);
|
3067
|
+
break;
|
3068
|
+
}
|
3015
3069
|
|
3016
3070
|
if ( x_off < 0 || x_off > image->columns
|
3017
3071
|
|| y_off < 0 || y_off > image->rows
|
@@ -3020,7 +3074,6 @@ Image_export_pixels(
|
|
3020
3074
|
rb_raise(rb_eArgError, "invalid extract geometry");
|
3021
3075
|
}
|
3022
3076
|
|
3023
|
-
map = STRING_PTR(map_arg);
|
3024
3077
|
|
3025
3078
|
npixels = cols * rows * strlen(map);
|
3026
3079
|
pixels = ALLOC_N(unsigned int, npixels);
|
@@ -3057,6 +3110,118 @@ Image_export_pixels(
|
|
3057
3110
|
#endif
|
3058
3111
|
}
|
3059
3112
|
|
3113
|
+
/*
|
3114
|
+
Method: Image#export_pixels_to_str(x=0, y=0, cols=self.columns,
|
3115
|
+
rows=self.rows, map="RGB", type=Magick::CharPixel)
|
3116
|
+
Purpose: extract image pixels to a Ruby string
|
3117
|
+
*/
|
3118
|
+
VALUE
|
3119
|
+
Image_export_pixels_to_str(int argc, VALUE *argv, VALUE self)
|
3120
|
+
{
|
3121
|
+
#if defined(HAVE_EXPORTIMAGEPIXELS)
|
3122
|
+
Image *image;
|
3123
|
+
long x_off = 0L, y_off = 0L;
|
3124
|
+
unsigned long cols, rows;
|
3125
|
+
unsigned long npixels;
|
3126
|
+
size_t sz;
|
3127
|
+
unsigned int okay;
|
3128
|
+
char *map = "RGB";
|
3129
|
+
StorageType type = CharPixel;
|
3130
|
+
volatile VALUE string;
|
3131
|
+
char *str;
|
3132
|
+
ExceptionInfo exception;
|
3133
|
+
|
3134
|
+
Data_Get_Struct(self, Image, image);
|
3135
|
+
cols = image->columns;
|
3136
|
+
rows = image->rows;
|
3137
|
+
|
3138
|
+
switch (argc)
|
3139
|
+
{
|
3140
|
+
case 6:
|
3141
|
+
VALUE_TO_ENUM(argv[5], type, StorageType);
|
3142
|
+
case 5:
|
3143
|
+
map = STRING_PTR(argv[4]);
|
3144
|
+
case 4:
|
3145
|
+
rows = NUM2ULONG(argv[3]);
|
3146
|
+
case 3:
|
3147
|
+
cols = NUM2ULONG(argv[2]);
|
3148
|
+
case 2:
|
3149
|
+
y_off = NUM2LONG(argv[1]);
|
3150
|
+
case 1:
|
3151
|
+
x_off = NUM2LONG(argv[0]);
|
3152
|
+
case 0:
|
3153
|
+
break;
|
3154
|
+
default:
|
3155
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 6)", argc);
|
3156
|
+
break;
|
3157
|
+
}
|
3158
|
+
|
3159
|
+
if ( x_off < 0 || x_off > image->columns
|
3160
|
+
|| y_off < 0 || y_off > image->rows
|
3161
|
+
|| cols == 0 || rows == 0)
|
3162
|
+
{
|
3163
|
+
rb_raise(rb_eArgError, "invalid extract geometry");
|
3164
|
+
}
|
3165
|
+
|
3166
|
+
|
3167
|
+
npixels = cols * rows * strlen(map);
|
3168
|
+
switch (type)
|
3169
|
+
{
|
3170
|
+
case CharPixel:
|
3171
|
+
sz = sizeof(unsigned char);
|
3172
|
+
break;
|
3173
|
+
case ShortPixel:
|
3174
|
+
sz = sizeof(unsigned short);
|
3175
|
+
break;
|
3176
|
+
case DoublePixel:
|
3177
|
+
sz = sizeof(double);
|
3178
|
+
break;
|
3179
|
+
case FloatPixel:
|
3180
|
+
sz = sizeof(float);
|
3181
|
+
break;
|
3182
|
+
case IntegerPixel:
|
3183
|
+
sz = sizeof(unsigned int);
|
3184
|
+
break;
|
3185
|
+
case LongPixel:
|
3186
|
+
sz = sizeof(unsigned long);
|
3187
|
+
break;
|
3188
|
+
#if defined(HAVE_QUANTUMPIXEL)
|
3189
|
+
case QuantumPixel:
|
3190
|
+
sz = sizeof(Quantum);
|
3191
|
+
break;
|
3192
|
+
#endif
|
3193
|
+
case UndefinedPixel:
|
3194
|
+
default:
|
3195
|
+
rb_raise(rb_eArgError, "undefined storage type");
|
3196
|
+
break;
|
3197
|
+
}
|
3198
|
+
|
3199
|
+
// Allocate a string long enough to hold the exported pixel data.
|
3200
|
+
// Get a pointer to the buffer.
|
3201
|
+
string = rb_str_new2("");
|
3202
|
+
rb_str_resize(string, (long)(sz * npixels));
|
3203
|
+
str = STRING_PTR(string);
|
3204
|
+
|
3205
|
+
GetExceptionInfo(&exception);
|
3206
|
+
|
3207
|
+
okay = ExportImagePixels(image, x_off, y_off, cols, rows, map, type, (void *)str, &exception);
|
3208
|
+
if (!okay)
|
3209
|
+
{
|
3210
|
+
// Let GC have the string buffer.
|
3211
|
+
rb_str_resize(string, 0);
|
3212
|
+
HANDLE_ERROR
|
3213
|
+
// Should never get here...
|
3214
|
+
rb_raise(rb_eStandardError, "ExportImagePixels failed with no explanation.");
|
3215
|
+
}
|
3216
|
+
|
3217
|
+
return string;
|
3218
|
+
|
3219
|
+
#else
|
3220
|
+
rm_not_implemented();
|
3221
|
+
return (VALUE)0;
|
3222
|
+
#endif
|
3223
|
+
}
|
3224
|
+
|
3060
3225
|
/*
|
3061
3226
|
Method: Image#extract_info, extract_info=
|
3062
3227
|
Purpose: the extract_info attribute accessors
|
@@ -3760,7 +3925,7 @@ VALUE
|
|
3760
3925
|
Image_import_pixels(int argc, VALUE *argv, VALUE self)
|
3761
3926
|
{
|
3762
3927
|
#if defined(HAVE_IMPORTIMAGEPIXELS)
|
3763
|
-
Image *image
|
3928
|
+
Image *image;
|
3764
3929
|
long x_off, y_off;
|
3765
3930
|
unsigned long cols, rows;
|
3766
3931
|
unsigned long npixels;
|
@@ -3772,7 +3937,6 @@ Image_import_pixels(int argc, VALUE *argv, VALUE self)
|
|
3772
3937
|
volatile int *pixels = NULL;
|
3773
3938
|
volatile void *buffer;
|
3774
3939
|
unsigned int okay;
|
3775
|
-
ExceptionInfo exception;
|
3776
3940
|
|
3777
3941
|
rm_check_frozen(self);
|
3778
3942
|
|
@@ -3883,15 +4047,9 @@ Image_import_pixels(int argc, VALUE *argv, VALUE self)
|
|
3883
4047
|
}
|
3884
4048
|
|
3885
4049
|
|
3886
|
-
|
3887
|
-
GetExceptionInfo(&exception);
|
3888
|
-
clone_image = CloneImage(image, 0, 0, True, &exception);
|
3889
|
-
HANDLE_ERROR
|
4050
|
+
okay = ImportImagePixels(image, x_off, y_off, cols, rows, map, stg_type, (const void *)buffer);
|
3890
4051
|
|
3891
|
-
|
3892
|
-
|
3893
|
-
// Free pixel array before checking for errors. If an error occurred, ImportImagePixels
|
3894
|
-
// destroyed the clone image, so we don't have to.
|
4052
|
+
// Free pixel array before checking for errors.
|
3895
4053
|
if (pixels)
|
3896
4054
|
{
|
3897
4055
|
xfree((void *)pixels);
|
@@ -3899,15 +4057,11 @@ Image_import_pixels(int argc, VALUE *argv, VALUE self)
|
|
3899
4057
|
|
3900
4058
|
if (!okay)
|
3901
4059
|
{
|
3902
|
-
HANDLE_ERROR_IMG(
|
4060
|
+
HANDLE_ERROR_IMG(image)
|
3903
4061
|
// Shouldn't get here...
|
3904
4062
|
rb_raise(rb_eStandardError, "ImportImagePixels failed with no explanation.");
|
3905
4063
|
}
|
3906
4064
|
|
3907
|
-
// Everything worked. Replace the image with the clone and destroy the original.
|
3908
|
-
DATA_PTR(self) = clone_image;
|
3909
|
-
DestroyImage(image);
|
3910
|
-
|
3911
4065
|
return self;
|
3912
4066
|
|
3913
4067
|
#else
|
@@ -3942,11 +4096,7 @@ Image_inspect(VALUE self)
|
|
3942
4096
|
// Print current filename.
|
3943
4097
|
x += sprintf(buffer+x, "%s", image->filename);
|
3944
4098
|
// Print scene number.
|
3945
|
-
#if defined(HAVE_GETNEXTIMAGEINLIST)
|
3946
4099
|
if ((GetPreviousImageInList(image) != NULL) && (GetNextImageInList(image) != NULL) && image->scene > 0)
|
3947
|
-
#else
|
3948
|
-
if ((image->previous || image->next) && image->scene > 0)
|
3949
|
-
#endif
|
3950
4100
|
{
|
3951
4101
|
x += sprintf(buffer+x, "[%lu]", image->scene);
|
3952
4102
|
}
|
@@ -4123,7 +4273,7 @@ Image_iptc_profile(VALUE self)
|
|
4123
4273
|
prof = GetImageProfile(image, "iptc", &length);
|
4124
4274
|
if (prof)
|
4125
4275
|
{
|
4126
|
-
profile = rb_str_new(prof, (long) length);
|
4276
|
+
profile = rb_str_new((char *)prof, (long) length);
|
4127
4277
|
}
|
4128
4278
|
#endif
|
4129
4279
|
|
@@ -4220,7 +4370,7 @@ Image_iptc_profile_eq(VALUE self, VALUE profile)
|
|
4220
4370
|
}
|
4221
4371
|
else
|
4222
4372
|
{
|
4223
|
-
prof = STRING_PTR_LEN(profile, prof_l);
|
4373
|
+
prof = (unsigned char *)STRING_PTR_LEN(profile, prof_l);
|
4224
4374
|
(void) SetImageProfile(image, "iptc", prof, (size_t)prof_l);
|
4225
4375
|
}
|
4226
4376
|
#endif
|
@@ -4311,7 +4461,6 @@ Image_level(int argc, VALUE *argv, VALUE self)
|
|
4311
4461
|
VALUE
|
4312
4462
|
Image_level_channel(int argc, VALUE *argv, VALUE self)
|
4313
4463
|
{
|
4314
|
-
#ifdef HAVE_LEVELIMAGECHANNEL
|
4315
4464
|
Image *image, *new_image;
|
4316
4465
|
double black_point = 0.0, mid_point = 1.0, white_point = (double)MaxRGB;
|
4317
4466
|
ChannelType channel;
|
@@ -4353,10 +4502,6 @@ Image_level_channel(int argc, VALUE *argv, VALUE self)
|
|
4353
4502
|
, white_point);
|
4354
4503
|
HANDLE_ERROR_IMG(new_image)
|
4355
4504
|
return rm_image_new(new_image);
|
4356
|
-
#else
|
4357
|
-
rm_not_implemented();
|
4358
|
-
return (VALUE)0;
|
4359
|
-
#endif
|
4360
4505
|
}
|
4361
4506
|
|
4362
4507
|
/*
|
@@ -4985,7 +5130,11 @@ Image_initialize(VALUE self, VALUE info_obj, VALUE width, VALUE height, VALUE fi
|
|
4985
5130
|
// specifying it when creating the Info parm block.
|
4986
5131
|
if (!fill)
|
4987
5132
|
{
|
5133
|
+
#if defined(HAVE_SETIMAGEBACKGROUNDCOLOR)
|
5134
|
+
SetImageBackgroundColor(image);
|
5135
|
+
#else
|
4988
5136
|
SetImage(image, OpaqueOpacity);
|
5137
|
+
#endif
|
4989
5138
|
}
|
4990
5139
|
// fillobj.fill(self)
|
4991
5140
|
else
|
@@ -5254,23 +5403,54 @@ Image_opaque_q(VALUE self)
|
|
5254
5403
|
}
|
5255
5404
|
|
5256
5405
|
/*
|
5257
|
-
Method: Image#ordered_dither
|
5258
|
-
Purpose:
|
5406
|
+
Method: Image#ordered_dither(order=2)
|
5407
|
+
Purpose: perform ordered dither on image
|
5408
|
+
Notes: order must be 2, 3, or 4
|
5409
|
+
I don't call OrderedDitherImages anymore. Sometime after
|
5410
|
+
IM 6.0.0 it quit working. IM and GM use the routines I use
|
5411
|
+
below to implement the "ordered-dither" option.
|
5259
5412
|
*/
|
5260
5413
|
VALUE
|
5261
|
-
Image_ordered_dither(VALUE self)
|
5414
|
+
Image_ordered_dither(int argc, VALUE *argv, VALUE self)
|
5262
5415
|
{
|
5263
5416
|
Image *image, *new_image;
|
5417
|
+
int order;
|
5418
|
+
const char *thresholds = "2x2";
|
5264
5419
|
ExceptionInfo exception;
|
5265
5420
|
|
5421
|
+
if (argc > 1)
|
5422
|
+
{
|
5423
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
|
5424
|
+
}
|
5425
|
+
if (argc == 1)
|
5426
|
+
{
|
5427
|
+
order = NUM2INT(argv[0]);
|
5428
|
+
if (order == 3)
|
5429
|
+
{
|
5430
|
+
thresholds = "3x3";
|
5431
|
+
}
|
5432
|
+
else if (order == 4)
|
5433
|
+
{
|
5434
|
+
thresholds = "4x4";
|
5435
|
+
}
|
5436
|
+
else if (order != 2)
|
5437
|
+
{
|
5438
|
+
rb_raise(rb_eArgError, "order must be 2, 3, or 4 (%d given)", order);
|
5439
|
+
}
|
5440
|
+
}
|
5441
|
+
|
5442
|
+
|
5266
5443
|
Data_Get_Struct(self, Image, image);
|
5267
5444
|
GetExceptionInfo(&exception);
|
5268
5445
|
|
5269
5446
|
new_image = CloneImage(image, 0, 0, True, &exception);
|
5270
5447
|
HANDLE_ERROR
|
5271
|
-
|
5272
|
-
(void)
|
5273
|
-
|
5448
|
+
#if defined(HAVE_RANDOMTHRESHOLDIMAGECHANNEL)
|
5449
|
+
(void) RandomThresholdImageChannel(new_image, AllChannels, thresholds, &exception);
|
5450
|
+
#else
|
5451
|
+
(void) RandomChannelThresholdImage(new_image, "all", thresholds, &exception);
|
5452
|
+
#endif
|
5453
|
+
HANDLE_ERROR
|
5274
5454
|
return rm_image_new(new_image);
|
5275
5455
|
}
|
5276
5456
|
|
@@ -6174,18 +6354,11 @@ static VALUE array_from_images(Image *images)
|
|
6174
6354
|
// Orphan the image, create an Image object, add it to the array.
|
6175
6355
|
|
6176
6356
|
image_ary = rb_ary_new();
|
6177
|
-
|
6357
|
+
next = NULL;
|
6178
6358
|
next = next; // defeat "never referenced" message from icc
|
6179
6359
|
while (images)
|
6180
6360
|
{
|
6181
6361
|
image = RemoveFirstImageFromList(&images);
|
6182
|
-
|
6183
|
-
#else
|
6184
|
-
for (image = images; image; image = next)
|
6185
|
-
{
|
6186
|
-
next = images->next;
|
6187
|
-
image->next = image->previous = NULL;
|
6188
|
-
#endif
|
6189
6362
|
image_obj = rm_image_new(image);
|
6190
6363
|
rb_ary_push(image_ary, image_obj);
|
6191
6364
|
}
|
@@ -6258,7 +6431,7 @@ resize(int bang, int argc, VALUE *argv, VALUE self)
|
|
6258
6431
|
double scale;
|
6259
6432
|
FilterTypes filter;
|
6260
6433
|
unsigned long rows, columns;
|
6261
|
-
double blur;
|
6434
|
+
double blur, drows, dcols;
|
6262
6435
|
ExceptionInfo exception;
|
6263
6436
|
|
6264
6437
|
Data_Get_Struct(self, Image, image);
|
@@ -6278,11 +6451,25 @@ resize(int bang, int argc, VALUE *argv, VALUE self)
|
|
6278
6451
|
case 2:
|
6279
6452
|
rows = NUM2ULONG(argv[1]);
|
6280
6453
|
columns = NUM2ULONG(argv[0]);
|
6454
|
+
if (columns == 0 || rows == 0)
|
6455
|
+
{
|
6456
|
+
rb_raise(rb_eArgError, "invalid result dimension (%lu, %lu given)", columns, rows);
|
6457
|
+
}
|
6281
6458
|
break;
|
6282
6459
|
case 1:
|
6283
6460
|
scale = NUM2DBL(argv[0]);
|
6284
|
-
|
6285
|
-
|
6461
|
+
if (scale < 0.0)
|
6462
|
+
{
|
6463
|
+
rb_raise(rb_eArgError, "invalid scale value (%g given)", scale);
|
6464
|
+
}
|
6465
|
+
drows = scale * image->rows + 0.5;
|
6466
|
+
dcols = scale * image->columns + 0.5;
|
6467
|
+
if (drows > ULONG_MAX || dcols > ULONG_MAX)
|
6468
|
+
{
|
6469
|
+
rb_raise(rb_eRangeError, "resulting image too big");
|
6470
|
+
}
|
6471
|
+
rows = (unsigned long) drows;
|
6472
|
+
columns = (unsigned long) dcols;
|
6286
6473
|
break;
|
6287
6474
|
default:
|
6288
6475
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 4)", argc);
|
@@ -6386,14 +6573,14 @@ DEF_ATTR_READER(Image, rows, int)
|
|
6386
6573
|
VALUE
|
6387
6574
|
Image_sample(int argc, VALUE *argv, VALUE self)
|
6388
6575
|
{
|
6389
|
-
return
|
6576
|
+
return scale(False, argc, argv, self, SampleImage);
|
6390
6577
|
}
|
6391
6578
|
|
6392
6579
|
VALUE
|
6393
6580
|
Image_sample_bang(int argc, VALUE *argv, VALUE self)
|
6394
6581
|
{
|
6395
6582
|
rm_check_frozen(self);
|
6396
|
-
return
|
6583
|
+
return scale(True, argc, argv, self, SampleImage);
|
6397
6584
|
}
|
6398
6585
|
|
6399
6586
|
/*
|
@@ -6406,28 +6593,28 @@ Image_sample_bang(int argc, VALUE *argv, VALUE self)
|
|
6406
6593
|
VALUE
|
6407
6594
|
Image_scale(int argc, VALUE *argv, VALUE self)
|
6408
6595
|
{
|
6409
|
-
return
|
6596
|
+
return scale(False, argc, argv, self, ScaleImage);
|
6410
6597
|
}
|
6411
6598
|
|
6412
6599
|
VALUE
|
6413
6600
|
Image_scale_bang(int argc, VALUE *argv, VALUE self)
|
6414
6601
|
{
|
6415
6602
|
rm_check_frozen(self);
|
6416
|
-
return
|
6603
|
+
return scale(True, argc, argv, self, ScaleImage);
|
6417
6604
|
}
|
6418
6605
|
|
6419
6606
|
/*
|
6420
|
-
Static:
|
6607
|
+
Static: scale
|
6421
6608
|
Purpose: Call ScaleImage or SampleImage
|
6422
6609
|
Arguments: if 1 argument > 0, multiply current size by this much
|
6423
6610
|
if 2 arguments, (cols, rows)
|
6424
6611
|
*/
|
6425
6612
|
static VALUE
|
6426
|
-
|
6613
|
+
scale(int bang, int argc, VALUE *argv, VALUE self, scaler_t *scaler)
|
6427
6614
|
{
|
6428
6615
|
Image *image, *new_image;
|
6429
6616
|
unsigned long columns, rows;
|
6430
|
-
double scale;
|
6617
|
+
double scale, drows, dcols;
|
6431
6618
|
ExceptionInfo exception;
|
6432
6619
|
|
6433
6620
|
Data_Get_Struct(self, Image, image);
|
@@ -6437,9 +6624,9 @@ scale_image(int bang, int argc, VALUE *argv, VALUE self, scaler_t *scaler)
|
|
6437
6624
|
case 2:
|
6438
6625
|
columns = NUM2ULONG(argv[0]);
|
6439
6626
|
rows = NUM2ULONG(argv[1]);
|
6440
|
-
if (columns
|
6627
|
+
if (columns == 0 || rows == 0)
|
6441
6628
|
{
|
6442
|
-
rb_raise(rb_eArgError, "invalid
|
6629
|
+
rb_raise(rb_eArgError, "invalid result dimension (%lu, %lu given)", columns, rows);
|
6443
6630
|
}
|
6444
6631
|
break;
|
6445
6632
|
case 1:
|
@@ -6448,8 +6635,14 @@ scale_image(int bang, int argc, VALUE *argv, VALUE self, scaler_t *scaler)
|
|
6448
6635
|
{
|
6449
6636
|
rb_raise(rb_eArgError, "invalid scale value (%g given)", scale);
|
6450
6637
|
}
|
6451
|
-
|
6452
|
-
|
6638
|
+
drows = scale * image->rows + 0.5;
|
6639
|
+
dcols = scale * image->columns + 0.5;
|
6640
|
+
if (drows > ULONG_MAX || dcols > ULONG_MAX)
|
6641
|
+
{
|
6642
|
+
rb_raise(rb_eRangeError, "resulting image too big");
|
6643
|
+
}
|
6644
|
+
rows = (unsigned long) drows;
|
6645
|
+
columns = (unsigned long) dcols;
|
6453
6646
|
break;
|
6454
6647
|
default:
|
6455
6648
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
|
@@ -7553,10 +7746,9 @@ VALUE threshold_image(
|
|
7553
7746
|
static VALUE
|
7554
7747
|
thumbnail(int bang, int argc, VALUE *argv, VALUE self)
|
7555
7748
|
{
|
7556
|
-
#ifdef HAVE_THUMBNAILIMAGE
|
7557
7749
|
Image *image, *new_image;
|
7558
7750
|
unsigned long columns, rows;
|
7559
|
-
double scale;
|
7751
|
+
double scale, drows, dcols;
|
7560
7752
|
ExceptionInfo exception;
|
7561
7753
|
|
7562
7754
|
Data_Get_Struct(self, Image, image);
|
@@ -7566,11 +7758,25 @@ thumbnail(int bang, int argc, VALUE *argv, VALUE self)
|
|
7566
7758
|
case 2:
|
7567
7759
|
columns = NUM2ULONG(argv[0]);
|
7568
7760
|
rows = NUM2ULONG(argv[1]);
|
7761
|
+
if (columns == 0 || rows == 0)
|
7762
|
+
{
|
7763
|
+
rb_raise(rb_eArgError, "invalid result dimension (%lu, %lu given)", columns, rows);
|
7764
|
+
}
|
7569
7765
|
break;
|
7570
7766
|
case 1:
|
7571
7767
|
scale = NUM2DBL(argv[0]);
|
7572
|
-
|
7573
|
-
|
7768
|
+
if (scale < 0.0)
|
7769
|
+
{
|
7770
|
+
rb_raise(rb_eArgError, "invalid scale value (%g given)", scale);
|
7771
|
+
}
|
7772
|
+
drows = scale * image->rows + 0.5;
|
7773
|
+
dcols = scale * image->columns + 0.5;
|
7774
|
+
if (drows > ULONG_MAX || dcols > ULONG_MAX)
|
7775
|
+
{
|
7776
|
+
rb_raise(rb_eRangeError, "resulting image too big");
|
7777
|
+
}
|
7778
|
+
rows = (unsigned long) drows;
|
7779
|
+
columns = (unsigned long) dcols;
|
7574
7780
|
break;
|
7575
7781
|
default:
|
7576
7782
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
|
@@ -7589,10 +7795,6 @@ thumbnail(int bang, int argc, VALUE *argv, VALUE self)
|
|
7589
7795
|
}
|
7590
7796
|
|
7591
7797
|
return rm_image_new(new_image);
|
7592
|
-
#else
|
7593
|
-
rm_not_implemented();
|
7594
|
-
return (VALUE)0;
|
7595
|
-
#endif
|
7596
7798
|
}
|
7597
7799
|
|
7598
7800
|
VALUE
|
@@ -7772,6 +7974,7 @@ Image_to_blob(VALUE self)
|
|
7772
7974
|
{
|
7773
7975
|
Image *image;
|
7774
7976
|
Info *info;
|
7977
|
+
const MagickInfo *magick_info;
|
7775
7978
|
volatile VALUE info_obj;
|
7776
7979
|
volatile VALUE blob_str;
|
7777
7980
|
void *blob = NULL;
|
@@ -7807,6 +8010,20 @@ Image_to_blob(VALUE self)
|
|
7807
8010
|
strncpy(image->magick, info->magick, sizeof(info->magick)-1);
|
7808
8011
|
}
|
7809
8012
|
|
8013
|
+
// Fix #2844 - libjpeg exits when image is 0x0
|
8014
|
+
magick_info = GetMagickInfo(image->magick, &exception);
|
8015
|
+
HANDLE_ERROR
|
8016
|
+
if (magick_info)
|
8017
|
+
{
|
8018
|
+
if ( (!rm_strcasecmp(magick_info->name, "JPEG")
|
8019
|
+
|| !rm_strcasecmp(magick_info->name, "JPG"))
|
8020
|
+
&& (image->rows == 0 || image->columns == 0))
|
8021
|
+
{
|
8022
|
+
rb_raise(rb_eRuntimeError, "Can't convert %lux%lu %.4s image to a blob"
|
8023
|
+
, image->columns, image->rows, magick_info->name);
|
8024
|
+
}
|
8025
|
+
}
|
8026
|
+
|
7810
8027
|
blob = ImageToBlob(info, image, &length, &exception);
|
7811
8028
|
HANDLE_ERROR
|
7812
8029
|
if (length == 0 || !blob)
|
@@ -8134,6 +8351,60 @@ Image_unsharp_mask_channel(int argc, VALUE *argv, VALUE self)
|
|
8134
8351
|
}
|
8135
8352
|
|
8136
8353
|
|
8354
|
+
/*
|
8355
|
+
Method: Image#vignette(horz_radius, vert_radius, radius, sigma);
|
8356
|
+
Purpose: soften the edges of an image
|
8357
|
+
Notes: The outer edges of the image are replaced by the background color.
|
8358
|
+
*/
|
8359
|
+
VALUE
|
8360
|
+
Image_vignette(int argc, VALUE *argv, VALUE self)
|
8361
|
+
{
|
8362
|
+
#if defined(HAVE_VIGNETTEIMAGE)
|
8363
|
+
Image *image, *new_image;
|
8364
|
+
long horz_radius, vert_radius;
|
8365
|
+
double radius = 0.0, sigma = 10.0;
|
8366
|
+
ExceptionInfo exception;
|
8367
|
+
|
8368
|
+
Data_Get_Struct(self, Image, image);
|
8369
|
+
|
8370
|
+
horz_radius = image->columns * 0.10 + 0.5;
|
8371
|
+
vert_radius = image->rows * 0.10 + 0.5;
|
8372
|
+
|
8373
|
+
switch (argc)
|
8374
|
+
{
|
8375
|
+
case 4:
|
8376
|
+
sigma = NUM2DBL(argv[3]);
|
8377
|
+
case 3:
|
8378
|
+
radius = NUM2DBL(argv[2]);
|
8379
|
+
case 2:
|
8380
|
+
vert_radius = NUM2INT(argv[1]);
|
8381
|
+
case 1:
|
8382
|
+
horz_radius = NUM2INT(argv[0]);
|
8383
|
+
case 0:
|
8384
|
+
break;
|
8385
|
+
default:
|
8386
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 4)", argc);
|
8387
|
+
break;
|
8388
|
+
}
|
8389
|
+
|
8390
|
+
GetExceptionInfo(&exception);
|
8391
|
+
|
8392
|
+
new_image = VignetteImage(image, radius, sigma, horz_radius, vert_radius, &exception);
|
8393
|
+
HANDLE_ERROR
|
8394
|
+
if (!new_image)
|
8395
|
+
{
|
8396
|
+
rb_raise(rb_eRuntimeError, "VignetteImage failed");
|
8397
|
+
}
|
8398
|
+
|
8399
|
+
return rm_image_new(new_image);
|
8400
|
+
|
8401
|
+
#else
|
8402
|
+
rm_not_implemented();
|
8403
|
+
return (VALUE)0;
|
8404
|
+
#endif
|
8405
|
+
}
|
8406
|
+
|
8407
|
+
|
8137
8408
|
/*
|
8138
8409
|
Method: Image#virtual_pixel_method
|
8139
8410
|
Purpose: get the VirtualPixelMethod for the image
|
@@ -8532,12 +8803,14 @@ static ChannelType extract_channels(
|
|
8532
8803
|
*argc -= 1;
|
8533
8804
|
}
|
8534
8805
|
|
8535
|
-
#if defined(HAVE_ALLCHANNELS)
|
8536
8806
|
if (channels == 0)
|
8537
8807
|
{
|
8808
|
+
#if defined(HAVE_ALLCHANNELS)
|
8538
8809
|
channels = AllChannels;
|
8539
|
-
|
8810
|
+
#else
|
8811
|
+
channels = 0xff;
|
8540
8812
|
#endif
|
8813
|
+
}
|
8541
8814
|
|
8542
8815
|
return channels;
|
8543
8816
|
}
|