eqemu

annotate 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
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 }