pixbufutils 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,1144 +20,39 @@
20
20
 
21
21
  %{
22
22
 
23
- extern void Init_pixbufutils(void);
24
-
25
- #ifndef IGNORE
26
- #define IGNORE(x) x=x
27
- #endif
28
-
29
- static GdkPixbuf *pixbuf_extract_alpha(GdkPixbuf *src, int cutoff, int force_2bit)
30
- {
31
- int s_has_alpha, d_has_alpha;
32
- int s_width, s_height, s_rowstride;
33
- int d_width, d_height, d_rowstride;
34
- GdkPixbuf *dest;
35
- guchar *s_pix, *sp;
36
- guchar *d_pix, *dp;
37
- int i, j, pix_width, grey;
38
-
39
- g_return_val_if_fail(src != NULL, NULL);
40
-
41
- s_width = gdk_pixbuf_get_width(src);
42
- s_height = gdk_pixbuf_get_height(src);
43
- s_has_alpha = gdk_pixbuf_get_has_alpha(src);
44
- s_rowstride = gdk_pixbuf_get_rowstride(src);
45
- s_pix = gdk_pixbuf_get_pixels(src);
46
- g_return_val_if_fail(s_has_alpha, NULL);
47
-
48
- dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, s_width, s_height);
49
-
50
- g_return_val_if_fail(dest != NULL, NULL);
51
-
52
- d_rowstride = gdk_pixbuf_get_rowstride(dest);
53
- d_pix = gdk_pixbuf_get_pixels(dest);
54
-
55
- d_width = gdk_pixbuf_get_width(dest);
56
- d_height = gdk_pixbuf_get_height(dest);
57
- d_has_alpha = gdk_pixbuf_get_has_alpha(dest);
58
- d_rowstride = gdk_pixbuf_get_rowstride(dest);
59
- d_pix = gdk_pixbuf_get_pixels(dest);
60
-
61
- g_return_val_if_fail(d_width == s_width, NULL);
62
- g_return_val_if_fail(d_height == s_height, NULL);
63
-
64
- pix_width = (s_has_alpha ? 4 : 3);
65
-
66
- for (i = 0; i < s_height; i++) {
67
- sp = s_pix;
68
- dp = d_pix;
69
-
70
- for (j = 0; j < s_width; j++) {
71
- grey = sp[3];
72
-
73
- if (grey < cutoff)
74
- grey = 0;
75
-
76
- if (force_2bit)
77
- grey = (grey >= cutoff ? 255 : 0);
78
-
79
- dp[0] = grey; /* red */
80
- dp[1] = grey; /* green */
81
- dp[2] = grey; /* blue */
82
-
83
- dp += 3;
84
- sp += 4;
85
- }
86
-
87
- d_pix += d_rowstride;
88
- s_pix += s_rowstride;
89
- }
90
-
91
- return dest;
92
- }
93
-
94
-
95
- typedef enum {
96
- ANGLE_0 = 0,
97
- ANGLE_90 = 90,
98
- ANGLE_180 = 180,
99
- ANGLE_270 = 270
100
- } rotate_angle_t;
101
-
102
- static GdkPixbuf *
103
- pixbuf_blur(GdkPixbuf *src, gint radius)
104
- {
105
- /* Pixels and Rowstride To Perform Blur On */
106
- guchar *pixels;
107
- GdkPixbuf *pixbuf;
108
- gint rowstride, width, height;
109
-
110
- pixbuf = gdk_pixbuf_copy(src);
111
-
112
- /* Get Pixels and Rowstride Of Image Buffer */
113
- if (pixbuf)
114
- {
115
- pixels = gdk_pixbuf_get_pixels (pixbuf);
116
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
117
- width = gdk_pixbuf_get_width(pixbuf);
118
- height = gdk_pixbuf_get_height(pixbuf);
119
- /*printf("%i, %i, %i, %i\n", rowstride, width, height, rowstride/width);*/
120
- }
121
- else
122
- {
123
- return NULL;
124
- }
125
- if (radius > 1)
126
- {
127
- /* Some Important Consts */
128
- gint bytes = rowstride/width;
129
- gboolean alpha = (bytes == 4);
130
-
131
- gint div = radius+radius+1;
132
- gint divsum = ((div+1)>>1)*((div+1)>>1);
133
- gint dv[256*divsum]; /* Table of Const RGBA Values */
134
-
135
- /* Some Important Variables */
136
- guchar stack[div][bytes];
137
- gint stackpointer;
138
- gint stackstart;
139
- gint vmin[MAX(width,height)];
140
- guchar *sir;
141
- gint rbs;
142
-
143
- gint current = 0;
144
-
145
- /* RGBA Sums
146
- 0 - Sum of Incoming pixels(the radius pixels above the Center/to left of Center)
147
- 1 - Sum of Outgoing pixels(the Center and the radius pixels below the Center/to right of Center)
148
- 2 - Sum of All pixels within radius
149
- */
150
- gint rgba_sums[3][bytes];
151
-
152
- /* RGBA Values */
153
- guchar rgba[bytes][width*height];
154
-
155
- /* Temp Indexes/Counters */
156
- gint x, y, i, p, yp, yi=0, yw=0;
157
-
158
- for (i=0; i<256*divsum; i++)
159
- {
160
- dv[i] = (i/divsum);
161
- }
162
-
163
- for (y=0; y < height; y++)
164
- {
165
- /* initialize sums to zero */
166
- for (i = 0; i<bytes; i++)
167
- {
168
- rgba_sums[0][i] = 0;
169
- rgba_sums[1][i] = 0;
170
- rgba_sums[2][i] = 0;
171
- }
172
-
173
- /* Calculate Initial Sums For radius */
174
- for(i=-radius; i<=radius; i++)
175
- {
176
- current = (yi + MIN(width - 1, MAX(i,0)))*bytes;
177
-
178
- sir = stack[i+radius];
179
-
180
- sir[0] = pixels[current + 0];
181
- sir[1] = pixels[current + 1];
182
- sir[2] = pixels[current + 2];
183
- sir[3] = pixels[current + 3];
184
-
185
- rbs = (radius + 1) - abs(i);
186
-
187
- rgba_sums[2][0] += sir[0]*rbs;
188
- rgba_sums[2][1] += sir[1]*rbs;
189
- rgba_sums[2][2] += sir[2]*rbs;
190
- if (alpha)
191
- {
192
- rgba_sums[2][3] += sir[3]*rbs;
193
- }
194
-
195
- if (i>0)
196
- {
197
- rgba_sums[0][0] += sir[0];
198
- rgba_sums[0][1] += sir[1];
199
- rgba_sums[0][2] += sir[2];
200
- if (alpha)
201
- {
202
- rgba_sums[0][3] += sir[3];
203
- }
204
- }
205
- else
206
- {
207
- rgba_sums[1][0] += sir[0];
208
- rgba_sums[1][1] += sir[1];
209
- rgba_sums[1][2] += sir[2];
210
- if (alpha)
211
- {
212
- rgba_sums[1][3] += sir[3];
213
- }
214
- }
215
- }
216
-
217
- stackpointer = radius;
218
-
219
- for (x=0; x<width; x++)
220
- {
221
- rgba[0][yi] = dv[rgba_sums[2][0]];
222
- rgba[1][yi] = dv[rgba_sums[2][1]];
223
- rgba[2][yi] = dv[rgba_sums[2][2]];
224
- if (alpha)
225
- {
226
- rgba[3][yi] = dv[rgba_sums[2][3]];
227
- }
228
-
229
- rgba_sums[2][0] -= rgba_sums[1][0];
230
- rgba_sums[2][1] -= rgba_sums[1][1];
231
- rgba_sums[2][2] -= rgba_sums[1][2];
232
- if (alpha)
233
- {
234
- rgba_sums[2][3] -= rgba_sums[1][3];
235
- }
236
-
237
- stackstart = stackpointer - radius + div;
238
- sir = stack[stackstart%div];
239
-
240
- rgba_sums[1][0] -= sir[0];
241
- rgba_sums[1][1] -= sir[1];
242
- rgba_sums[1][2] -= sir[2];
243
- if (alpha)
244
- {
245
- rgba_sums[1][3] -= sir[3];
246
- }
247
-
248
- if(y==0)
249
- {
250
- vmin[x] = MIN(x + radius + 1, width - 1);
251
- }
252
-
253
- current = (yw + vmin[x])*bytes;
254
-
255
- sir[0] = pixels[current + 0];
256
- sir[1] = pixels[current + 1];
257
- sir[2] = pixels[current + 2];
258
- if (alpha)
259
- {
260
- sir[3] = pixels[current + 3];
261
- }
262
-
263
- rgba_sums[0][0] += sir[0];
264
- rgba_sums[0][1] += sir[1];
265
- rgba_sums[0][2] += sir[2];
266
- if (alpha)
267
- {
268
- rgba_sums[0][3] += sir[3];
269
- }
270
-
271
- rgba_sums[2][0] += rgba_sums[0][0];
272
- rgba_sums[2][1] += rgba_sums[0][1];
273
- rgba_sums[2][2] += rgba_sums[0][2];
274
- if (alpha)
275
- {
276
- rgba_sums[2][3] += rgba_sums[0][3];
277
- }
278
-
279
- stackpointer=(stackpointer+1)%div;
280
- sir=stack[(stackpointer)%div];
281
-
282
- rgba_sums[1][0] += sir[0];
283
- rgba_sums[1][1] += sir[1];
284
- rgba_sums[1][2] += sir[2];
285
- if (alpha)
286
- {
287
- rgba_sums[1][3] += sir[3];
288
- }
289
-
290
- rgba_sums[0][0] -= sir[0];
291
- rgba_sums[0][1] -= sir[1];
292
- rgba_sums[0][2] -= sir[2];
293
- if (alpha)
294
- {
295
- rgba_sums[0][3] -= sir[3];
296
- }
297
-
298
- yi++;
299
- }
300
-
301
- yw += width;
302
- }
303
-
304
- for (x=0; x<width; x++)
305
- {
306
- yp=-radius*width;
307
-
308
- /* initialize sums to zero */
309
- for (i = 0; i<bytes; i++)
310
- {
311
- rgba_sums[0][i] = 0;
312
- rgba_sums[1][i] = 0;
313
- rgba_sums[2][i] = 0;
314
- }
315
-
316
- /* Calculate Initial Sums For radius */
317
- for(i=-radius; i<=radius; i++)
318
- {
319
- yi = MAX(0,yp) + x;
320
-
321
- sir = stack[i+radius];
322
-
323
- sir[0] = rgba[0][yi];
324
- sir[1] = rgba[1][yi];
325
- sir[2] = rgba[2][yi];
326
- if (alpha)
327
- {
328
- sir[3] = rgba[3][yi];
329
- }
330
-
331
- rbs = (radius + 1) - abs(i);
332
-
333
- rgba_sums[2][0] += rgba[0][yi]*rbs;
334
- rgba_sums[2][1] += rgba[1][yi]*rbs;
335
- rgba_sums[2][2] += rgba[2][yi]*rbs;
336
- if (alpha)
337
- {
338
- rgba_sums[2][3] += rgba[3][yi]*rbs;
339
- }
340
-
341
- if (i>0)
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
- else
352
- {
353
- rgba_sums[1][0] += sir[0];
354
- rgba_sums[1][1] += sir[1];
355
- rgba_sums[1][2] += sir[2];
356
- if (alpha)
357
- {
358
- rgba_sums[1][3] += sir[3];
359
- }
360
- }
361
-
362
- if(i < height - 1)
363
- {
364
- yp += width;
365
- }
366
- }
367
-
368
- yi = x;
369
- stackpointer = radius;
370
-
371
- for (y=0; y<height; y++)
372
- {
373
- current = (yi)*bytes;
374
-
375
- pixels[current + 0] = dv[rgba_sums[2][0]];
376
- pixels[current + 1] = dv[rgba_sums[2][1]];
377
- pixels[current + 2] = dv[rgba_sums[2][2]];
378
- if (alpha)
379
- {
380
- pixels[current + 3] = dv[rgba_sums[2][3]];
381
- }
382
-
383
- rgba_sums[2][0] -= rgba_sums[1][0];
384
- rgba_sums[2][1] -= rgba_sums[1][1];
385
- rgba_sums[2][2] -= rgba_sums[1][2];
386
- if (alpha)
387
- {
388
- rgba_sums[2][3] -= rgba_sums[1][3];
389
- }
390
-
391
- stackstart = stackpointer - radius + div;
392
- sir = stack[stackstart%div];
393
-
394
- rgba_sums[1][0] -= sir[0];
395
- rgba_sums[1][1] -= sir[1];
396
- rgba_sums[1][2] -= sir[2];
397
- if (alpha)
398
- {
399
- rgba_sums[1][3] -= sir[3];
400
- }
401
-
402
- if (x == 0)
403
- {
404
- vmin[y] = MIN(y + (radius + 1), height - 1)*width;
405
- }
406
-
407
- p = x + vmin[y];
408
-
409
- sir[0] = rgba[0][p];
410
- sir[1] = rgba[1][p];
411
- sir[2] = rgba[2][p];
412
- if (alpha)
413
- {
414
- sir[3] = rgba[3][p];
415
- }
416
-
417
- rgba_sums[0][0] += sir[0];
418
- rgba_sums[0][1] += sir[1];
419
- rgba_sums[0][2] += sir[2];
420
- if (alpha)
421
- {
422
- rgba_sums[0][3] += sir[3];
423
- }
424
-
425
- rgba_sums[2][0] += rgba_sums[0][0];
426
- rgba_sums[2][1] += rgba_sums[0][1];
427
- rgba_sums[2][2] += rgba_sums[0][2];
428
- if (alpha)
429
- {
430
- rgba_sums[2][3] += rgba_sums[0][3];
431
- }
432
-
433
- stackpointer = (stackpointer+1)%div;
434
- sir = stack[stackpointer];
435
-
436
- rgba_sums[1][0] += sir[0];
437
- rgba_sums[1][1] += sir[1];
438
- rgba_sums[1][2] += sir[2];
439
- if (alpha)
440
- {
441
- rgba_sums[1][3] += sir[3];
442
- }
443
-
444
- rgba_sums[0][0] -= sir[0];
445
- rgba_sums[0][1] -= sir[1];
446
- rgba_sums[0][2] -= sir[2];
447
- if (alpha)
448
- {
449
- rgba_sums[0][3] -= sir[3];
450
- }
451
-
452
- yi += width;
453
- }
454
- }
455
- }
456
-
457
- return pixbuf;
458
- }
459
-
460
- static GdkPixbuf *
461
- pixbuf_sharpen(GdkPixbuf *src, int strength)
462
- {
463
- GdkPixbuf *dest;
464
- int has_alpha;
465
- int s_width, s_height, s_rowstride;
466
- int d_width, d_height, d_rowstride;
467
- guchar *s_pix;
468
- guchar *d_pix;
469
- guchar *sp;
470
- guchar *dp;
471
- int pix_width;
472
- bool row_only = TRUE;
473
- int a=0, r, g, b, x, y, mul;
474
- int b_a=0, b_r, b_g, b_b;
475
-
476
- if (!src) return NULL;
477
-
478
- s_width = gdk_pixbuf_get_width(src);
479
- s_height = gdk_pixbuf_get_height(src);
480
- has_alpha = gdk_pixbuf_get_has_alpha(src);
481
- s_rowstride = gdk_pixbuf_get_rowstride(src);
482
- s_pix = gdk_pixbuf_get_pixels(src);
483
-
484
- d_width = s_width;
485
- d_height = s_height;
486
-
487
- dest = gdk_pixbuf_copy(src);
488
- d_rowstride = gdk_pixbuf_get_rowstride(dest);
489
- d_pix = gdk_pixbuf_get_pixels(dest);
490
-
491
- pix_width = (has_alpha ? 4 : 3);
492
-
493
- mul = (row_only ? 3 : 5);
494
-
495
- for (y = 0; y < (s_height); y++)
496
- {
497
- sp = s_pix + (y * s_rowstride) + pix_width;
498
- dp = d_pix + (y * d_rowstride) + pix_width;
499
-
500
- for (x = 1; x < (s_width - 1); x++)
501
- {
502
-
503
- b_r = ((int)*(sp));
504
- b_g = ((int)*(sp+1));
505
- b_b = ((int)*(sp+2));
506
- if (has_alpha)
507
- b_a = ((int)*((sp+3)));
508
-
509
- r = b_r * mul;
510
- g = b_g * mul;
511
- b = b_b * mul;
512
- if (has_alpha)
513
- a = b_a * mul;
514
-
515
- r = ((int)*(sp)) * mul;
516
- g = ((int)*(sp+1)) * mul;
517
- b = ((int)*(sp+2)) * mul;
518
- if (has_alpha)
519
- a = ((int)*((sp+3))) * mul;
520
-
521
- r -= (int)*(sp - pix_width);
522
- g -= (int)*(sp - pix_width + 1);
523
- b -= (int)*(sp - pix_width + 2);
524
- if (has_alpha)
525
- a -= (int)*(sp - pix_width + 3);
526
-
527
- r -= (int)*(sp + pix_width);
528
- g -= (int)*(sp + pix_width + 1);
529
- b -= (int)*(sp + pix_width + 2);
530
- if (has_alpha)
531
- a -= (int)*(sp + pix_width + 3);
532
-
533
- if (row_only == 0)
534
- {
535
- r -= (int)*(sp - (s_rowstride));
536
- g -= (int)*(sp + 1 - (s_rowstride));
537
- b -= (int)*(sp + 2 - (s_rowstride));
538
- if (has_alpha)
539
- a -= (int)*(sp + 3 - (s_rowstride));
540
-
541
- r -= (int)*(sp + (s_rowstride));
542
- g -= (int)*(sp + 1 + (s_rowstride));
543
- b -= (int)*(sp + 2 + (s_rowstride));
544
- if (has_alpha)
545
- a -= (int)*(sp + 3 + (s_rowstride));
546
- }
547
-
548
- r = (r & ((~r) >> 16));
549
- r = ((r | ((r & 256) - ((r & 256) >> 8))));
550
- g = (g & ((~g) >> 16));
551
- g = ((g | ((g & 256) - ((g & 256) >> 8))));
552
- b = (b & ((~b) >> 16));
553
- b = ((b | ((b & 256) - ((b & 256) >> 8))));
554
- a = (a & ((~a) >> 16));
555
- a = ((a | ((a & 256) - ((a & 256) >> 8))));
556
-
557
- r = 0xff & (MAX(r,0));
558
- g = 0xff & (MAX(g,0));
559
- b = 0xff & (MAX(b,0));
560
- if (has_alpha)
561
- a = 0xff & (MAX(a,0));
562
-
563
- r = ((r * strength) + b_r) / (strength + 1);
564
- g = ((g * strength) + b_g) / (strength + 1);
565
- b = ((b * strength) + b_b) / (strength + 1);
566
- if (has_alpha)
567
- a = ((a * strength) + b_a) / (strength + 1);
568
-
569
- *(dp++) = r;
570
- *(dp++) = g;
571
- *(dp++) = b;
572
- if (has_alpha)
573
- *(dp++) = a;
574
-
575
- sp += pix_width;
576
- }
577
- }
578
- return dest;
579
- } // */
580
-
581
- static GdkPixbuf *
582
- pixbuf_rotate(GdkPixbuf *src, rotate_angle_t angle)
583
- {
584
- GdkPixbuf *dest;
585
- int has_alpha;
586
- int s_width, s_height, s_rowstride;
587
- int d_width, d_height, d_rowstride;
588
- guchar *s_pix;
589
- guchar *d_pix;
590
- guchar *sp;
591
- guchar *dp;
592
- int i, j, pix_width;
593
-
594
- if (!src) return NULL;
595
-
596
- if (angle == ANGLE_0)
597
- return gdk_pixbuf_copy(src);
598
-
599
- s_width = gdk_pixbuf_get_width(src);
600
- s_height = gdk_pixbuf_get_height(src);
601
- has_alpha = gdk_pixbuf_get_has_alpha(src);
602
- s_rowstride = gdk_pixbuf_get_rowstride(src);
603
- s_pix = gdk_pixbuf_get_pixels(src);
604
-
605
- switch (angle)
606
- {
607
- case ANGLE_90:
608
- case ANGLE_270:
609
- d_width = s_height;
610
- d_height = s_width;
611
- break;
612
- default:
613
- case ANGLE_0:/* Avoid compiler warnings... */
614
- case ANGLE_180:
615
- d_width = s_width;
616
- d_height = s_height;
617
- break;
618
- }
619
-
620
- dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, has_alpha, 8, d_width, d_height);
621
- d_rowstride = gdk_pixbuf_get_rowstride(dest);
622
- d_pix = gdk_pixbuf_get_pixels(dest);
623
-
624
- pix_width = (has_alpha ? 4 : 3);
625
-
626
- for (i = 0; i < s_height; i++) {
627
- sp = s_pix + (i * s_rowstride);
628
- for (j = 0; j < s_width; j++) {
629
- switch (angle)
630
- {
631
- case ANGLE_180:
632
- dp = d_pix + ((d_height - i - 1) * d_rowstride) + ((d_width - j - 1) * pix_width);
633
- break;
634
- case ANGLE_90:
635
- dp = d_pix + (j * d_rowstride) + ((d_width - i - 1) * pix_width);
636
- break;
637
- case ANGLE_270:
638
- dp = d_pix + ((d_height - j - 1) * d_rowstride) + (i * pix_width);
639
- break;
640
- default:
641
- case ANGLE_0:/* Avoid compiler warnings... */
642
- dp = d_pix + (i * d_rowstride) + (j * pix_width);
643
- break;
644
- }
645
-
646
- *(dp++) = *(sp++); /* red */
647
- *(dp++) = *(sp++); /* green */
648
- *(dp++) = *(sp++); /* blue */
649
- if (has_alpha) *(dp) = *(sp++); /* alpha */
650
- }
651
- }
652
-
653
- return dest;
654
- }
655
-
656
- #include <unistd.h>
657
-
658
- static gboolean pixbuf_save_tiff(GdkPixbuf *pixbuf, char *filename)
659
- {
660
- long row;
661
- TIFF *tif;
662
- struct tm *ct;
663
- time_t t;
664
- int width,
665
- height,
666
- rowstride;
667
- guchar *pixels;
668
- short photometric;
669
- short samplesperpixel;
670
- short bitspersample;
671
- static char datetime[40] = "";
672
- char hostname[256] = "";
673
-
674
- time(&t);
675
- ct = localtime(&t);
676
- sprintf(datetime, "%04i:%02i:%02i %02i:%02i:%02i",
677
- 1900 + ct->tm_year, ct->tm_mon + 1, ct->tm_mday,
678
- ct->tm_hour, ct->tm_min, ct->tm_sec);
679
-
680
- tif = TIFFOpen(filename, "w");
681
-
682
- width = gdk_pixbuf_get_width(pixbuf);
683
- height = gdk_pixbuf_get_height(pixbuf);
684
- samplesperpixel = gdk_pixbuf_get_has_alpha(pixbuf) ? 4 : 3;
685
- bitspersample = gdk_pixbuf_get_bits_per_sample(pixbuf);
686
- photometric = PHOTOMETRIC_RGB;
687
- rowstride = gdk_pixbuf_get_rowstride(pixbuf);
688
- pixels = gdk_pixbuf_get_pixels(pixbuf);
689
-
690
-
691
- TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
692
- TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
693
- TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
694
- TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
695
- TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
696
- TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
697
- /*#TIFFSetField(tif, TIFFTAG_DOCUMENTNAME, inf);*/
698
- TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, "Saved from a Gdk::Pixbuf");
699
- TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
700
- TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
701
- TIFFSetField(tif, TIFFTAG_SOFTWARE, "LiveLink Photo Kiosk 1.0");
702
- TIFFSetField(tif, TIFFTAG_DATETIME, datetime);
703
- if(gethostname((char*)&hostname,sizeof(hostname))==0)
704
- TIFFSetField(tif, TIFFTAG_HOSTCOMPUTER, hostname);
705
-
706
- for (row = 0; row < height; row++) {
707
- if (TIFFWriteScanline(tif, (u_char *) pixels, row, 0) < 0) {
708
- fprintf(stderr, "failed a scanline write (%li)\n", row);
709
- break;
710
- }
711
- pixels = GINT_TO_POINTER(GPOINTER_TO_INT(pixels) + rowstride);
712
- }
713
- TIFFFlushData(tif);
714
- TIFFClose(tif);
715
-
716
- return TRUE;
717
- }
718
-
719
- #include <math.h>
720
-
721
- static GdkPixbuf *pixbuf_gamma(GdkPixbuf *src, GdkPixbuf *dest, double gamma)
722
- {
723
- int has_alpha;
724
- int s_width, s_height, s_rowstride;
725
- int d_width, d_height, d_rowstride;
726
- guchar *s_pix;
727
- guchar *d_pix;
728
- guchar *sp;
729
- guchar *dp;
730
- int i, j, pix_width;
731
- double map[256] = {0.0,};
732
-
733
- for (i=0; i < 256; i++)
734
- map[i] = 255 * pow((double) i/255, 1.0/gamma);
735
-
736
- g_return_val_if_fail(src != NULL, NULL);
737
- g_return_val_if_fail(dest != NULL, NULL);
738
-
739
- s_width = gdk_pixbuf_get_width(src);
740
- s_height = gdk_pixbuf_get_height(src);
741
- has_alpha = gdk_pixbuf_get_has_alpha(src);
742
- s_rowstride = gdk_pixbuf_get_rowstride(src);
743
- s_pix = gdk_pixbuf_get_pixels(src);
744
-
745
- d_width = gdk_pixbuf_get_width(dest);
746
- d_height = gdk_pixbuf_get_height(dest);
747
- d_rowstride = gdk_pixbuf_get_rowstride(dest);
748
- d_pix = gdk_pixbuf_get_pixels(dest);
749
-
750
- g_return_val_if_fail(d_width == s_width, NULL);
751
- g_return_val_if_fail(d_height == s_height, NULL);
752
- g_return_val_if_fail(has_alpha == gdk_pixbuf_get_has_alpha(dest), NULL);
753
-
754
- pix_width = (has_alpha ? 4 : 3);
755
-
756
- for (i = 0; i < s_height; i++) {
757
- sp = s_pix + (i * s_rowstride);
758
- dp = d_pix + (i * d_rowstride);
759
- for (j = 0; j < s_width; j++) {
760
- *(dp++) = map[*(sp++)]; /* red */
761
- *(dp++) = map[*(sp++)]; /* green */
762
- *(dp++) = map[*(sp++)]; /* blue */
763
- if (has_alpha) *(dp++) = map[*(sp++)]; /* alpha */
764
- }
765
- }
766
-
767
- return dest;
768
- }
769
-
770
23
  #define PIXEL(row, channels, x) ((pixel_t)(row + (channels * x)))
