pixbufutils 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1ba2ec614619680bd44bf1e4c122ba3b8dc1c830
4
+ data.tar.gz: 41112646a90c2c68aa2f2f8da9750732e83130d5
5
+ SHA512:
6
+ metadata.gz: 524e1a045190ed226aa85f41e72051e509cc9dbc7d6d60004f0e6ff3c90cc7d204648eef0887a604c5e415a90e45e6172d5ff040b619dcc26a74047212d1cd66
7
+ data.tar.gz: dd0d72083538fd27eb43d72a391420b61bc3c3b00bc62a3181bd29b18f959e47f55c21a21e9a9de9401ec0fa45e71dd20dc29a07883f6548f930158b3fac7b86
data/Rakefile CHANGED
@@ -22,7 +22,7 @@ spec = Gem::Specification.new do |s|
22
22
  s.name = "pixbufutils"
23
23
  s.author = "Geoff Youngs"
24
24
  s.email = "git@intersect-uk.co.uk"
25
- s.version = "0.0.3"
25
+ s.version = "0.0.4"
26
26
  s.homepage = "http://github.com/geoffyoungs/pixbufutils"
27
27
  s.summary = "Additional utils for Gdk::Pixbuf"
28
28
  s.add_dependency("rubber-generate", ">= 0.0.17")
