|
|
@@ -27,6 +27,11 @@ |
|
|
|
#include "pipi.h" |
|
|
|
#include "pipi_internals.h" |
|
|
|
|
|
|
|
#if !defined TEMPLATE_FILE /* This file uses the template system */ |
|
|
|
#define TEMPLATE_FLAGS SET_FLAG_GRAY |
|
|
|
#define TEMPLATE_FILE "filter/blur.c" |
|
|
|
#include "pipi_template.h" |
|
|
|
|
|
|
|
/* Any standard deviation below this value will be rounded up, in order |
|
|
|
* to avoid ridiculously low values. exp(-1/(2*0.2*0.2)) is < 10^-5 so |
|
|
|
* there is little chance that any value below 0.2 will be useful. */ |
|
|
@@ -124,60 +129,64 @@ pipi_image_t *pipi_box_blur(pipi_image_t *src, int size) |
|
|
|
return pipi_box_blur_ext(src, size, size); |
|
|
|
} |
|
|
|
|
|
|
|
/* FIXME: split this into templates for wrap-around and proper gray support */ |
|
|
|
pipi_image_t *pipi_box_blur_ext(pipi_image_t *src, int m, int n) |
|
|
|
{ |
|
|
|
if(src->last_modified == PIPI_PIXELS_Y_F) |
|
|
|
return boxblur_gray(src, m, n); |
|
|
|
|
|
|
|
return boxblur(src, m, n); |
|
|
|
} |
|
|
|
|
|
|
|
#else /* XXX: the following functions use the template system */ |
|
|
|
|
|
|
|
/* FIXME: FLAG_WRAP */ |
|
|
|
static pipi_image_t *SUFFIX(boxblur)(pipi_image_t *src, int m, int n) |
|
|
|
{ |
|
|
|
pipi_image_t *dst; |
|
|
|
pipi_pixels_t *srcp, *dstp; |
|
|
|
float *srcdata, *dstdata; |
|
|
|
double *acc; |
|
|
|
int x, y, w, h, i, j, size, gray; |
|
|
|
int x, y, w, h, i, j, size; |
|
|
|
|
|
|
|
w = src->w; |
|
|
|
h = src->h; |
|
|
|
size = (2 * m + 1) * (2 * n + 1); |
|
|
|
|
|
|
|
gray = (src->last_modified == PIPI_PIXELS_Y_F); |
|
|
|
|
|
|
|
srcp = gray ? pipi_getpixels(src, PIPI_PIXELS_Y_F) |
|
|
|
: pipi_getpixels(src, PIPI_PIXELS_RGBA_F); |
|
|
|
srcp = FLAG_GRAY ? pipi_getpixels(src, PIPI_PIXELS_Y_F) |
|
|
|
: pipi_getpixels(src, PIPI_PIXELS_RGBA_F); |
|
|
|
srcdata = (float *)srcp->pixels; |
|
|
|
|
|
|
|
dst = pipi_new(w, h); |
|
|
|
dstp = gray ? pipi_getpixels(dst, PIPI_PIXELS_Y_F) |
|
|
|
: pipi_getpixels(dst, PIPI_PIXELS_RGBA_F); |
|
|
|
dstp = FLAG_GRAY ? pipi_getpixels(dst, PIPI_PIXELS_Y_F) |
|
|
|
: pipi_getpixels(dst, PIPI_PIXELS_RGBA_F); |
|
|
|
dstdata = (float *)dstp->pixels; |
|
|
|
|
|
|
|
acc = malloc(w * (gray ? 1 : 4) * sizeof(double)); |
|
|
|
acc = malloc(w * (FLAG_GRAY ? 1 : 4) * sizeof(double)); |
|
|
|
|
|
|
|
/* Step 1: fill the accumulator */ |
|
|
|
for(x = 0; x < w; x++) |
|
|
|
{ |
|
|
|
if(gray) |
|
|
|
{ |
|
|
|
double t = 0.; |
|
|
|
|
|
|
|
for(j = -n; j <= n; j++) |
|
|
|
{ |
|
|
|
int j2 = (j < 0) ? h - 1 - ((-j - 1) % h) : j % h; |
|
|
|
t += srcdata[j2 * w + x]; |
|
|
|
} |
|
|
|
double r = 0., g = 0., b = 0., a = 0.; |
|
|
|
double t = 0.; |
|
|
|
|
|
|
|
acc[x] = t; |
|
|
|
} |
|
|
|
else |
|
|
|
for(j = -n; j <= n; j++) |
|
|
|
{ |
|
|
|
double r = 0., g = 0., b = 0., a = 0.; |
|
|
|
|
|
|
|
for(j = -n; j <= n; j++) |
|
|
|
int j2 = (j < 0) ? h - 1 - ((-j - 1) % h) : j % h; |
|
|
|
if(FLAG_GRAY) |
|
|
|
t += srcdata[j2 * w + x]; |
|
|
|
else |
|
|
|
{ |
|
|
|
int j2 = (j < 0) ? h - 1 - ((-j - 1) % h) : j % h; |
|
|
|
r += srcdata[4 * (j2 * w + x)]; |
|
|
|
g += srcdata[4 * (j2 * w + x) + 1]; |
|
|
|
b += srcdata[4 * (j2 * w + x) + 2]; |
|
|
|
a += srcdata[4 * (j2 * w + x) + 3]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if(FLAG_GRAY) |
|
|
|
acc[x] = t; |
|
|
|
else |
|
|
|
{ |
|
|
|
acc[4 * x] = r; |
|
|
|
acc[4 * x + 1] = g; |
|
|
|
acc[4 * x + 2] = b; |
|
|
@@ -192,19 +201,14 @@ pipi_image_t *pipi_box_blur_ext(pipi_image_t *src, int m, int n) |
|
|
|
double t = 0.; |
|
|
|
|
|
|
|
/* 2.1: compute the first pixel */ |
|
|
|
if(gray) |
|
|
|
for(i = -m; i <= m; i++) |
|
|
|
{ |
|
|
|
for(i = -m; i <= m; i++) |
|
|
|
{ |
|
|
|
int i2 = (i < 0) ? w - 1 - ((-i - 1) % w) : i % w; |
|
|
|
int i2 = (i < 0) ? w - 1 - ((-i - 1) % w) : i % w; |
|
|
|
|
|
|
|
if(FLAG_GRAY) |
|
|
|
t += acc[i2]; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
for(i = -m; i <= m; i++) |
|
|
|
else |
|
|
|
{ |
|
|
|
int i2 = (i < 0) ? w - 1 - ((-i - 1) % w) : i % w; |
|
|
|
r += acc[4 * i2]; |
|
|
|
g += acc[4 * i2 + 1]; |
|
|
|
b += acc[4 * i2 + 2]; |
|
|
@@ -217,7 +221,7 @@ pipi_image_t *pipi_box_blur_ext(pipi_image_t *src, int m, int n) |
|
|
|
{ |
|
|
|
int u, u2, v, v2; |
|
|
|
|
|
|
|
if(gray) |
|
|
|
if(FLAG_GRAY) |
|
|
|
{ |
|
|
|
dstdata[y * w + x] = t / size; |
|
|
|
} |
|
|
@@ -233,7 +237,7 @@ pipi_image_t *pipi_box_blur_ext(pipi_image_t *src, int m, int n) |
|
|
|
u2 = (u < 0) ? w - 1 - ((-u - 1) % w) : u % w; |
|
|
|
v = x + m + 1; |
|
|
|
v2 = (v < 0) ? w - 1 - ((-v - 1) % w) : v % w; |
|
|
|
if(gray) |
|
|
|
if(FLAG_GRAY) |
|
|
|
{ |
|
|
|
t = t - acc[u2] + acc[v2]; |
|
|
|
} |
|
|
@@ -255,7 +259,7 @@ pipi_image_t *pipi_box_blur_ext(pipi_image_t *src, int m, int n) |
|
|
|
u2 = (u < 0) ? w - 1 - ((-u - 1) % w) : u % w; |
|
|
|
v = y + n + 1; |
|
|
|
v2 = (v < 0) ? w - 1 - ((-v - 1) % w) : v % w; |
|
|
|
if(gray) |
|
|
|
if(FLAG_GRAY) |
|
|
|
{ |
|
|
|
acc[x] += srcdata[v2 * w + x] - srcdata[u2 * w + x]; |
|
|
|
} |
|
|
@@ -277,3 +281,5 @@ pipi_image_t *pipi_box_blur_ext(pipi_image_t *src, int m, int n) |
|
|
|
return dst; |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
|