771
24
 
772
25
  typedef struct {
773
26
  unsigned char r,g,b,a;
774
27
  } * pixel_t;
775
28
 
776
- #define RLUM (0.3086)
777
- #define GLUM (0.6094)
778
- #define BLUM (0.0820)
779
-
780
- // Graphica Obscure
781
- #define GO_RGB_TO_GREY(r,g,b) ((int)((RLUM * (double)r) + (GLUM * (double)g) + (BLUM * (double)b)))
782
-
783
- // Gimp Values
784
- #define GIMP_RGB_TO_GREY(r,g,b) (((77 * r) + (151 * g) + (28 * b)) >> 8)
785
-
786
- static GdkPixbuf *pixbuf_mask(GdkPixbuf *src, GdkPixbuf *mask)
787
- {
788
- int s_has_alpha, m_has_alpha;
789
- int s_width, s_height, s_rowstride;
790
- int d_width, d_height, d_rowstride;
791
- int m_width, m_height, m_rowstride;
792
- guchar *s_pix, *sp;
793
- guchar *d_pix, *dp;
794
- guchar *m_pix, *mp;
795
- int i, j, pix_width, alpha, grey;
796
- pixel_t pix;
797
- GdkPixbuf *dest;
798
-
799
- g_return_val_if_fail(src != NULL, NULL);
800
-
801
- s_width = gdk_pixbuf_get_width(src);
802
- s_height = gdk_pixbuf_get_height(src);
803
- s_has_alpha = gdk_pixbuf_get_has_alpha(src);
804
- s_rowstride = gdk_pixbuf_get_rowstride(src);
805
- s_pix = gdk_pixbuf_get_pixels(src);
806
-
807
- g_return_val_if_fail(mask != NULL, NULL);
808
-
809
- m_width = gdk_pixbuf_get_width(mask);
810
- m_height = gdk_pixbuf_get_height(mask);
811
- m_has_alpha = gdk_pixbuf_get_has_alpha(mask);
812
- m_rowstride = gdk_pixbuf_get_rowstride(mask);
813
- m_pix = gdk_pixbuf_get_pixels(mask);
814
-
815
- g_return_val_if_fail(m_width <= s_width, NULL);
816
- g_return_val_if_fail(m_height <= s_height, NULL);
817
-
818
- d_width = m_width;
819
- d_height = m_height;
820
- dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, d_width, d_height);
821
-
822
- g_return_val_if_fail(dest != NULL, NULL);
823
-
824
- d_rowstride = gdk_pixbuf_get_rowstride(dest);
825
- d_pix = gdk_pixbuf_get_pixels(dest);
826
-
827
- pix_width = (m_has_alpha ? 4 : 3);
828
-
829
-
830
-
831
- for (i = 0; i < m_height; i++) {
832
- sp = s_pix + (i * s_rowstride);
833
- dp = d_pix + (i * d_rowstride);
834
- mp = m_pix + (i * m_rowstride);
835
-
836
- for (j = 0; j < m_width; j++) {
837
- *(dp++) = *(sp++); /* red */
838
- *(dp++) = *(sp++); /* green */
839
- *(dp++) = *(sp++); /* blue */
840
-
841
- if (s_has_alpha)
842
- {
843
- alpha = *(sp++); /* alpha */
844
- }
845
- else
846
- {
847
- alpha = 0xff;
848
- }
849
-
850
- pix = PIXEL(mp, pix_width, j);
851
- grey = GIMP_RGB_TO_GREY(pix->r, pix->g, pix->b);
852
-
853
- *(dp++) = sqrt(alpha * (255 - grey)); /* alpha */
854
- }
855
- }
856
-
857
- return dest;
858
- }
859
-
860
- static GdkPixbuf *pixbuf_blend5050(GdkPixbuf *src1, GdkPixbuf *src2)
861
- {
862
- int s1_has_alpha, s2_has_alpha;
863
- int s1_width, s1_height, s1_rowstride;
864
- int d_width, d_height, d_rowstride;
865
- int s2_width, s2_height, s2_rowstride;
866
- guchar *s1_pix, *sp;
867
- guchar *d_pix, *dp;
868
- guchar *s2_pix, *mp;
869
- int i, j;
870
- GdkPixbuf *dest;
871
-
872
- g_return_val_if_fail(src1 != NULL, NULL);
873
-
874
- s1_width = gdk_pixbuf_get_width(src1);
875
- s1_height = gdk_pixbuf_get_height(src1);
876
- s1_has_alpha = gdk_pixbuf_get_has_alpha(src1);
877
- s1_rowstride = gdk_pixbuf_get_rowstride(src1);
878
- s1_pix = gdk_pixbuf_get_pixels(src1);
879
-
880
- g_return_val_if_fail(src2 != NULL, NULL);
881
-
882
- s2_width = gdk_pixbuf_get_width(src2);
883
- s2_height = gdk_pixbuf_get_height(src2);
884
- s2_has_alpha = gdk_pixbuf_get_has_alpha(src2);
885
- s2_rowstride = gdk_pixbuf_get_rowstride(src2);
886
- s2_pix = gdk_pixbuf_get_pixels(src2);
887
-
888
- g_return_val_if_fail(s2_width == s1_width, NULL);
889
- g_return_val_if_fail(s2_height == s1_height, NULL);
890
- g_return_val_if_fail(s2_has_alpha == s1_has_alpha, NULL);
891
-
892
- d_width = s2_width;
893
- d_height = s2_height;
894
-
895
- dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, d_width, d_height);
896
-
897
- g_return_val_if_fail(dest != NULL, NULL);
898
-
899
- d_rowstride = gdk_pixbuf_get_rowstride(dest);
900
- d_pix = gdk_pixbuf_get_pixels(dest);
901
-
902
- for (i = 0; i < s2_height; i++) {
903
- sp = s1_pix + (i * s1_rowstride);
904
- mp = s2_pix + (i * s2_rowstride);
905
- dp = d_pix + (i * d_rowstride);
906
-
907
- for (j = 0; j < s2_width; j++) {
908
- *(dp++) = ((*(sp++)) >> 1) + ((*(mp++)) >> 1); /* red */
909
- *(dp++) = ((*(sp++)) >> 1) + ((*(mp++)) >> 1); /* green */
910
- *(dp++) = ((*(sp++)) >> 1) + ((*(mp++)) >> 1); /* blue */
911
-
912
- if (s1_has_alpha)
913
- *(dp++) = ((*(sp++)) >> 1) + ((*(mp++)) >> 1); /* alpha */
914
- else
915
- *(dp++) = 0xff; /* alpha */
916
-
917
- }
918
- }
919
-
920
- return dest;
921
- }
922
-
923
-
924
- static GdkPixbuf *pixbuf_greyscale(GdkPixbuf *src, GdkPixbuf *dest)
925
- {
926
- int s_has_alpha, d_has_alpha;
927
- int s_width, s_height, s_rowstride;
928
- int d_width, d_height, d_rowstride;
929
- guchar *s_pix, *sp;
930
- guchar *d_pix, *dp;
931
- int i, j, pix_width, grey;
932
-
933
- g_return_val_if_fail(src != NULL, NULL);
934
- g_return_val_if_fail(dest != NULL, NULL);
935
-
936
- s_width = gdk_pixbuf_get_width(src);
937
- s_height = gdk_pixbuf_get_height(src);
938
- s_has_alpha = gdk_pixbuf_get_has_alpha(src);
939
- s_rowstride = gdk_pixbuf_get_rowstride(src);
940
- s_pix = gdk_pixbuf_get_pixels(src);
941
-
942
- d_width = gdk_pixbuf_get_width(dest);
943
- d_height = gdk_pixbuf_get_height(dest);
944
- d_has_alpha = gdk_pixbuf_get_has_alpha(dest);
945
- d_rowstride = gdk_pixbuf_get_rowstride(dest);
946
- d_pix = gdk_pixbuf_get_pixels(dest);
947
-
948
- g_return_val_if_fail(d_width == s_width, NULL);
949
- g_return_val_if_fail(d_height == s_height, NULL);
950
- g_return_val_if_fail(d_has_alpha == s_has_alpha, NULL);
951
-
952
- pix_width = (s_has_alpha ? 4 : 3);
953
-
954
-
955
- for (i = 0; i < s_height; i++) {
956
- sp = s_pix;
957
- dp = d_pix;
958
-
959
- for (j = 0; j < s_width; j++) {
960
- grey = GIMP_RGB_TO_GREY(sp[0], sp[1], sp[2]);
961
-
962
- dp[0] = grey; /* red */
963
- dp[1] = grey; /* green */
964
- dp[2] = grey; /* blue */
965
-
966
- if (s_has_alpha)
967
- {
968
- dp[3] = sp[3]; /* alpha */
969
- }
970
-
971
- dp += pix_width;
972
- sp += pix_width;
973
- }
974
-
975
- d_pix += d_rowstride;
976
- s_pix += s_rowstride;
977
- }
978
-
979
- return dest;
980
- }
981
-
982
- static GdkPixbuf *pixbuf_greyscale_go(GdkPixbuf *src, GdkPixbuf *dest)
983
- {
984
- int s_has_alpha, d_has_alpha;
985
- int s_width, s_height, s_rowstride;
986
- int d_width, d_height, d_rowstride;
987
- guchar *s_pix, *sp;
988
- guchar *d_pix, *dp;
989
- int i, j, pix_width, grey;
990
-
991
- g_return_val_if_fail(src != NULL, NULL);
992
- g_return_val_if_fail(dest != NULL, NULL);
993
-
994
- s_width = gdk_pixbuf_get_width(src);
995
- s_height = gdk_pixbuf_get_height(src);
996
- s_has_alpha = gdk_pixbuf_get_has_alpha(src);
997
- s_rowstride = gdk_pixbuf_get_rowstride(src);
998
- s_pix = gdk_pixbuf_get_pixels(src);
999
-
1000
- d_width = gdk_pixbuf_get_width(dest);
1001
- d_height = gdk_pixbuf_get_height(dest);
1002
- d_has_alpha = gdk_pixbuf_get_has_alpha(dest);
1003
- d_rowstride = gdk_pixbuf_get_rowstride(dest);
1004
- d_pix = gdk_pixbuf_get_pixels(dest);
1005
-
1006
- g_return_val_if_fail(d_width == s_width, NULL);
1007
- g_return_val_if_fail(d_height == s_height, NULL);
1008
- g_return_val_if_fail(d_has_alpha == s_has_alpha, NULL);
1009
-
1010
- pix_width = (s_has_alpha ? 4 : 3);
1011
-
1012
- for (i = 0; i < s_height; i++) {
1013
- sp = s_pix;
1014
- dp = d_pix;
1015
-
1016
- for (j = 0; j < s_width; j++) {
1017
- grey = GO_RGB_TO_GREY(sp[0], sp[1], sp[2]);
1018
-
1019
- dp[0] = grey; /* red */
1020
- dp[1] = grey; /* green */
1021
- dp[2] = grey; /* blue */
1022
-
1023
- if (s_has_alpha)
1024
- {
1025
- dp[3] = sp[3]; /* alpha */
1026
- }
1027
-
1028
- dp += pix_width;
1029
- sp += pix_width;
1030
- }
1031
-
1032
- d_pix += d_rowstride;
1033
- s_pix += s_rowstride;
1034
- }
1035
-
1036
- return dest;
1037
- }
1038
-
1039
- static inline unsigned char pu_clamp(int x)
1040
- {
1041
- unsigned char i = (x > 255) ? 255 : (x < 0 ? 0 : x);
1042
- return i;
1043
- }
1044
-
1045
- static GdkPixbuf *pixbuf_tint(GdkPixbuf *src, GdkPixbuf *dest, int r, int g, int b, int alpha)
1046
- {
1047
- int s_has_alpha, d_has_alpha;
1048
- int s_width, s_height, s_rowstride;
1049
- int d_width, d_height, d_rowstride;
1050
- guchar *s_pix, *sp;
1051
- guchar *d_pix, *dp;
1052
- int i, j, pix_width, grey;
1053
-
1054
- g_return_val_if_fail(src != NULL, NULL);
1055
- g_return_val_if_fail(dest != NULL, NULL);
1056
-
1057
- s_width = gdk_pixbuf_get_width(src);
1058
- s_height = gdk_pixbuf_get_height(src);
1059
- s_has_alpha = gdk_pixbuf_get_has_alpha(src);
1060
- s_rowstride = gdk_pixbuf_get_rowstride(src);
1061
- s_pix = gdk_pixbuf_get_pixels(src);
1062
-
1063
- d_width = gdk_pixbuf_get_width(dest);
1064
- d_height = gdk_pixbuf_get_height(dest);
1065
- d_has_alpha = gdk_pixbuf_get_has_alpha(dest);
1066
- d_rowstride = gdk_pixbuf_get_rowstride(dest);
1067
- d_pix = gdk_pixbuf_get_pixels(dest);
1068
-
1069
- g_return_val_if_fail(d_width == s_width, NULL);
1070
- g_return_val_if_fail(d_height == s_height, NULL);
1071
- g_return_val_if_fail(d_has_alpha == s_has_alpha, NULL);
1072
-
1073
- pix_width = (s_has_alpha ? 4 : 3);
1074
-
1075
- for (i = 0; i < s_height; i++) {
1076
- sp = s_pix;
1077
- dp = d_pix;
1078
-
1079
- for (j = 0; j < s_width; j++) {
1080
- grey = GO_RGB_TO_GREY(sp[0], sp[1], sp[2]);
1081
-
1082
- dp[0] = pu_clamp(pu_clamp(((int)grey + r) * alpha / 255) + pu_clamp((int)sp[0] * (255 - alpha) / 255)); /* red */
1083
-
1084
- //fprintf(stderr, "alpha=%i, r=%i, grey=%i -> %i + %i = %i\n", alpha, r, grey, pu_clamp(((int)grey + r) * alpha / 255), pu_clamp((int)sp[0] * (255 - alpha) / 255), dp[0]); /* red */
1085
-
1086
- dp[1] = pu_clamp(pu_clamp((grey + g) * alpha / 255) + pu_clamp((int)sp[1] * (255 - alpha) / 255)); /* green */
1087
- dp[2] = pu_clamp(pu_clamp((grey + b) * alpha / 255) + pu_clamp((int)sp[2] * (255 - alpha) / 255)); /* blue */
1088
-
1089
- if (s_has_alpha)
1090
- {
1091
- dp[3] = sp[3]; /* alpha */
1092
- }
1093
-
1094
- dp += pix_width;
1095
- sp += pix_width;
1096
- }
1097
-
1098
- d_pix += d_rowstride;
1099
- s_pix += s_rowstride;
1100
- }
1101
-
1102
- return dest;
1103
- }
1104
-
1105
- static GdkPixbuf *pixbuf_soften_edges(GdkPixbuf *dest, int size)
1106
- {
1107
- int d_has_alpha;
1108
- int d_width, d_height, d_rowstride;
1109
- guchar *d_pix, *dp;
1110
- int i, j, pix_width;
1111
-
1112
- g_return_val_if_fail(dest != NULL, NULL);
1113
-
1114
- d_width = gdk_pixbuf_get_width(dest);
1115
- d_height = gdk_pixbuf_get_height(dest);
1116
- d_has_alpha = gdk_pixbuf_get_has_alpha(dest);
1117
- d_rowstride = gdk_pixbuf_get_rowstride(dest);
1118
- d_pix = gdk_pixbuf_get_pixels(dest);
1119
-
1120
- g_return_val_if_fail(d_has_alpha, NULL);
1121
-
1122
- pix_width = (d_has_alpha ? 4 : 3);
29
+ extern void Init_pixbufutils(void);
1123
30
 
1124
- for (i = 0; i < MIN(size,d_height); i++) {
1125
- dp = d_pix + (i * d_rowstride);
1126
- //pix = (pixel_t)dp;
1127
- for (j = 0; j < d_width; j++) {
1128
- dp[3] = (dp[3] * i) / size; /* alpha */
1129
- dp += pix_width;
1130
- }
1131
-
1132
- dp = d_pix + ((d_height - i - 1) * d_rowstride);
1133
- for (j = 0; j < d_width; j++) {
1134
- dp[3] = (dp[3] * i) / size; /* alpha */
1135
- dp += pix_width;
1136
- }
1137
-
1138
- }
1139
- for (j = 0; j < d_height; j++) {
1140
- //pix = (pixel_t)GINT_TO_POINTER(GPOINTER_TO_INT(d_pix) + (j * d_rowstride));
1141
- dp = d_pix + ((d_height - i - 1) * d_rowstride);
1142
- for (i = 0; i < MIN(size, d_width); i++) {
1143
- dp[3] = (dp[3] * i) / size; /* alpha */
1144
- dp += pix_width;
1145
- }
1146
-
1147
- dp = d_pix + (j * d_rowstride) + (pix_width * d_width);
1148
- for (i = 0; i < MIN(size, d_width); i++) {
1149
- dp[3] = (dp[3] * i) / size; /* alpha */
1150
- dp -= pix_width;
1151
- }
1152
- }
31
+ #ifndef IGNORE
32
+ #define IGNORE(x) x=x
33
+ #endif
1153
34
 
1154
- return dest;
1155
- }
35
+ #include <unistd.h>
36
+ #include <math.h>
1156
37
 
