Browse Source

* blur.c: use the template system for the boxblur functions.

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2801 92316355-f0b4-4df1-b90c-862c8a59935f
remotes/tiles
sam 16 years ago
parent
commit
916f579194
1 changed files with 44 additions and 38 deletions
  1. +44
    -38
      pipi/filter/blur.c

+ 44
- 38
pipi/filter/blur.c View File

@@ -27,6 +27,11 @@
#include "pipi.h" #include "pipi.h"
#include "pipi_internals.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 /* 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 * 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. */ * 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); 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) 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_image_t *dst;
pipi_pixels_t *srcp, *dstp; pipi_pixels_t *srcp, *dstp;
float *srcdata, *dstdata; float *srcdata, *dstdata;
double *acc; double *acc;
int x, y, w, h, i, j, size, gray;
int x, y, w, h, i, j, size;


w = src->w; w = src->w;
h = src->h; h = src->h;
size = (2 * m + 1) * (2 * n + 1); 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; srcdata = (float *)srcp->pixels;


dst = pipi_new(w, h); 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; 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 */ /* Step 1: fill the accumulator */
for(x = 0; x < w; x++) 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)]; r += srcdata[4 * (j2 * w + x)];
g += srcdata[4 * (j2 * w + x) + 1]; g += srcdata[4 * (j2 * w + x) + 1];
b += srcdata[4 * (j2 * w + x) + 2]; b += srcdata[4 * (j2 * w + x) + 2];
a += srcdata[4 * (j2 * w + x) + 3]; a += srcdata[4 * (j2 * w + x) + 3];
} }
}


if(FLAG_GRAY)
acc[x] = t;
else
{
acc[4 * x] = r; acc[4 * x] = r;
acc[4 * x + 1] = g; acc[4 * x + 1] = g;
acc[4 * x + 2] = b; 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.; double t = 0.;


/* 2.1: compute the first pixel */ /* 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]; 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]; r += acc[4 * i2];
g += acc[4 * i2 + 1]; g += acc[4 * i2 + 1];
b += acc[4 * i2 + 2]; 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; int u, u2, v, v2;


if(gray)
if(FLAG_GRAY)
{ {
dstdata[y * w + x] = t / size; 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; u2 = (u < 0) ? w - 1 - ((-u - 1) % w) : u % w;
v = x + m + 1; v = x + m + 1;
v2 = (v < 0) ? w - 1 - ((-v - 1) % w) : v % w; v2 = (v < 0) ? w - 1 - ((-v - 1) % w) : v % w;
if(gray)
if(FLAG_GRAY)
{ {
t = t - acc[u2] + acc[v2]; 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; u2 = (u < 0) ? w - 1 - ((-u - 1) % w) : u % w;
v = y + n + 1; v = y + n + 1;
v2 = (v < 0) ? w - 1 - ((-v - 1) % w) : v % w; 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]; 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; return dst;
} }


#endif


Loading…
Cancel
Save