ruby-libgd 0.2.5 → 0.3.0

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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/ext/gd/filter.c +188 -3
  3. data/ext/gd/filter.o +0 -0
  4. data/ext/gd/gd.so +0 -0
  5. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e7aa6764204d6e185d6ba8ba4ed606c5f2a13e9cff220cec8557cc12a99b6ce2
4
- data.tar.gz: 73916e75296f31ef431b34c22124aef6b293985b2a27d670fcb1073f03bf5bad
3
+ metadata.gz: 310bd931469060390ec5d475ce151934d42afb9e51e3d9ddaa59075c8a4f88db
4
+ data.tar.gz: 4d5dcef0cb4eb3556f4aa88733fd541539b49e489b4820469425270662b06b4c
5
5
  SHA512:
6
- metadata.gz: 7f34d5a36d7c1db0daa1770f7406006a17a4bdcf0e778b172581c6f0a9863c62d510fef76535310358a39a57d74e5f2cffff3cbfea3e46b66844832db230b307
7
- data.tar.gz: e1409b46676c61e39970bfd3f8a5ef773bce0c9dcae07f15ce6a255f609d97a0e6ee29f03036f10f0b50949aa02e94e397e2b5a9bab30140410ad26a85dd0252
6
+ metadata.gz: c3bb2ad496f6764c13c00d25f0e4d30b8b388915f45d16421ae85982148bd2ab0ee6e3abd5e5eba16e155fbeb2d1cd74e71fa509a733b49543f8ba0702a1eea8
7
+ data.tar.gz: 1cabca6431ea0b7db31f0341ff63e68420c70b137a3b902b09f7b0bcf86a98d9ce71c3e7e4de67a85d07af47d2c1213e688665333657bc30b0d1ab5c64a55345
data/ext/gd/filter.c CHANGED
@@ -1,6 +1,48 @@
1
1
  #include "ruby_gd.h"
2
2
  #include <string.h>
3
3
 