38
+ #include "extract-alpha.h"
39
+ #include "blur.h"
40
+ #include "sharpen.h"
41
+ #include "greyscale.h"
42
+ #include "rotate.h"
43
+ #include "tiff.h"
44
+ #include "gamma.h"
45
+ #include "mask.h"
46
+ #include "blend5050.h"
47
+ #include "tint.h"
48
+ #include "soften-edges.h"
49
+ #include "histogram.h"
50
+ #include "auto-equalize.h"
51
+ #include "filter.h"
1157
52
 
1158
53
 
1159
54
  /*
1160
- GdkPixbuf *pixbuf_op(GdkPixbuf *src, GdkPixbuf *dest,
55
+ GdkPixbuf *pixbuf_op(GdkPixbuf *src, GdkPixbuf *dest,
1161
56
  */
1162
57
 
1163
58
  static GdkPixbuf *pixbuf_perspect_v(GdkPixbuf *src, int top_x1, int top_x2, int bot_x1, int bot_x2)
@@ -1177,65 +72,65 @@ static GdkPixbuf *pixbuf_perspect_v(GdkPixbuf *src, int top_x1, int top_x2, int
1177
72
  double row_offset2, row_end2;
1178
73
  double left_theta, right_theta;
1179
74
  pixel_t spx[3];
1180
- double ex;
1181
-
75
+ double ex;
76
+
1182
77
  s_width = gdk_pixbuf_get_width(src);
1183
78
  s_height = gdk_pixbuf_get_height(src);
1184
79
  has_alpha = gdk_pixbuf_get_has_alpha(src);
1185
80
  s_rowstride = gdk_pixbuf_get_rowstride(src);
1186
81
  s_pix = gdk_pixbuf_get_pixels(src);
1187
-
1188
-
82
+
83
+
1189
84
  g_return_val_if_fail((top_x2 - top_x1) <= s_width, NULL);
1190
85
  g_return_val_if_fail((bot_x2 - bot_x1) <= s_width, NULL);
1191
-
86
+
1192
87
  d_width = s_width;
1193
88
  d_height = s_height;
1194
89
  dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, d_width, d_height);