@@ -0,0 +1,102 @@
1
+ // Auto-equalize stuff here...
2
+ //
3
+
4
+ static long **
5
+ get_cumulative (histogram *data)
6
+ {
7
+ long **cumulative;
8
+ int i, v;
9
+
10
+ cumulative = ALLOC_N(long *, N_CHANNELS);
11
+ for (i = 0; i < N_CHANNELS; i++) {
12
+ int s;
13
+
14
+ cumulative[i] = ALLOC_N(long, 256);
15
+ s = 0;
16
+ for (v = 0; v < 256; v++) {
17
+ s += data->values[i][v];
18
+ cumulative[i][v] = s;
19
+ }
20
+ }
21
+
22
+ return cumulative;
23
+ }
24
+
25
+
26
+ static void
27
+ free_cumulative (long **cumulative)
28
+ {
29
+ int i;
30
+ for (i = 0; i < N_CHANNELS; i++)
31
+ free(cumulative[i]);
32
+
33
+ free(cumulative);
34
+ }
35
+
36
+
37
+ static GdkPixbuf *
38
+ auto_equalize(GdkPixbuf *src, GdkPixbuf *dest)
39
+ {
40
+ int s_has_alpha, d_has_alpha;
41
+ int s_width, s_height, s_rowstride;
42
+ guchar *s_pix, *sp;
43
+ int i, j, n_channels, r, g, b, a;
44
+ histogram *data;
45
+ long ** cumulative = NULL;
46
+ double factor;
47
+
48
+
49
+ int d_width, d_height, d_rowstride;
50
+ guchar *d_pix, *dp;
51
+
52
+ g_return_val_if_fail(src != NULL, NULL);
53
+
54
+ s_width = gdk_pixbuf_get_width(src);
55
+ s_height = gdk_pixbuf_get_height(src);
56
+ s_has_alpha = gdk_pixbuf_get_has_alpha(src);
57
+ s_rowstride = gdk_pixbuf_get_rowstride(src);
58
+ s_pix = gdk_pixbuf_get_pixels(src);
59
+ n_channels = s_has_alpha ? 4 : 3;
60
+
61
+ d_width = gdk_pixbuf_get_width(dest);
62
+ d_height = gdk_pixbuf_get_height(dest);
63
+ d_has_alpha = gdk_pixbuf_get_has_alpha(dest);
64
+ d_rowstride = gdk_pixbuf_get_rowstride(dest);
65
+ d_pix = gdk_pixbuf_get_pixels(dest);
66
+
67
+ g_return_val_if_fail(d_width == s_width, NULL);
68
+ g_return_val_if_fail(d_height == s_height, NULL);
69
+ g_return_val_if_fail(d_has_alpha == s_has_alpha, NULL);
70
+
71
+ data = histogram_from_pixbuf(src);
72
+ cumulative = get_cumulative(data);
73
+ factor = 255.0/(s_width * s_height);
74
+
75
+ for (i = 0; i < s_height; i++) {
76
+ sp = s_pix + (i * s_rowstride);
77
+ dp = d_pix + (i * d_rowstride);
78
+
79
+ for (j = 0; j < s_width; j++) {
80
+ r = *sp++;
81
+ g = *sp++;
82
+ b = *sp++;
83
+ if (s_has_alpha) {
84
+ a = *sp++;
85
+ }
86
+ /*fprintf(stderr, "r=%i,g=%i,b=%i -> count %li %li %li -- ", r, g, b, data->values[CHAN_RED][r], data->values[CHAN_GREEN][g], data->values[CHAN_BLUE][b]);
87
+ fprintf(stderr, "r=%i,g=%i,b=%i -> cumulative %li %li %li \n", r, g, b, cumulative[CHAN_RED][r], cumulative[CHAN_GREEN][g], cumulative[CHAN_BLUE][b]);*/
88
+ *dp ++ = (unsigned char)((double)cumulative[CHAN_RED][r] * factor);
89
+ *dp ++ = (unsigned char)((double)cumulative[CHAN_GREEN][g] * factor);
90
+ *dp ++ = (unsigned char)((double)cumulative[CHAN_BLUE][b] * factor);
91
+ if (s_has_alpha) {
92
+ *dp ++ = (unsigned char)((double)cumulative[CHAN_ALPHA][a] * factor);
93
+ }
94
+ }
95
+ }
96
+
97
+ free_cumulative(cumulative);
98
+ free_histogram(data);
99
+
100
+ return dest;
101
+ }
102
+
@@ -0,0 +1,63 @@
1
+ static GdkPixbuf *pixbuf_blend5050(GdkPixbuf *src1, GdkPixbuf *src2)
2
+ {
3
+ int s1_has_alpha, s2_has_alpha;
4
+ int s1_width, s1_height, s1_rowstride;
5
+ int d_width, d_height, d_rowstride;
6
+ int s2_width, s2_height, s2_rowstride;
7
+ guchar *s1_pix, *sp;
8
+ guchar *d_pix, *dp;
9
+ guchar *s2_pix, *mp;
10
+ int i, j;
11
+ GdkPixbuf *dest;
12
+
13
+ g_return_val_if_fail(src1 != NULL, NULL);
14
+
15
+ s1_width = gdk_pixbuf_get_width(src1);
16
+ s1_height = gdk_pixbuf_get_height(src1);
17
+ s1_has_alpha = gdk_pixbuf_get_has_alpha(src1);
18
+ s1_rowstride = gdk_pixbuf_get_rowstride(src1);
19
+ s1_pix = gdk_pixbuf_get_pixels(src1);
20
+
21
+ g_return_val_if_fail(src2 != NULL, NULL);
22
+
23
+ s2_width = gdk_pixbuf_get_width(src2);
24
+ s2_height = gdk_pixbuf_get_height(src2);
25
+ s2_has_alpha = gdk_pixbuf_get_has_alpha(src2);
26
+ s2_rowstride = gdk_pixbuf_get_rowstride(src2);
27
+ s2_pix = gdk_pixbuf_get_pixels(src2);
28
+
29
+ g_return_val_if_fail(s2_width == s1_width, NULL);
30
+ g_return_val_if_fail(s2_height == s1_height, NULL);
31
+ g_return_val_if_fail(s2_has_alpha == s1_has_alpha, NULL);
32
+
33
+ d_width = s2_width;
34
+ d_height = s2_height;
35
+
36
+ dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, d_width, d_height);
37
+
38
+ g_return_val_if_fail(dest != NULL, NULL);
39
+
40
+ d_rowstride = gdk_pixbuf_get_rowstride(dest);
41
+ d_pix = gdk_pixbuf_get_pixels(dest);
42
+
43
+ for (i = 0; i < s2_height; i++) {
44
+ sp = s1_pix + (i * s1_rowstride);
45
+ mp = s2_pix + (i * s2_rowstride);
46
+ dp = d_pix + (i * d_rowstride);
47
+
48
+ for (j = 0; j < s2_width; j++) {
49
+ *(dp++) = ((*(sp++)) >> 1) + ((*(mp++)) >> 1); /* red */
50
+ *(dp++) = ((*(sp++)) >> 1) + ((*(mp++)) >> 1); /* green */
51
+ *(dp++) = ((*(sp++)) >> 1) + ((*(mp++)) >> 1); /* blue */
52
+
53
+ if (s1_has_alpha)
54
+ *(dp++) = ((*(sp++)) >> 1) + ((*(mp++)) >> 1); /* alpha */
55
+ else
56
+ *(dp++) = 0xff; /* alpha */
57
+
58
+ }
59
+ }
60
+
61
+ return dest;
62
+ }
63
+
@@ -0,0 +1,358 @@
1
+ static GdkPixbuf *
2
+ pixbuf_blur(GdkPixbuf *src, gint radius)
3
+ {
4
+ /* Pixels and Rowstride To Perform Blur On */
5
+ guchar *pixels;
6
+ GdkPixbuf *pixbuf;
7
+ gint rowstride, width, height;
8
+
9
+ pixbuf = gdk_pixbuf_copy(src);
10
+
11
+ /* Get Pixels and Rowstride Of Image Buffer */
12
+ if (pixbuf)
13
+ {
14
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
15
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
16
+ width = gdk_pixbuf_get_width(pixbuf);
17
+ height = gdk_pixbuf_get_height(pixbuf);
18
+ /*printf("%i, %i, %i, %i\n", rowstride, width, height, rowstride/width);*/
19
+ }
20
+ else
21
+ {
22
+ return NULL;
23
+ }
24
+ if (radius > 1)
25
+ {
26
+ /* Some Important Consts */
27
+ gint bytes = rowstride/width;
28
+ gboolean alpha = (bytes == 4);
29
+
30
+ gint div = radius+radius+1;
31
+ gint divsum = ((div+1)>>1)*((div+1)>>1);
32
+ gint dv[256*divsum]; /* Table of Const RGBA Values */
33
+
34
+ /* Some Important Variables */
35
+ guchar stack[div][bytes];
36
+ gint stackpointer;
37
+ gint stackstart;
38
+ gint vmin[MAX(width,height)];
39
+ guchar *sir;
40
+ gint rbs;
41
+
42
+ gint current = 0;
43
+
44
+ /* RGBA Sums
45
+ 0 - Sum of Incoming pixels(the radius pixels above the Center/to left of Center)
46
+ 1 - Sum of Outgoing pixels(the Center and the radius pixels below the Center/to right of Center)
47
+ 2 - Sum of All pixels within radius
48
+ */
49
+ gint rgba_sums[3][bytes];
50
+
51
+ /* RGBA Values */
52
+ guchar rgba[bytes][width*height];
53
+
54
+ /* Temp Indexes/Counters */
55
+ gint x, y, i, p, yp, yi=0, yw=0;
56
+
57
+ for (i=0; i<256*divsum; i++)
58
+ {
59
+ dv[i] = (i/divsum);
60
+ }
61
+
62
+ for (y=0; y < height; y++)
63
+ {
64
+ /* initialize sums to zero */
65
+ for (i = 0; i<bytes; i++)
66
+ {
67
+ rgba_sums[0][i] = 0;
68
+ rgba_sums[1][i] = 0;
69
+ rgba_sums[2][i] = 0;
70
+ }
71
+
72
+ /* Calculate Initial Sums For radius */
73
+ for(i=-radius; i<=radius; i++)
74
+ {
75
+ current = (yi + MIN(width - 1, MAX(i,0)))*bytes;
76
+
77
+ sir = stack[i+radius];
78
+
79
+ sir[0] = pixels[current + 0];
80
+ sir[1] = pixels[current + 1];
81
+ sir[2] = pixels[current + 2];
82
+ sir[3] = pixels[current + 3];
83
+
84
+ rbs = (radius + 1) - abs(i);
85
+
86
+ rgba_sums[2][0] += sir[0]*rbs;
87
+ rgba_sums[2][1] += sir[1]*rbs;
88
+ rgba_sums[2][2] += sir[2]*rbs;
89
+ if (alpha)
90
+ {
91
+ rgba_sums[2][3] += sir[3]*rbs;
92
+ }
93
+
94
+ if (i>0)
95
+ {
96
+ rgba_sums[0][0] += sir[0];
97
+ rgba_sums[0][1] += sir[1];
98
+ rgba_sums[0][2] += sir[2];
99
+ if (alpha)
100
+ {
101
+ rgba_sums[0][3] += sir[3];
102
+ }
103
+ }
104
+ else
105
+ {
106
+ rgba_sums[1][0] += sir[0];
107
+ rgba_sums[1][1] += sir[1];
108
+ rgba_sums[1][2] += sir[2];
109
+ if (alpha)
110
+ {
111
+ rgba_sums[1][3] += sir[3];
112
+ }
113
+ }
114
+ }
115
+
116
+ stackpointer = radius;
117
+
118
+ for (x=0; x<width; x++)
119
+ {
120
+ rgba[0][yi] = dv[rgba_sums[2][0]];
121
+ rgba[1][yi] = dv[rgba_sums[2][1]];
122
+ rgba[2][yi] = dv[rgba_sums[2][2]];
123
+ if (alpha)
124
+ {
125
+ rgba[3][yi] = dv[rgba_sums[2][3]];
126
+ }
127
+
128
+ rgba_sums[2][0] -= rgba_sums[1][0];
129
+ rgba_sums[2][1] -= rgba_sums[1][1];
130
+ rgba_sums[2][2] -= rgba_sums[1][2];
131
+ if (alpha)
132
+ {
133
+ rgba_sums[2][3] -= rgba_sums[1][3];
134
+ }
135
+
136
+ stackstart = stackpointer - radius + div;
137
+ sir = stack[stackstart%div];
138
+
139
+ rgba_sums[1][0] -= sir[0];
140
+ rgba_sums[1][1] -= sir[1];
141
+ rgba_sums[1][2] -= sir[2];
142
+ if (alpha)
143
+ {
144
+ rgba_sums[1][3] -= sir[3];
145
+ }
146
+
147
+ if(y==0)
148
+ {
149
+ vmin[x] = MIN(x + radius + 1, width - 1);
150
+ }
151
+
152
+ current = (yw + vmin[x])*bytes;
153
+
154
+ sir[0] = pixels[current + 0];
155
+ sir[1] = pixels[current + 1];
156
+ sir[2] = pixels[current + 2];
157
+ if (alpha)
158
+ {
159
+ sir[3] = pixels[current + 3];
160
+ }
161
+
162
+ rgba_sums[0][0] += sir[0];
163
+ rgba_sums[0][1] += sir[1];
164
+ rgba_sums[0][2] += sir[2];
165
+ if (alpha)
166
+ {
167
+ rgba_sums[0][3] += sir[3];
168
+ }
169
+
170
+ rgba_sums[2][0] += rgba_sums[0][0];
171
+ rgba_sums[2][1] += rgba_sums[0][1];
172
+ rgba_sums[2][2] += rgba_sums[0][2];
173
+ if (alpha)
174
+ {
175
+ rgba_sums[2][3] += rgba_sums[0][3];
176
+ }
177
+
178
+ stackpointer=(stackpointer+1)%div;
179
+ sir=stack[(stackpointer)%div];
180
+
181
+ rgba_sums[1][0] += sir[0];
182
+ rgba_sums[1][1] += sir[1];
183
+ rgba_sums[1][2] += sir[2];
184
+ if (alpha)
185
+ {
186
+ rgba_sums[1][3] += sir[3];
187
+ }
188
+
189
+ rgba_sums[0][0] -= sir[0];
190
+ rgba_sums[0][1] -= sir[1];
191
+ rgba_sums[0][2] -= sir[2];
192
+ if (alpha)
193
+ {
194
+ rgba_sums[0][3] -= sir[3];
195
+ }
196
+
197
+ yi++;
198
+ }
199
+
200
+ yw += width;
201
+ }
202
+
203
+ for (x=0; x<width; x++)
204
+ {
205
+ yp=-radius*width;
206
+
207
+ /* initialize sums to zero */
208
+ for (i = 0; i<bytes; i++)
209
+ {
210
+ rgba_sums[0][i] = 0;
211
+ rgba_sums[1][i] = 0;
212
+ rgba_sums[2][i] = 0;
213
+ }
214
+
215
+ /* Calculate Initial Sums For radius */
216
+ for(i=-radius; i<=radius; i++)
217
+ {
218
+ yi = MAX(0,yp) + x;
219
+
220
+ sir = stack[i+radius];
221
+
222
+ sir[0] = rgba[0][yi];
223
+ sir[1] = rgba[1][yi];
224
+ sir[2] = rgba[2][yi];
225
+ if (alpha)
226
+ {
227
+ sir[3] = rgba[3][yi];
228
+ }
229
+
230
+ rbs = (radius + 1) - abs(i);
231
+
232
+ rgba_sums[2][0] += rgba[0][yi]*rbs;
233
+ rgba_sums[2][1] += rgba[1][yi]*rbs;
234
+ rgba_sums[2][2] += rgba[2][yi]*rbs;
235
+ if (alpha)
236
+ {
237
+ rgba_sums[2][3] += rgba[3][yi]*rbs;
238
+ }
239
+
240
+ if (i>0)
241
+ {
242
+ rgba_sums[0][0] += sir[0];
243
+ rgba_sums[0][1] += sir[1];
244
+ rgba_sums[0][2] += sir[2];
245
+ if (alpha)
246
+ {
247
+ rgba_sums[0][3] += sir[3];
248
+ }
249
+ }
250
+ else
251
+ {
252
+ rgba_sums[1][0] += sir[0];
253
+ rgba_sums[1][1] += sir[1];
254
+ rgba_sums[1][2] += sir[2];
255
+ if (alpha)
256
+ {
257
+ rgba_sums[1][3] += sir[3];
258
+ }
259
+ }
260
+
261
+ if(i < height - 1)
262
+ {
263
+ yp += width;
264
+ }
265
+ }
266
+
267
+ yi = x;
268
+ stackpointer = radius;
269
+
270
+ for (y=0; y<height; y++)
271
+ {
272
+ current = (yi)*bytes;
273
+
274
+ pixels[current + 0] = dv[rgba_sums[2][0]];
275
+ pixels[current + 1] = dv[rgba_sums[2][1]];
276
+ pixels[current + 2] = dv[rgba_sums[2][2]];
277
+ if (alpha)
278
+ {
279
+ pixels[current + 3] = dv[rgba_sums[2][3]];
280
+ }
281
+
282
+ rgba_sums[2][0] -= rgba_sums[1][0];
283
+ rgba_sums[2][1] -= rgba_sums[1][1];
284
+ rgba_sums[2][2] -= rgba_sums[1][2];
285
+ if (alpha)
286
+ {
287
+ rgba_sums[2][3] -= rgba_sums[1][3];
288
+ }
289
+
290
+ stackstart = stackpointer - radius + div;
291
+ sir = stack[stackstart%div];
292
+
293
+ rgba_sums[1][0] -= sir[0];
294
+ rgba_sums[1][1] -= sir[1];
295
+ rgba_sums[1][2] -= sir[2];
296
+ if (alpha)
297
+ {
298
+ rgba_sums[1][3] -= sir[3];
299
+ }
300
+
301
+ if (x == 0)
302
+ {
303
+ vmin[y] = MIN(y + (radius + 1), height - 1)*width;
304
+ }
305
+
306
+ p = x + vmin[y];
307
+
308
+ sir[0] = rgba[0][p];
309
+ sir[1] = rgba[1][p];
310
+ sir[2] = rgba[2][p];
311
+ if (alpha)
312
+ {
313
+ sir[3] = rgba[3][p];
314
+ }
315
+
316
+ rgba_sums[0][0] += sir[0];
317
+ rgba_sums[0][1] += sir[1];
318
+ rgba_sums[0][2] += sir[2];
319
+ if (alpha)
320
+ {
321
+ rgba_sums[0][3] += sir[3];
322
+ }
323
+
324
+ rgba_sums[2][0] += rgba_sums[0][0];
325
+ rgba_sums[2][1] += rgba_sums[0][1];
326
+ rgba_sums[2][2] += rgba_sums[0][2];
327
+ if (alpha)
328
+ {
329
+ rgba_sums[2][3] += rgba_sums[0][3];
330
+ }
331
+
332
+ stackpointer = (stackpointer+1)%div;
333
+ sir = stack[stackpointer];
334
+
335
+ rgba_sums[1][0] += sir[0];
336
+ rgba_sums[1][1] += sir[1];
337
+ rgba_sums[1][2] += sir[2];
338
+ if (alpha)
339
+ {
340
+ rgba_sums[1][3] += sir[3];
341
+ }
342
+
343
+ rgba_sums[0][0] -= sir[0];
344
+ rgba_sums[0][1] -= sir[1];
345
+ rgba_sums[0][2] -= sir[2];
346
+ if (alpha)
347
+ {
348
+ rgba_sums[0][3] -= sir[3];
349
+ }
350
+
351
+ yi += width;
352
+ }
353
+ }
354
+ }
355
+
356
+ return pixbuf;
357
+ }
358
+