rev |
line source |
nuclear@12
|
1 /*
|
nuclear@12
|
2 eqemu - electronic queue system emulator
|
nuclear@12
|
3 Copyright (C) 2014 John Tsiombikas <nuclear@member.fsf.org>,
|
nuclear@12
|
4 Eleni-Maria Stea <eleni@mutantstargoat.com>
|
nuclear@12
|
5
|
nuclear@12
|
6 This program is free software: you can redistribute it and/or modify
|
nuclear@12
|
7 it under the terms of the GNU General Public License as published by
|
nuclear@12
|
8 the Free Software Foundation, either version 3 of the License, or
|
nuclear@12
|
9 (at your option) any later version.
|
nuclear@12
|
10
|
nuclear@12
|
11 This program is distributed in the hope that it will be useful,
|
nuclear@12
|
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nuclear@12
|
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nuclear@12
|
14 GNU General Public License for more details.
|
nuclear@12
|
15
|
nuclear@12
|
16 You should have received a copy of the GNU General Public License
|
nuclear@12
|
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
nuclear@12
|
18 */
|
nuclear@8
|
19 #include <string.h>
|
nuclear@8
|
20 #include <alloca.h>
|
nuclear@8
|
21 #include "fblur.h"
|
nuclear@8
|
22
|
nuclear@8
|
23 #if defined(__i386__) || defined(__ia64__) || defined(WIN32) || \
|
nuclear@8
|
24 (defined(__alpha__) || defined(__alpha)) || \
|
nuclear@8
|
25 defined(__arm__) || \
|
nuclear@8
|
26 (defined(__mips__) && defined(__MIPSEL__)) || \
|
nuclear@8
|
27 defined(__SYMBIAN32__) || \
|
nuclear@8
|
28 defined(__x86_64__) || \
|
nuclear@8
|
29 defined(__LITTLE_ENDIAN__)
|
nuclear@8
|
30 #define FBLUR_LITTLE_ENDIAN
|
nuclear@8
|
31 #else
|
nuclear@8
|
32 #define FBLUR_BIG_ENDIAN
|
nuclear@8
|
33 #endif
|
nuclear@8
|
34
|
nuclear@8
|
35 /* some color packing/unpacking macros */
|
nuclear@8
|
36 #ifdef FBLUR_BIG_ENDIAN
|
nuclear@8
|
37 #define RSHIFT 24
|
nuclear@8
|
38 #define GSHIFT 16
|
nuclear@8
|
39 #define BSHIFT 8
|
nuclear@8
|
40 #else /* little endian */
|
nuclear@8
|
41 #define RSHIFT 0
|
nuclear@8
|
42 #define GSHIFT 8
|
nuclear@8
|
43 #define BSHIFT 16
|
nuclear@8
|
44 #endif
|
nuclear@8
|
45
|
nuclear@8
|
46 #define RED(p) (((p) >> RSHIFT) & 0xff)
|
nuclear@8
|
47 #define GREEN(p) (((p) >> GSHIFT) & 0xff)
|
nuclear@8
|
48 #define BLUE(p) (((p) >> BSHIFT) & 0xff)
|
nuclear@8
|
49 #define RGB(r, g, b) \
|
nuclear@8
|
50 ((((r) & 0xff) << RSHIFT) | \
|
nuclear@8
|
51 (((g) & 0xff) << GSHIFT) | \
|
nuclear@8
|
52 (((b) & 0xff) << BSHIFT))
|
nuclear@8
|
53
|
nuclear@8
|
54 #define MIN(a, b) ((a) < (b) ? (a) : (b))
|
nuclear@8
|
55 #define MAX(a, b) ((a) > (b) ? (a) : (b))
|
nuclear@8
|
56
|
nuclear@8
|
57
|
nuclear@8
|
58 void fast_blur(int dir, int amount, uint32_t *buf, int x, int y)
|
nuclear@8
|
59 {
|
nuclear@8
|
60 int i, j, half;
|
nuclear@8
|
61 uint32_t *dptr, *sptr, *tmp_buf;
|
nuclear@8
|
62
|
nuclear@8
|
63 int blur_len = dir == BLUR_HORIZ ? x : y;
|
nuclear@8
|
64 int blur_times = dir == BLUR_HORIZ ? y : x;
|
nuclear@8
|
65
|
nuclear@8
|
66 if(amount <= 1) return;
|
nuclear@8
|
67
|
nuclear@8
|
68 dptr = buf;
|
nuclear@8
|
69 half = amount / 2;
|
nuclear@8
|
70
|
nuclear@8
|
71 tmp_buf = (uint32_t*)alloca(blur_len * sizeof(uint32_t));
|
nuclear@8
|
72
|
nuclear@8
|
73 for(i=0; i<blur_times; i++) {
|
nuclear@8
|
74 int ar = 0, ag = 0, ab = 0;
|
nuclear@8
|
75 int divisor = 0;
|
nuclear@8
|
76
|
nuclear@8
|
77 if(dir == BLUR_HORIZ) {
|
nuclear@8
|
78 sptr = tmp_buf;
|
nuclear@8
|
79 memcpy(sptr, dptr, x * sizeof(uint32_t));
|
nuclear@8
|
80 } else {
|
nuclear@8
|
81 dptr = buf + i;
|
nuclear@8
|
82
|
nuclear@8
|
83 sptr = tmp_buf;
|
nuclear@8
|
84 for(j=0; j<y; j++) {
|
nuclear@8
|
85 *sptr++ = *dptr;
|
nuclear@8
|
86 dptr += x;
|
nuclear@8
|
87 }
|
nuclear@8
|
88 dptr = buf + i;
|
nuclear@8
|
89 sptr = tmp_buf;
|
nuclear@8
|
90 }
|
nuclear@8
|
91
|
nuclear@8
|
92
|
nuclear@8
|
93 for(j=0; j<half; j++) {
|
nuclear@8
|
94 uint32_t pixel = tmp_buf[j];
|
nuclear@8
|
95 ar += RED(pixel);
|
nuclear@8
|
96 ag += GREEN(pixel);
|
nuclear@8
|
97 ab += BLUE(pixel);
|
nuclear@8
|
98 divisor++;
|
nuclear@8
|
99 }
|
nuclear@8
|
100
|
nuclear@8
|
101 for(j=0; j<blur_len; j++) {
|
nuclear@8
|
102 int r, g, b;
|
nuclear@8
|
103
|
nuclear@8
|
104 if(j > half) {
|
nuclear@8
|
105 uint32_t out = *(sptr - half - 1);
|
nuclear@8
|
106 ar -= RED(out);
|
nuclear@8
|
107 ag -= GREEN(out);
|
nuclear@8
|
108 ab -= BLUE(out);
|
nuclear@8
|
109 divisor--;
|
nuclear@8
|
110 }
|
nuclear@8
|
111
|
nuclear@8
|
112 if(j < blur_len - half) {
|
nuclear@8
|
113 uint32_t in = *(sptr + half);
|
nuclear@8
|
114 ar += RED(in);
|
nuclear@8
|
115 ag += GREEN(in);
|
nuclear@8
|
116 ab += BLUE(in);
|
nuclear@8
|
117 divisor++;
|
nuclear@8
|
118 }
|
nuclear@8
|
119
|
nuclear@8
|
120 r = ar / divisor;
|
nuclear@8
|
121 g = ag / divisor;
|
nuclear@8
|
122 b = ab / divisor;
|
nuclear@8
|
123
|
nuclear@8
|
124 r = MAX(MIN(r, 255), 0);
|
nuclear@8
|
125 g = MAX(MIN(g, 255), 0);
|
nuclear@8
|
126 b = MAX(MIN(b, 255), 0);
|
nuclear@8
|
127
|
nuclear@8
|
128 *dptr = RGB(r, g, b);
|
nuclear@8
|
129 dptr += dir == BLUR_HORIZ ? 1 : x;
|
nuclear@8
|
130 sptr++;
|
nuclear@8
|
131 }
|
nuclear@8
|
132
|
nuclear@8
|
133 }
|
nuclear@8
|
134
|
nuclear@8
|
135 if(dir == BLUR_BOTH) {
|
nuclear@8
|
136 fast_blur(BLUR_HORIZ, amount, buf, x, y);
|
nuclear@8
|
137 }
|
nuclear@8
|
138 }
|