1195
90
  d_rowstride = gdk_pixbuf_get_rowstride(dest);
1196
91
  d_pix = gdk_pixbuf_get_pixels(dest);
1197
-
92
+
1198
93
  // Shortcut ... should be harmless?
1199
94
  // We should really only touch info
1200
95
  // Within the range d_pix + (d_rowstride * y) + ((has_alpha ? 4 : 3) * x)
1201
96
  bzero(d_pix, (d_rowstride * d_height));
1202
-
97
+
1203
98
  top_width = top_x2 - top_x1;
1204
99
  bot_width = bot_x2 - bot_x1;
1205
-
100
+
1206
101
  min_x = MIN(top_x1, bot_x1);
1207
102
  max_x = MAX(top_x2, bot_x2);
1208
-
103
+
1209
104
  s_channels = has_alpha ? 4 : 3;
1210
105
  channels = 4;
1211
-
106
+
1212
107
  left_theta = ((double)(min_x == bot_x1 ? top_x1 : bot_x1) - min_x) / (double)d_height;
1213
108
  right_theta = ((double)max_x - ((max_x == bot_x2) ? top_x2 : bot_x2)) / (double)d_height;
1214
-
1215
-
109
+
110
+
1216
111
  for (y = 0; y < d_height; y++) {
1217
112
  sp = s_pix + (y * s_rowstride);
1218
-
113
+
1219
114
  row_offset = min_x;
1220
115
  row_end = max_x;
1221
-
116
+
1222
117
  row_offset2 = min_x;
1223
118
  row_end2 = max_x;
1224
-
119
+
1225
120
  row_offset += (left_theta * ((min_x == bot_x1) ? (d_height - y - 1) : y));
1226
121
  row_end -= (right_theta * ((max_x == bot_x2) ? (d_height - y - 1) : y));
1227
-
122
+
1228
123
  row_offset2 += (left_theta * ((min_x == bot_x1) ? (d_height - y) : y+1));
1229
124
  row_end2 -= (right_theta * ((max_x == bot_x2) ? (d_height - y) : y+1));
1230
-
125
+
1231
126
  row_width = ceil(row_end) - floor(row_offset);
1232
-
127
+
1233
128
  dp = d_pix + (y * d_rowstride) + ((int)floor(row_offset) * channels);
1234
-
129
+
1235
130
  for (x = (int)floor(row_offset); x < (int)ceil(row_end); x++)
1236
131
  {
1237
132
  ex = x - floor(row_offset);
1238
-
133
+
1239
134
  if ((x < ceil(row_offset)))
1240
135
  {
1241
136
  alpha = ((int) ((double)255 * (ceil(row_offset) - row_offset)));
@@ -1250,11 +145,11 @@ static GdkPixbuf *pixbuf_perspect_v(GdkPixbuf *src, int top_x1, int top_x2, int
1250
145
  {
1251
146
  alpha = 0xff;
1252
147
  }
1253
-
148
+
1254
149
  spx[0] = PIXEL(sp, s_channels, (int)floor(((ex - 1) * (double)s_width) / (double)row_width));
1255
150
  spx[1] = PIXEL(sp, s_channels, (int)floor((ex * (double)s_width) / (double)row_width));
1256
151
  spx[2] = PIXEL(sp, s_channels, (int)floor(((ex + 1) * (double)s_width) / (double)row_width));
1257
-
152
+
1258
153
  *(dp++) = ((spx[1]->r * 14) + ((spx[0]->r + spx[2]->r))) >> 4; /* red */
1259
154
  *(dp++) = ((spx[1]->g * 14) + ((spx[0]->g + spx[2]->g))) >> 4; /* green */
1260
155
  *(dp++) = ((spx[1]->b * 14) + ((spx[0]->b + spx[2]->b))) >> 4; /* blue */
@@ -1263,9 +158,9 @@ static GdkPixbuf *pixbuf_perspect_v(GdkPixbuf *src, int top_x1, int top_x2, int
1263
158
  else
1264
159
  *(dp++) = alpha; /* alpha */
1265
160
  }
1266
-
161
+
1267
162
  }
1268
-
163
+
1269
164
  return dest;
1270
165
  }
1271
166
 
@@ -1277,27 +172,27 @@ static VALUE pixbuf_mask_area(GdkPixbuf *mask, double cutoff)
1277
172
  guchar *m_pix, *mp;
1278
173
  long int y, x;
1279
174
  long pix_width;
1280
- volatile
175
+ volatile
1281
176
  double grey;
1282
-
177
+
1283
178
  g_return_val_if_fail(mask != NULL, Qnil);
1284
-
179
+
1285
180
  m_width = gdk_pixbuf_get_width(mask);
1286
181
  m_height = gdk_pixbuf_get_height(mask);
1287
182
  m_has_alpha = gdk_pixbuf_get_has_alpha(mask);
1288
183
  m_rowstride = gdk_pixbuf_get_rowstride(mask);
1289
184
  m_pix = gdk_pixbuf_get_pixels(mask);
1290
-
185
+
1291
186
  pix_width = (m_has_alpha ? 4 : 3);
1292
187
 
1293
-
188
+
1294
189
  x1 = m_width;
1295
190
  y1 = m_height;
1296
-
191
+
1297
192
  for (y = 0; y < m_height; y++)
1298
193
  {
1299
194
  mp = m_pix;
1300
- for (x = 0; x < m_width; x++)
195
+ for (x = 0; x < m_width; x++)
1301
196
  {
1302
197
  grey = GIMP_RGB_TO_GREY(mp[0], mp[1], mp[2]);
1303
198
  if (grey < cutoff)// ie. darker than cutoff
@@ -1312,7 +207,7 @@ static VALUE pixbuf_mask_area(GdkPixbuf *mask, double cutoff)
1312
207
  x0 = MIN(x0, x);
1313
208
  x1 = MAX(x1, x);
1314
209
  }
1315
-
210
+
1316
211
  if (y0 == 0)
1317
212
  {
1318
213
  y0 = MAX(y0, y);
@@ -1324,24 +219,24 @@ static VALUE pixbuf_mask_area(GdkPixbuf *mask, double cutoff)
1324
219
  y1 = MAX(y1, y);
1325
220
  }
1326
221
  }
1327
-
222
+
1328
223
  mp += pix_width;
1329
224
  }
1330
225
  m_pix += m_rowstride;
1331
226
  }
