* 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-862c8a59935fremotes/tiles
@@ -131,6 +131,12 @@ int pipi_command(pipi_context_t *ctx, char const *cmd, ...) | |||||
pipi_free(src); | pipi_free(src); | ||||
ctx->images[ctx->nimages - 1] = dst; | 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")) | else if(!strcmp(cmd, "gray")) | ||||
{ | { | ||||
if(ctx->nimages <= 0) | if(ctx->nimages <= 0) | ||||
@@ -27,6 +27,12 @@ | |||||
#include "pipi.h" | #include "pipi.h" | ||||
#include "pipi_internals.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, | static pipi_image_t *conv_std_rgba_f(pipi_image_t *src, | ||||
int m, int n, double mat[]); | int m, int n, double mat[]); | ||||
static pipi_image_t *conv_sep_rgba_f(pipi_image_t *src, | 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 FUNC1 | ||||
#undef FUNC2 | #undef FUNC2 | ||||
#undef PIXEL | #undef PIXEL | ||||
#undef GRAY | |||||
#undef FLAGS | |||||
#define FUNC1 conv_std_rgba_f | #define FUNC1 conv_std_rgba_f | ||||
#define FUNC2 conv_sep_rgba_f | #define FUNC2 conv_sep_rgba_f | ||||
#define PIXEL float | #define PIXEL float | ||||
#define GRAY 0 | |||||
#define FLAGS 0 | |||||
#include "convolution_template.h" | #include "convolution_template.h" | ||||
static pipi_image_t *conv_std_y_f(pipi_image_t *src, | 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 FUNC1 | ||||
#undef FUNC2 | #undef FUNC2 | ||||
#undef PIXEL | #undef PIXEL | ||||
#undef GRAY | |||||
#undef FLAGS | |||||
#define FUNC1 conv_std_y_f | #define FUNC1 conv_std_y_f | ||||
#define FUNC2 conv_sep_y_f | #define FUNC2 conv_sep_y_f | ||||
#define PIXEL float | #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" | #include "convolution_template.h" | ||||
pipi_image_t *pipi_convolution(pipi_image_t *src, int m, int n, double mat[]) | 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(fabs(p - q) > 0.0001 * 0.0001) | ||||
{ | { | ||||
if(src->last_modified == PIPI_PIXELS_Y_F) | 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); | return conv_std_y_f(src, m, n, mat); | ||||
} | |||||
else | else | ||||
{ | |||||
if(src->wrap) | |||||
return wrap_std_rgba_f(src, m, n, mat); | |||||
return conv_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; | vvec[j] = mat[j * m + besti] / tmp; | ||||
if(src->last_modified == PIPI_PIXELS_Y_F) | 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 | 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(hvec); | ||||
free(vvec); | free(vvec); | ||||
@@ -18,7 +18,8 @@ | |||||
* FUNC1 standard function name | * FUNC1 standard function name | ||||
* FUNC2 separable function name | * FUNC2 separable function name | ||||
* PIXEL pixel type | * 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[]) | 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; | w = src->w; | ||||
h = src->h; | 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; | srcdata = (PIXEL *)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 = (PIXEL *)dstp->pixels; | dstdata = (PIXEL *)dstp->pixels; | ||||
for(y = 0; y < h; y++) | for(y = 0; y < h; y++) | ||||
{ | { | ||||
for(x = 0; x < w; x++) | for(x = 0; x < w; x++) | ||||
{ | { | ||||
if(GRAY) | |||||
if(FLAG_GRAY) | |||||
{ | { | ||||
double Y = 0.; | double Y = 0.; | ||||
int x2, y2; | 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++) | for(j = 0; j < n; j++) | ||||
{ | { | ||||
y2 = y + j - n / 2; | 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++) | for(i = 0; i < m; i++) | ||||
{ | { | ||||
x2 = x + i - m / 2; | 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]; | 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++) | for(j = 0; j < n; j++) | ||||
{ | { | ||||
y2 = y + j - n / 2; | 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++) | for(i = 0; i < m; i++) | ||||
{ | { | ||||
double f = mat[j * m + i]; | double f = mat[j * m + i]; | ||||
x2 = x + i - m / 2; | 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]; | R += f * srcdata[(y2 * w + x2) * 4]; | ||||
G += f * srcdata[(y2 * w + x2) * 4 + 1]; | G += f * srcdata[(y2 * w + x2) * 4 + 1]; | ||||
@@ -114,22 +115,22 @@ static pipi_image_t *FUNC2(pipi_image_t *src, | |||||
w = src->w; | w = src->w; | ||||
h = src->h; | 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; | srcdata = (PIXEL *)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 = (PIXEL *)dstp->pixels; | 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(y = 0; y < h; y++) | ||||
{ | { | ||||
for(x = 0; x < w; x++) | for(x = 0; x < w; x++) | ||||
{ | { | ||||
if(GRAY) | |||||
if(FLAG_GRAY) | |||||
{ | { | ||||
double Y = 0.; | double Y = 0.; | ||||
int x2; | int x2; | ||||
@@ -137,8 +138,8 @@ static pipi_image_t *FUNC2(pipi_image_t *src, | |||||
for(i = 0; i < m; i++) | for(i = 0; i < m; i++) | ||||
{ | { | ||||
x2 = x + i - m / 2; | 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]; | Y += hvec[i] * srcdata[y * w + x2]; | ||||
} | } | ||||
@@ -155,8 +156,8 @@ static pipi_image_t *FUNC2(pipi_image_t *src, | |||||
double f = hvec[i]; | double f = hvec[i]; | ||||
x2 = x + i - m / 2; | 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]; | R += f * srcdata[(y * w + x2) * 4]; | ||||
G += f * srcdata[(y * w + x2) * 4 + 1]; | 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++) | for(x = 0; x < w; x++) | ||||
{ | { | ||||
if(GRAY) | |||||
if(FLAG_GRAY) | |||||
{ | { | ||||
double Y = 0.; | double Y = 0.; | ||||
int y2; | int y2; | ||||
@@ -182,8 +183,8 @@ static pipi_image_t *FUNC2(pipi_image_t *src, | |||||
for(j = 0; j < n; j++) | for(j = 0; j < n; j++) | ||||
{ | { | ||||
y2 = y + j - n / 2; | 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]; | Y += vvec[j] * buffer[y2 * w + x]; | ||||
} | } | ||||
@@ -200,8 +201,8 @@ static pipi_image_t *FUNC2(pipi_image_t *src, | |||||
double f = vvec[j]; | double f = vvec[j]; | ||||
y2 = y + j - n / 2; | 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]; | R += f * buffer[(y2 * w + x) * 4]; | ||||
G += f * buffer[(y2 * w + x) * 4 + 1]; | G += f * buffer[(y2 * w + x) * 4 + 1]; | ||||
@@ -57,6 +57,10 @@ pipi_image_t *pipi_copy(pipi_image_t *src) | |||||
{ | { | ||||
pipi_image_t *dst = pipi_new(src->w, src->h); | 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) | if(src->last_modified != PIPI_PIXELS_UNINITIALISED) | ||||
{ | { | ||||
pipi_pixels_t *srcp, *dstp; | pipi_pixels_t *srcp, *dstp; | ||||
@@ -25,6 +25,7 @@ | |||||
struct pipi_image | struct pipi_image | ||||
{ | { | ||||
int w, h, pitch; | int w, h, pitch; | ||||
int wrap; | |||||
pipi_format_t codec_format, last_modified; | pipi_format_t codec_format, last_modified; | ||||
/* List of all possible pixel formats */ | /* List of all possible pixel formats */ | ||||
@@ -41,6 +41,11 @@ int main(int argc, char *argv[]) | |||||
if(pipi_command(ctx, "gray") != 0) | if(pipi_command(ctx, "gray") != 0) | ||||
return EXIT_FAILURE; | 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")) | else if(!strcmp(argv[0], "--output") || !strcmp(argv[0], "-o")) | ||||
{ | { | ||||
if(argv[1] == NULL) | if(argv[1] == NULL) | ||||