4
+ static float kernel_sobel[3][3] = {
5
+ {-1,0,1},
6
+ {-2,0,2},
7
+ {-1,0,1}
8
+ };
9
+
10
+ static float kernel_sharpen[3][3] = {
11
+ {0,-1,0},
12
+ {-1,5,-1},
13
+ {0,-1,0}
14
+ };
15
+
16
+ static float kernel_edge[3][3] = {
17
+ {-1,-1,-1},
18
+ {-1,8,-1},
19
+ {-1,-1,-1}
20
+ };
21
+
22
+ static float kernel_box_blur[3][3] = {
23
+ {1,1,1},
24
+ {1,1,1},
25
+ {1,1,1}
26
+ };
27
+
28
+ static float kernel_gaussian[3][3] = {
29
+ {1,2,1},
30
+ {2,4,2},
31
+ {1,2,1}
32
+ };
33
+
34
+ static float kernel_emboss2[3][3] = {
35
+ {-2,-1,0},
36
+ {-1,1,1},
37
+ {0,1,2}
38
+ };
39
+
40
+ static float kernel_laplacian[3][3] = {
41
+ {0,-1,0},
42
+ {-1,4,-1},
43
+ {0,-1,0}
44
+ };
45
+
4
46
  static void gd_image_apply_sepia(gdImagePtr img) {
5
47
  int x, y;
6
48
  for (y = 0; y < img->sy; y++) {
@@ -46,9 +88,6 @@ static VALUE gd_image_filter(int argc, VALUE *argv, VALUE self) {
46
88
  else if (strcmp(name, "contrast") == 0) {
47
89
  gdImageContrast(wrap->img, NUM2INT(arg1));
48
90
  }
49
- else if (strcmp(name, "colorize") == 0) {
50
- rb_raise(rb_eNotImpError, "colorize not supported by libgd");
51
- }
52
91
  else if (strcmp(name, "edge_detect") == 0) {
53
92
  gdImageEdgeDetectQuick(wrap->img);
54
93
  }
@@ -113,6 +152,152 @@ static VALUE gd_image_filter(int argc, VALUE *argv, VALUE self) {
113
152
  rb_raise(rb_eRuntimeError, "convolution failed");
114
153
  }
115
154
  }
155
+ else if (strcmp(name, "contrast") == 0) {
156
+ /* libgd: double contrast */
157
+ gdImageContrast(wrap->img, NUM2DBL(arg1));
158
+ }
159
+ else if (strcmp(name, "colorize") == 0) {
160
+ /* libgd calls this "gdImageColor": add to channels */
161
+ /* Ruby: img.filter(:colorize, r, g, b [, a]) */
162
+ if (NIL_P(arg1) || NIL_P(arg2) || NIL_P(arg3)) {
163
+ rb_raise(rb_eArgError, "colorize requires r, g, b (and optional alpha)");
164
+ }
165
+ int r = NUM2INT(arg1);
166
+ int g = NUM2INT(arg2);
167
+ int b = NUM2INT(arg3);
168
+ int a = NIL_P(arg4) ? 0 : NUM2INT(arg4);
169
+
170
+ if (!gdImageColor(wrap->img, r, g, b, a)) {
171
+ rb_raise(rb_eRuntimeError, "colorize failed");
172
+ }
173
+ }
174
+ else if (strcmp(name, "smooth") == 0) {
175
+ /* libgd: float weight */
176
+ gdImageSmooth(wrap->img, (float)NUM2DBL(arg1));
177
+ }
178
+ else if (strcmp(name, "scatter_color") == 0) {
179
+ /* Ruby: img.filter(:scatter_color, sub, plus, [colors...]) */
180
+ if (NIL_P(arg1) || NIL_P(arg2) || NIL_P(arg3)) {
181
+ rb_raise(rb_eArgError, "scatter_color requires sub, plus, colors_array");
182
+ }
183
+
184
+ Check_Type(arg3, T_ARRAY);
185
+ long n = RARRAY_LEN(arg3);
186
+ if (n <= 0) {
187
+ rb_raise(rb_eArgError, "colors_array must not be empty");
188
+ }
189
+
190
+ int *colors = ALLOC_N(int, n);
191
+ for (long i = 0; i < n; i++) {
192
+ colors[i] = NUM2INT(rb_ary_entry(arg3, i));
193
+ }
194
+
195
+ int ok = gdImageScatterColor(
196
+ wrap->img,
197
+ NUM2INT(arg1),
198
+ NUM2INT(arg2),
199
+ colors,
200
+ (unsigned int)n
201
+ );
202
+ xfree(colors);
203
+
204
+ if (!ok) {
205
+ rb_raise(rb_eRuntimeError, "scatter_color failed");
206
+ }
207
+ }
208
+ else if (strcmp(name, "scatter_ex") == 0) {
209
+ /*
210
+ Ruby: img.filter(:scatter_ex, opts)
211
+ opts is a Hash:
212
+ { sub: 2, plus: 5, seed: 123, colors: [ ... ] }
213
+ colors is optional
214
+ seed is optional
215
+ */
216
+ if (NIL_P(arg1) || TYPE(arg1) != T_HASH) {
217
+ rb_raise(rb_eArgError, "scatter_ex requires a hash: {sub:, plus:, seed:, colors:}");
218
+ }
219
+
220
+ VALUE v_sub = rb_hash_aref(arg1, ID2SYM(rb_intern("sub")));
221
+ VALUE v_plus = rb_hash_aref(arg1, ID2SYM(rb_intern("plus")));
222
+ VALUE v_seed = rb_hash_aref(arg1, ID2SYM(rb_intern("seed")));
223
+ VALUE v_colors = rb_hash_aref(arg1, ID2SYM(rb_intern("colors")));
224
+
225
+ if (NIL_P(v_sub) || NIL_P(v_plus)) {
226
+ rb_raise(rb_eArgError, "scatter_ex hash must include :sub and :plus");
227
+ }
228
+
229
+ gdScatter s;
230
+ memset(&s, 0, sizeof(gdScatter));
231
+
232
+ s.sub = NUM2INT(v_sub);
233
+ s.plus = NUM2INT(v_plus);
234
+ s.seed = NIL_P(v_seed) ? 0 : (unsigned int)NUM2UINT(v_seed);
235
+
236
+ int *colors = NULL;
237
+ unsigned int num_colors = 0;
238
+
239
+ if (!NIL_P(v_colors)) {
240
+ Check_Type(v_colors, T_ARRAY);
241
+ long n = RARRAY_LEN(v_colors);
242
+ if (n > 0) {
243
+ colors = ALLOC_N(int, n);
244
+ for (long i = 0; i < n; i++) {
245
+ colors[i] = NUM2INT(rb_ary_entry(v_colors, i));
246
+ }
247
+ num_colors = (unsigned int)n;
248
+ }
249
+ }
250
+
251
+ s.num_colors = num_colors;
252
+ s.colors = colors;
253
+
254
+ int ok = gdImageScatterEx(wrap->img, &s);
255
+
256
+ if (colors) xfree(colors);
257
+
258
+ if (!ok) {
259
+ rb_raise(rb_eRuntimeError, "scatter_ex failed");
260
+ }
261
+ }
262
+ else if (strcmp(name, "sobel") == 0) {
263
+ if (!gdImageConvolution(wrap->img, kernel_sobel, 1.0, 0.0)) {
264
+ rb_raise(rb_eRuntimeError, "sobel convolution failed");
265
+ }
266
+ }
267
+ else if (strcmp(name, "sharpen") == 0) {
268
+ if (!gdImageConvolution(wrap->img, kernel_sharpen, 1.0, 0.0)) {
269
+ rb_raise(rb_eRuntimeError, "sharpen convolution failed");
270
+ }
271
+ }
272
+ else if (strcmp(name, "edge") == 0) {
273
+ if (!gdImageConvolution(wrap->img, kernel_edge, 1.0, 0.0)) {
274
+ rb_raise(rb_eRuntimeError, "edge convolution failed");
275
+ }
276
+ }
277
+ else if (strcmp(name, "box_blur") == 0) {
278
+
279
+ if (!gdImageConvolution(wrap->img, kernel_box_blur, 9.0, 0.0)) {
280
+ rb_raise(rb_eRuntimeError, "box_blur convolution failed");
281
+ }
282
+
283
+ }
284
+ else if (strcmp(name, "gaussian_kernel") == 0) {
285
+
286
+ if (!gdImageConvolution(wrap->img, kernel_gaussian, 16.0, 0.0)) {
287
+ rb_raise(rb_eRuntimeError, "gaussian_kernel convolution failed");
288
+ }
289
+
290
+ }
291
+ else if (strcmp(name, "emboss2") == 0) {
292
+ if (!gdImageConvolution(wrap->img, kernel_emboss2, 1.0, 128.0)) {
293
+ rb_raise(rb_eRuntimeError, "emboss2 convolution failed");
294
+ }
295
+ }
296
+ else if (strcmp(name, "laplacian") == 0) {
297
+ if (!gdImageConvolution(wrap->img, kernel_laplacian, 1.0, 0.0)) {
298
+ rb_raise(rb_eRuntimeError, "laplacian convolution failed");
299
+ }
300
+ }
116
301
  else {
117
302
  rb_raise(rb_eArgError, "unknown filter");
118
303
  }
data/ext/gd/filter.o CHANGED
Binary file
data/ext/gd/gd.so CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-libgd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Germán Alberto Giménez Silva