1332
-
227
+
1333
228
  return rb_ary_new3(4, INT2NUM(x0), INT2NUM(y0), INT2NUM(x1), INT2NUM(y1));
1334
229
  }
1335
230
 
1336
- static inline VALUE
231
+ static inline VALUE
1337
232
  unref_pixbuf(GdkPixbuf *pixbuf)
1338
233
  {
1339
234
  volatile VALUE pb = Qnil;
1340
-
235
+
1341
236
  pb = GOBJ2RVAL(pixbuf);
1342
-
237
+
1343
238
  g_object_unref(pixbuf);
1344
-
239
+
1345
240
  return pb;
1346
241
  }
1347
242
 
@@ -1379,7 +274,7 @@ module PixbufUtils
1379
274
 
1380
275
  gdk_pixbuf_fill(dest, pixcol);
1381
276
  gdk_pixbuf_composite(src, dest, 0, 0, w, h, 0, 0, 1.0, 1.0, GDK_INTERP_NEAREST, 0xff);
1382
-
277
+
1383
278
  return dest;
1384
279
  end
1385
280
  def unref_pixbuf:self.sharpen(GdkPixbuf *src, int radius)
@@ -1394,6 +289,40 @@ module PixbufUtils
1394
289
  IGNORE(self);
1395
290
  return pixbuf_blur(gdk_pixbuf_copy(src), radius);
