pixbufutils 0.0.3 → 0.0.4

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 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
+