Procházet zdrojové kódy

* convolution.c: support for wrap-around in convolutions.

* pipi.c: add the "--wrap" flag to tell libpipi that a given image wraps
    around.

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2703 92316355-f0b4-4df1-b90c-862c8a59935f
remotes/tiles
sam před 16 roky
rodič
revize
7f3e08d021
6 změnil soubory, kde provedl 98 přidání a 35 odebrání
  1. +6
    -0
      pipi/context.c
  2. +52
    -6
      pipi/filter/convolution.c
  3. +30
    -29
      pipi/filter/convolution_template.h
  4. +4
    -0
      pipi/pipi.c
  5. +1
    -0
      pipi/pipi_internals.h
  6. +5
    -0
      src/pipi.c

+ 6
- 0
pipi/context.c Zobrazit soubor

@@ -131,6 +131,12 @@ int pipi_command(pipi_context_t *ctx, char const *cmd, ...)
pipi_free(src);
ctx->images[ctx->nimages - 1] = dst;
}
else if(!strcmp(cmd, "wrap"))
{
if(ctx->nimages <= 0)
return -1;
ctx->images[ctx->nimages - 1]->wrap = 1;
}
else if(!strcmp(cmd, "gray"))
{
if(ctx->nimages <= 0)


+ 52
- 6
pipi/filter/convolution.c Zobrazit soubor

@@ -27,6 +27,12 @@
#include "pipi.h"
#include "pipi_internals.h"

#define FLAG_GRAY ((FLAGS) & SET_FLAG_GRAY)
#define FLAG_WRAP ((FLAGS) & SET_FLAG_WRAP)

#define SET_FLAG_GRAY 0x01
#define SET_FLAG_WRAP 0x02

static pipi_image_t *conv_std_rgba_f(pipi_image_t *src,
int m, int n, double mat[]);
static pipi_image_t *conv_sep_rgba_f(pipi_image_t *src,
@@ -35,11 +41,11 @@ static pipi_image_t *conv_sep_rgba_f(pipi_image_t *src,
#undef FUNC1
#undef FUNC2
#undef PIXEL
#undef GRAY
#undef FLAGS
#define FUNC1 conv_std_rgba_f
#define FUNC2 conv_sep_rgba_f
#define PIXEL float
#define GRAY 0
#define FLAGS 0
#include "convolution_template.h"

static pipi_image_t *conv_std_y_f(pipi_image_t *src,
@@ -50,11 +56,41 @@ static pipi_image_t *conv_sep_y_f(pipi_image_t *src,
#undef FUNC1
#undef FUNC2
#undef PIXEL
#undef GRAY
#undef FLAGS
#define FUNC1 conv_std_y_f
#define FUNC2 conv_sep_y_f
#define PIXEL float
#define GRAY 1
#define FLAGS SET_FLAG_GRAY
#include "convolution_template.h"

static pipi_image_t *wrap_std_rgba_f(pipi_image_t *src,
int m, int n, double mat[]);
static pipi_image_t *wrap_sep_rgba_f(pipi_image_t *src,
int m, double hvec[],
int n, double vvec[]);
#undef FUNC1
#undef FUNC2
#undef PIXEL
#undef FLAGS
#define FUNC1 wrap_std_rgba_f
#define FUNC2 wrap_sep_rgba_f
#define PIXEL float
#define FLAGS SET_FLAG_WRAP
#include "convolution_template.h"

static pipi_image_t *wrap_std_y_f(pipi_image_t *src,
int m, int n, double mat[]);
static pipi_image_t *wrap_sep_y_f(pipi_image_t *src,
int m, double hvec[],
int n, double vvec[]);
#undef FUNC1
#undef FUNC2
#undef PIXEL
#undef FLAGS
#define FUNC1 wrap_std_y_f
#define FUNC2 wrap_sep_y_f
#define PIXEL float
#define FLAGS SET_FLAG_GRAY|SET_FLAG_WRAP
#include "convolution_template.h"

pipi_image_t *pipi_convolution(pipi_image_t *src, int m, int n, double mat[])
@@ -97,9 +133,17 @@ pipi_image_t *pipi_convolution(pipi_image_t *src, int m, int n, double mat[])
if(fabs(p - q) > 0.0001 * 0.0001)
{
if(src->last_modified == PIPI_PIXELS_Y_F)
{
if(src->wrap)
return wrap_std_y_f(src, m, n, mat);
return conv_std_y_f(src, m, n, mat);
}
else
{
if(src->wrap)
return wrap_std_rgba_f(src, m, n, mat);
return conv_std_rgba_f(src, m, n, mat);
}
}
}
}
@@ -115,9 +159,11 @@ pipi_image_t *pipi_convolution(pipi_image_t *src, int m, int n, double mat[])
vvec[j] = mat[j * m + besti] / tmp;

if(src->last_modified == PIPI_PIXELS_Y_F)
ret = conv_sep_y_f(src, m, hvec, n, vvec);
ret = src->wrap ? wrap_sep_y_f(src, m, hvec, n, vvec)
: conv_sep_y_f(src, m, hvec, n, vvec);
else
ret = conv_sep_rgba_f(src, m, hvec, n, vvec);
ret = src->wrap ? wrap_sep_rgba_f(src, m, hvec, n, vvec)
: conv_sep_rgba_f(src, m, hvec, n, vvec);

free(hvec);
free(vvec);


+ 30
- 29
pipi/filter/convolution_template.h Zobrazit soubor

@@ -18,7 +18,8 @@
* FUNC1 standard function name
* FUNC2 separable function name
* PIXEL pixel type
* GRAY 1 (grayscale) or 0 (classic RGBA)
* FLAGS 1 (grayscale)
* 2 (loop)
*/

static pipi_image_t *FUNC1(pipi_image_t *src, int m, int n, double mat[])
@@ -31,20 +32,20 @@ static pipi_image_t *FUNC1(pipi_image_t *src, int m, int n, double mat[])
w = src->w;
h = src->h;

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 = (PIXEL *)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 = (PIXEL *)dstp->pixels;

for(y = 0; y < h; y++)
{
for(x = 0; x < w; x++)
{
if(GRAY)
if(FLAG_GRAY)
{
double Y = 0.;
int x2, y2;
@@ -52,14 +53,14 @@ static pipi_image_t *FUNC1(pipi_image_t *src, int m, int n, double mat[])
for(j = 0; j < n; j++)
{
y2 = y + j - n / 2;
if(y2 < 0) y2 = 0;
else if(y2 >= h) y2 = h - 1;
if(y2 < 0) y2 = FLAG_WRAP ? (h - 1 - (-y2 - 1) % h) : 0;
else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;

for(i = 0; i < m; i++)
{
x2 = x + i - m / 2;
if(x2 < 0) x2 = 0;
else if(x2 >= w) x2 = w - 1;
if(x2 < 0) x2 = FLAG_WRAP ? (w - 1 - (-x2 - 1) % w) : 0;
else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;

Y += mat[j * m + i] * srcdata[y2 * w + x2];
}
@@ -75,16 +76,16 @@ static pipi_image_t *FUNC1(pipi_image_t *src, int m, int n, double mat[])
for(j = 0; j < n; j++)
{
y2 = y + j - n / 2;
if(y2 < 0) y2 = 0;
else if(y2 >= h) y2 = h - 1;
if(y2 < 0) y2 = FLAG_WRAP ? (h - 1 - (-y2 - 1) % h) : 0;
else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;

for(i = 0; i < m; i++)
{
double f = mat[j * m + i];

x2 = x + i - m / 2;
if(x2 < 0) x2 = 0;
else if(x2 >= w) x2 = w - 1;
if(x2 < 0) x2 = FLAG_WRAP ? (w - 1 - (-x2 - 1) % w) : 0;
else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;

R += f * srcdata[(y2 * w + x2) * 4];
G += f * srcdata[(y2 * w + x2) * 4 + 1];
@@ -114,22 +115,22 @@ static pipi_image_t *FUNC2(pipi_image_t *src,
w = src->w;
h = src->h;

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 = (PIXEL *)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 = (PIXEL *)dstp->pixels;

buffer = malloc(w * h * (GRAY ? 1 : 4) * sizeof(double));
buffer = malloc(w * h * (FLAG_GRAY ? 1 : 4) * sizeof(double));

for(y = 0; y < h; y++)
{
for(x = 0; x < w; x++)
{
if(GRAY)
if(FLAG_GRAY)
{
double Y = 0.;
int x2;
@@ -137,8 +138,8 @@ static pipi_image_t *FUNC2(pipi_image_t *src,
for(i = 0; i < m; i++)
{
x2 = x + i - m / 2;
if(x2 < 0) x2 = 0;
else if(x2 >= w) x2 = w - 1;
if(x2 < 0) x2 = FLAG_WRAP ? (w - 1 - (-x2 - 1) % w) : 0;
else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;

Y += hvec[i] * srcdata[y * w + x2];
}
@@ -155,8 +156,8 @@ static pipi_image_t *FUNC2(pipi_image_t *src,
double f = hvec[i];

x2 = x + i - m / 2;
if(x2 < 0) x2 = 0;
else if(x2 >= w) x2 = w - 1;
if(x2 < 0) x2 = FLAG_WRAP ? (w - 1 - (-x2 - 1) % w) : 0;
else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;

R += f * srcdata[(y * w + x2) * 4];
G += f * srcdata[(y * w + x2) * 4 + 1];
@@ -174,7 +175,7 @@ static pipi_image_t *FUNC2(pipi_image_t *src,
{
for(x = 0; x < w; x++)
{
if(GRAY)
if(FLAG_GRAY)
{
double Y = 0.;
int y2;
@@ -182,8 +183,8 @@ static pipi_image_t *FUNC2(pipi_image_t *src,
for(j = 0; j < n; j++)
{
y2 = y + j - n / 2;
if(y2 < 0) y2 = 0;
else if(y2 >= h) y2 = h - 1;
if(y2 < 0) y2 = FLAG_WRAP ? (h - 1 - (-y2 - 1) % h) : 0;
else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;

Y += vvec[j] * buffer[y2 * w + x];
}
@@ -200,8 +201,8 @@ static pipi_image_t *FUNC2(pipi_image_t *src,
double f = vvec[j];

y2 = y + j - n / 2;
if(y2 < 0) y2 = 0;
else if(y2 >= h) y2 = h - 1;
if(y2 < 0) y2 = FLAG_WRAP ? (h - 1 - (-y2 - 1) % h) : 0;
else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;

R += f * buffer[(y2 * w + x) * 4];
G += f * buffer[(y2 * w + x) * 4 + 1];


+ 4
- 0
pipi/pipi.c Zobrazit soubor

@@ -57,6 +57,10 @@ pipi_image_t *pipi_copy(pipi_image_t *src)
{
pipi_image_t *dst = pipi_new(src->w, src->h);

/* Copy properties */
dst->wrap = src->wrap;

/* Copy pixels, if any */
if(src->last_modified != PIPI_PIXELS_UNINITIALISED)
{
pipi_pixels_t *srcp, *dstp;


+ 1
- 0
pipi/pipi_internals.h Zobrazit soubor

@@ -25,6 +25,7 @@
struct pipi_image
{
int w, h, pitch;
int wrap;
pipi_format_t codec_format, last_modified;

/* List of all possible pixel formats */


+ 5
- 0
src/pipi.c Zobrazit soubor

@@ -41,6 +41,11 @@ int main(int argc, char *argv[])
if(pipi_command(ctx, "gray") != 0)
return EXIT_FAILURE;
}
else if(!strcmp(argv[0], "--wrap"))
{
if(pipi_command(ctx, "wrap") != 0)
return EXIT_FAILURE;
}
else if(!strcmp(argv[0], "--output") || !strcmp(argv[0], "-o"))
{
if(argv[1] == NULL)


Načítá se…
Zrušit
Uložit