1396
291
  end
292
+ def unref_pixbuf:self.contrast(GdkPixbuf *src, int adjust)
293
+ IGNORE(self);
294
+ return pixbuf_adjust_contrast(src, gdk_pixbuf_copy(src), adjust);
295
+ end
296
+ def unref_pixbuf:self.vibrance(GdkPixbuf *src, int adjust)
297
+ IGNORE(self);
298
+ return pixbuf_adjust_vibrance(src, gdk_pixbuf_copy(src), adjust);
299
+ end
300
+ def unref_pixbuf:self.saturation(GdkPixbuf *src, int adjust)
301
+ IGNORE(self);
302
+ return pixbuf_adjust_saturation(src, gdk_pixbuf_copy(src), adjust);
303
+ end
304
+ def unref_pixbuf:self.brightness(GdkPixbuf *src, int adjust)
305
+ IGNORE(self);
306
+ return pixbuf_adjust_brightness(src, gdk_pixbuf_copy(src), adjust);
307
+ end
308
+ def unref_pixbuf:self.filter(GdkPixbuf *src, T_ARRAY filter, double divisor)
309
+ int matrix_size = RARRAY_LEN(filter), len, i;
310
+ double *matrix;
311
+
312
+ IGNORE(self);
313
+ len = (int) sqrt((double)matrix_size);
314
+
315
+ if ((len * len) != matrix_size) {
316
+ rb_raise(rb_eArgError, "Invalid matrix size - sqrt(%i)*sqrt(%i) != %i", matrix_size, matrix_size, matrix_size);
317
+ }
318
+ matrix = ALLOCA_N(double, matrix_size);
319
+
320
+ for (i = 0; i < matrix_size; i ++) {
321
+ matrix[i] = NUM2DBL(RARRAY_PTR(filter)[i]);
322
+ }
323
+
324
+ return pixbuf_convolution_matrix(src, gdk_pixbuf_copy(src), len, matrix, divisor);
325
+ end
1397
326
  def unref_pixbuf:self.rotate_90(GdkPixbuf *src, bool counter_clockwise)
