rev |
line source |
nuclear@8
|
1 #include <string.h>
|
nuclear@8
|
2 #include <alloca.h>
|
nuclear@8
|
3 #include "fblur.h"
|
nuclear@8
|
4
|
nuclear@8
|
5 #if defined(__i386__) || defined(__ia64__) || defined(WIN32) || \
|
nuclear@8
|
6 (defined(__alpha__) || defined(__alpha)) || \
|
nuclear@8
|
7 defined(__arm__) || \
|
nuclear@8
|
8 (defined(__mips__) && defined(__MIPSEL__)) || \
|
nuclear@8
|
9 defined(__SYMBIAN32__) || \
|
nuclear@8
|
10 defined(__x86_64__) || \
|
nuclear@8
|
11 defined(__LITTLE_ENDIAN__)
|
nuclear@8
|
12 #define FBLUR_LITTLE_ENDIAN
|
nuclear@8
|
13 #else
|
nuclear@8
|
14 #define FBLUR_BIG_ENDIAN
|
nuclear@8
|
15 #endif
|
nuclear@8
|
16
|
nuclear@8
|
17 /* some color packing/unpacking macros */
|
nuclear@8
|
18 #ifdef FBLUR_BIG_ENDIAN
|
nuclear@8
|
19 #define RSHIFT 24
|
nuclear@8
|
20 #define GSHIFT 16
|
nuclear@8
|
21 #define BSHIFT 8
|
nuclear@8
|
22 #else /* little endian */
|
nuclear@8
|
23 #define RSHIFT 0
|
nuclear@8
|
24 #define GSHIFT 8
|
nuclear@8
|
25 #define BSHIFT 16
|
nuclear@8
|
26 #endif
|
nuclear@8
|
27
|
nuclear@8
|
28 #define RED(p) (((p) >> RSHIFT) & 0xff)
|
nuclear@8
|
29 #define GREEN(p) (((p) >> GSHIFT) & 0xff)
|
nuclear@8
|
30 #define BLUE(p) (((p) >> BSHIFT) & 0xff)
|
nuclear@8
|
31 #define RGB(r, g, b) \
|
nuclear@8
|
32 ((((r) & 0xff) << RSHIFT) | \
|
nuclear@8
|
33 (((g) & 0xff) << GSHIFT) | \
|
nuclear@8
|
34 (((b) & 0xff) << BSHIFT))
|
nuclear@8
|
35
|
nuclear@8
|
36 #define MIN(a, b) ((a) < (b) ? (a) : (b))
|
nuclear@8
|
37 #define MAX(a, b) ((a) > (b) ? (a) : (b))
|
nuclear@8
|
38
|
nuclear@8
|
39
|
nuclear@8
|
40 void fast_blur(int dir, int amount, uint32_t *buf, int x, int y)
|
nuclear@8
|
41 {
|
nuclear@8
|
42 int i, j, half;
|
nuclear@8
|
43 uint32_t *dptr, *sptr, *tmp_buf;
|
nuclear@8
|
44
|
nuclear@8
|
45 int blur_len = dir == BLUR_HORIZ ? x : y;
|
nuclear@8
|
46 int blur_times = dir == BLUR_HORIZ ? y : x;
|
nuclear@8
|
47
|
nuclear@8
|
48 if(amount <= 1) return;
|
nuclear@8
|
49
|
nuclear@8
|
50 dptr = buf;
|
nuclear@8
|
51 half = amount / 2;
|
nuclear@8
|
52
|
nuclear@8
|
53 tmp_buf = (uint32_t*)alloca(blur_len * sizeof(uint32_t));
|
nuclear@8
|
54
|
nuclear@8
|
55 for(i=0; i<blur_times; i++) {
|
nuclear@8
|
56 int ar = 0, ag = 0, ab = 0;
|
nuclear@8
|
57 int divisor = 0;
|
nuclear@8
|
58
|
nuclear@8
|
59 if(dir == BLUR_HORIZ) {
|
nuclear@8
|
60 sptr = tmp_buf;
|
nuclear@8
|
61 memcpy(sptr, dptr, x * sizeof(uint32_t));
|
nuclear@8
|
62 } else {
|
nuclear@8
|
63 dptr = buf + i;
|
nuclear@8
|
64
|
nuclear@8
|
65 sptr = tmp_buf;
|
nuclear@8
|
66 for(j=0; j<y; j++) {
|
nuclear@8
|
67 *sptr++ = *dptr;
|
nuclear@8
|
68 dptr += x;
|
nuclear@8
|
69 }
|
nuclear@8
|
70 dptr = buf + i;
|
nuclear@8
|
71 sptr = tmp_buf;
|
nuclear@8
|
72 }
|
nuclear@8
|
73
|
nuclear@8
|
74
|
nuclear@8
|
75 for(j=0; j<half; j++) {
|
nuclear@8
|
76 uint32_t pixel = tmp_buf[j];
|
nuclear@8
|
77 ar += RED(pixel);
|
nuclear@8
|
78 ag += GREEN(pixel);
|
nuclear@8
|
79 ab += BLUE(pixel);
|
nuclear@8
|
80 divisor++;
|
nuclear@8
|
81 }
|
nuclear@8
|
82
|
nuclear@8
|
83 for(j=0; j<blur_len; j++) {
|
nuclear@8
|
84 int r, g, b;
|
nuclear@8
|
85
|
nuclear@8
|
86 if(j > half) {
|
nuclear@8
|
87 uint32_t out = *(sptr - half - 1);
|
nuclear@8
|
88 ar -= RED(out);
|
nuclear@8
|
89 ag -= GREEN(out);
|
nuclear@8
|
90 ab -= BLUE(out);
|
nuclear@8
|
91 divisor--;
|
nuclear@8
|
92 }
|
nuclear@8
|
93
|
nuclear@8
|
94 if(j < blur_len - half) {
|
nuclear@8
|
95 uint32_t in = *(sptr + half);
|
nuclear@8
|
96 ar += RED(in);
|
nuclear@8
|
97 ag += GREEN(in);
|
nuclear@8
|
98 ab += BLUE(in);
|
nuclear@8
|
99 divisor++;
|
nuclear@8
|
100 }
|
nuclear@8
|
101
|
nuclear@8
|
102 r = ar / divisor;
|
nuclear@8
|
103 g = ag / divisor;
|
nuclear@8
|
104 b = ab / divisor;
|
nuclear@8
|
105
|
nuclear@8
|
106 r = MAX(MIN(r, 255), 0);
|
nuclear@8
|
107 g = MAX(MIN(g, 255), 0);
|
nuclear@8
|
108 b = MAX(MIN(b, 255), 0);
|
nuclear@8
|
109
|
nuclear@8
|
110 *dptr = RGB(r, g, b);
|
nuclear@8
|
111 dptr += dir == BLUR_HORIZ ? 1 : x;
|
nuclear@8
|
112 sptr++;
|
nuclear@8
|
113 }
|
nuclear@8
|
114
|
nuclear@8
|
115 }
|
nuclear@8
|
116
|
nuclear@8
|
117 if(dir == BLUR_BOTH) {
|
nuclear@8
|
118 fast_blur(BLUR_HORIZ, amount, buf, x, y);
|
nuclear@8
|
119 }
|
nuclear@8
|
120 }
|