eqemu

view src/fblur.cc @ 10:819c7ebb1bec

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