1398
327
  IGNORE(self);
1399
328
  return pixbuf_rotate(src, counter_clockwise ? ANGLE_270 : ANGLE_90);
@@ -1459,6 +388,10 @@ module PixbufUtils
1459
388
  IGNORE(self);
1460
389
  return pixbuf_mask(src, mask);
1461
390
  end
391
+ def unref_pixbuf:self.auto_equalize(GdkPixbuf *src)
392
+ IGNORE(self);
393
+ return auto_equalize(src, gdk_pixbuf_copy(src));
394
+ end
1462
395
  def unref_pixbuf:self.blend5050(GdkPixbuf *src1, GdkPixbuf *src2)
1463
396
  IGNORE(self);
1464
397
  return pixbuf_blend5050(src1, src2);
@@ -1470,7 +403,7 @@ module PixbufUtils
1470
403
  def unref_pixbuf:self.scale_max(GdkPixbuf *src, gulong max, GdkInterpType interp = GDK_INTERP_BILINEAR)
1471
404
  gulong width, height, largest;
1472
405
  gdouble scale;
1473
-
406
+
1474
407
  IGNORE(self);
1475
408
  width = gdk_pixbuf_get_width(src);
1476
409
  height = gdk_pixbuf_get_height(src);
@@ -1479,17 +412,17 @@ module PixbufUtils
1479
412
  {
1480
413
  return gdk_pixbuf_copy(src);
1481
414
  }
