ruby-libgd 0.2.4 → 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 +217 -3
  3. data/ext/gd/filter.o +0 -0
  4. data/ext/gd/gd.so +0 -0
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d0a3de385842f0cf17fc56e102fc0dd9614512227bf9a07dc8b8cd96929dd2a4
4
- data.tar.gz: 3b47534f1017febc504cb328c1d1db1b2fa7f58f5e15047504abff2e119d347b
3
+ metadata.gz: 310bd931469060390ec5d475ce151934d42afb9e51e3d9ddaa59075c8a4f88db
4
+ data.tar.gz: 4d5dcef0cb4eb3556f4aa88733fd541539b49e489b4820469425270662b06b4c
5
5
  SHA512:
6
- metadata.gz: de84a2dc1be0454faea9fad0105cf7bda0e4a0684ed90ff62bf91e914e246afcd0ce21b666793b86d198e335324464a31b173b3e7d589d6d01ff8b73c76eee02
7
- data.tar.gz: 2c699498111605b390e3b9c25f9f5a157e806612094fdee1aa0e2ffaf858bb7fecfe0c45e8d3a651f7ea8e7ae2c777f016623c38fa4742c5a9b236351623a669
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
  }
@@ -84,6 +123,181 @@ static VALUE gd_image_filter(int argc, VALUE *argv, VALUE self) {
84
123
  else if (strcmp(name, "sepia") == 0) {
85
124
  gd_image_apply_sepia(wrap->img);
86
125
  }
126
+ else if (strcmp(name, "convolve") == 0) {
127
+
128
+ Check_Type(arg1, T_ARRAY);
129
+ if (RARRAY_LEN(arg1) != 3) {
130
+ rb_raise(rb_eArgError, "kernel must be a 3x3 array");
131
+ }
132
+
133
+ float filter[3][3];
134
+
135
+ for (int i = 0; i < 3; i++) {
136
+ VALUE row = rb_ary_entry(arg1, i);
137
+ Check_Type(row, T_ARRAY);
138
+
139
+ if (RARRAY_LEN(row) != 3) {
140
+ rb_raise(rb_eArgError, "kernel must be a 3x3 array");
141
+ }
142
+
143
+ for (int j = 0; j < 3; j++) {
144
+ filter[i][j] = (float)NUM2DBL(rb_ary_entry(row, j));
145
+ }
146
+ }
147
+
148
+ float divisor = NIL_P(arg2) ? 1.0f : (float)NUM2DBL(arg2);
149
+ float offset = NIL_P(arg3) ? 0.0f : (float)NUM2DBL(arg3);
150
+
151
+ if (!gdImageConvolution(wrap->img, filter, divisor, offset)) {
152
+ rb_raise(rb_eRuntimeError, "convolution failed");
153
+ }
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
+ }
87
301
  else {
88
302
  rb_raise(rb_eArgError, "unknown filter");
89
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.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Germán Alberto Giménez Silva
@@ -89,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
89
  - !ruby/object:Gem::Version
90
90
  version: '0'
91
91
  requirements: []
92
- rubygems_version: 4.0.6
92
+ rubygems_version: 4.0.3
93
93
  specification_version: 4
94
94
  summary: Native Ruby bindings for libgd
95
95
  test_files: []