eqemu

view src/fblur.cc @ 12:2656099aff12

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