1482
-
415
+
1483
416
  scale = (double)(max) / (double)(largest);
1484
-
417
+
1485
418
  return gdk_pixbuf_scale_simple(src, (int)(scale * width), (int)(scale * height), interp);
1486
419
  end
1487
- def self.draw_scaled(GdkDrawable *drawable, GdkPixbuf *src, int x, int y,
420
+ def self.draw_scaled(GdkDrawable *drawable, GdkPixbuf *src, int x, int y,
1488
421
  int width, int height, GdkInterpType interp = GDK_INTERP_BILINEAR)
1489
-
422
+
1490
423
  GdkPixbuf *tmp;
1491
-
1492
-
424
+
425
+
1493
426
  IGNORE(self);
1494
427
  if((width == gdk_pixbuf_get_width(src)) && (height == gdk_pixbuf_get_height(src)))
1495
428
  {
@@ -1504,7 +437,7 @@ module PixbufUtils
1504
437
  g_object_set_data_full(G_OBJECT(src), "pixbuf_utils_scaled", tmp, g_object_unref);
1505
438
  }
1506
439
  g_return_val_if_fail(tmp != NULL, Qfalse);
1507
-
440
+
1508
441
  gdk_draw_pixbuf(/* GdkDrawable *drawable */ drawable,
1509
442
  /* GdkGC *gc */ NULL,
1510
443
  /* GdkPixbuf *pixbuf */ tmp,
@@ -1518,14 +451,14 @@ module PixbufUtils
1518
451
  /* gint x_dither */ 0,
1519
452
  /* gint y_dither */ 0);
1520
453
  return Qtrue;
1521
-
454
+
1522
455
  end
1523
- def self.draw_scaled_clip(GdkDrawable *drawable, GdkPixbuf *src, int x, int y,
456
+ def self.draw_scaled_clip(GdkDrawable *drawable, GdkPixbuf *src, int x, int y,
1524
457
  int width, int height, GdkRectangle *clip_area, GdkInterpType interp = GDK_INTERP_BILINEAR)
1525
-
458
+
1526
459
  GdkPixbuf *tmp;
1527
460
  GdkGC *gc;
1528
-
461
+
1529
462
  IGNORE(self);
1530
463
  if((width == gdk_pixbuf_get_width(src)) && (height == gdk_pixbuf_get_height(src)))
1531
464
  {
@@ -1540,7 +473,7 @@ module PixbufUtils
1540
473
  g_object_set_data_full(G_OBJECT(src), "pixbuf_utils_scaled", tmp, g_object_unref);
1541
474
  }
1542
475
  g_return_val_if_fail(tmp != NULL, Qfalse);
1543
-
476
+
1544
477
  gc = gdk_gc_new(drawable);
1545
478
  gdk_gc_set_clip_rectangle(GDK_GC(gc), clip_area);
1546
479
 
@@ -1557,9 +490,9 @@ module PixbufUtils
1557
490
  /* gint x_dither */ 0,
1558
491
  /* gint y_dither */ 0);
1559
492
  g_object_unref(gc);
1560
-
493
+
1561
494
  return Qtrue;
1562
-
495
+
1563
496
  end
1564
497
  end
1565
498