eqemu

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