git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2793 92316355-f0b4-4df1-b90c-862c8a59935fremotes/tiles
@@ -16,6 +16,7 @@ libpipi_la_SOURCES = \ | |||||
pipi.c \ | pipi.c \ | ||||
pipi.h \ | pipi.h \ | ||||
pipi_internals.h \ | pipi_internals.h \ | ||||
pipi_template.h \ | |||||
context.c \ | context.c \ | ||||
pixels.c \ | pixels.c \ | ||||
codec.c \ | codec.c \ | ||||
@@ -61,7 +62,7 @@ combine_sources = \ | |||||
filter_sources = \ | filter_sources = \ | ||||
filter/autocontrast.c \ | filter/autocontrast.c \ | ||||
filter/blur.c \ | filter/blur.c \ | ||||
filter/convolution.c filter/convolution_template.h \ | filter/convolution.c \ | ||||
filter/color.c \ | filter/color.c \ | ||||
filter/transform.c \ | filter/transform.c \ | ||||
filter/median.c \ | filter/median.c \ | ||||
@@ -27,51 +27,10 @@ | |||||
#include "pipi.h" | #include "pipi.h" | ||||
#include "pipi_internals.h" | #include "pipi_internals.h" | ||||
#define FLAG_GRAY ((FLAGS) & SET_FLAG_GRAY) | #if !defined TEMPLATE_FILE /* This file uses the template system */ | ||||
#define FLAG_WRAP ((FLAGS) & SET_FLAG_WRAP) | #define TEMPLATE_FLAGS SET_FLAG_GRAY | SET_FLAG_WRAP | ||||
#define TEMPLATE_FILE "filter/convolution.c" | |||||
#define SET_FLAG_GRAY 0x01 | #include "pipi_template.h" | ||||
#define SET_FLAG_WRAP 0x02 | |||||
#undef FUNC1 | |||||
#undef FUNC2 | |||||
#undef PIXEL | |||||
#undef FLAGS | |||||
#define FUNC1 conv_std_rgba_f | |||||
#define FUNC2 conv_sep_rgba_f | |||||
#define PIXEL float | |||||
#define FLAGS 0 | |||||
#include "convolution_template.h" | |||||
#undef FUNC1 | |||||
#undef FUNC2 | |||||
#undef PIXEL | |||||
#undef FLAGS | |||||
#define FUNC1 conv_std_y_f | |||||
#define FUNC2 conv_sep_y_f | |||||
#define PIXEL float | |||||
#define FLAGS SET_FLAG_GRAY | |||||
#include "convolution_template.h" | |||||
#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" | |||||
#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[]) | pipi_image_t *pipi_convolution(pipi_image_t *src, int m, int n, double mat[]) | ||||
{ | { | ||||
@@ -115,14 +74,14 @@ pipi_image_t *pipi_convolution(pipi_image_t *src, int m, int n, double mat[]) | |||||
if(src->last_modified == PIPI_PIXELS_Y_F) | if(src->last_modified == PIPI_PIXELS_Y_F) | ||||
{ | { | ||||
if(src->wrap) | if(src->wrap) | ||||
return wrap_std_y_f(src, m, n, mat); | return conv_gray_wrap(src, m, n, mat); | ||||
return conv_std_y_f(src, m, n, mat); | return conv_gray(src, m, n, mat); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
if(src->wrap) | if(src->wrap) | ||||
return wrap_std_rgba_f(src, m, n, mat); | return conv_wrap(src, m, n, mat); | ||||
return conv_std_rgba_f(src, m, n, mat); | return conv(src, m, n, mat); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -139,11 +98,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 = src->wrap ? wrap_sep_y_f(src, m, hvec, n, vvec) | ret = src->wrap ? sepconv_gray_wrap(src, m, hvec, n, vvec) | ||||
: conv_sep_y_f(src, m, hvec, n, vvec); | : sepconv_gray(src, m, hvec, n, vvec); | ||||
else | else | ||||
ret = src->wrap ? wrap_sep_rgba_f(src, m, hvec, n, vvec) | ret = src->wrap ? sepconv_wrap(src, m, hvec, n, vvec) | ||||
: conv_sep_rgba_f(src, m, hvec, n, vvec); | : sepconv(src, m, hvec, n, vvec); | ||||
free(hvec); | free(hvec); | ||||
free(vvec); | free(vvec); | ||||
@@ -151,3 +110,207 @@ pipi_image_t *pipi_convolution(pipi_image_t *src, int m, int n, double mat[]) | |||||
return ret; | return ret; | ||||
} | } | ||||
#else /* XXX: the following functions use the template system */ | |||||
static pipi_image_t *SUFFIX(conv)(pipi_image_t *src, | |||||
int m, int n, double mat[]) | |||||
{ | |||||
pipi_image_t *dst; | |||||
pipi_pixels_t *srcp, *dstp; | |||||
float *srcdata, *dstdata; | |||||
int x, y, i, j, w, h; | |||||
w = src->w; | |||||
h = src->h; | |||||
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 = FLAG_GRAY ? pipi_getpixels(dst, PIPI_PIXELS_Y_F) | |||||
: pipi_getpixels(dst, PIPI_PIXELS_RGBA_F); | |||||
dstdata = (float *)dstp->pixels; | |||||
for(y = 0; y < h; y++) | |||||
{ | |||||
for(x = 0; x < w; x++) | |||||
{ | |||||
if(FLAG_GRAY) | |||||
{ | |||||
double Y = 0.; | |||||
int x2, y2; | |||||
for(j = 0; j < n; j++) | |||||
{ | |||||
y2 = y + j - n / 2; | |||||
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 = 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]; | |||||
} | |||||
} | |||||
dstdata[y * w + x] = Y < 0.0 ? 0.0 : Y > 1.0 ? 1.0 : Y; | |||||
} | |||||
else | |||||
{ | |||||
double R = 0., G = 0., B = 0.; | |||||
int x2, y2, off = 4 * (y * w + x); | |||||
for(j = 0; j < n; j++) | |||||
{ | |||||
y2 = y + j - n / 2; | |||||
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 = 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]; | |||||
B += f * srcdata[(y2 * w + x2) * 4 + 2]; | |||||
} | |||||
} | |||||
dstdata[off] = R < 0.0 ? 0.0 : R > 1.0 ? 1.0 : R; | |||||
dstdata[off + 1] = G < 0.0 ? 0.0 : G > 1.0 ? 1.0 : G; | |||||
dstdata[off + 2] = B < 0.0 ? 0.0 : B > 1.0 ? 1.0 : B; | |||||
} | |||||
} | |||||
} | |||||
return dst; | |||||
} | |||||
static pipi_image_t *SUFFIX(sepconv)(pipi_image_t *src, | |||||
int m, double hvec[], int n, double vvec[]) | |||||
{ | |||||
pipi_image_t *dst; | |||||
pipi_pixels_t *srcp, *dstp; | |||||
float *srcdata, *dstdata; | |||||
double *buffer; | |||||
int x, y, i, j, w, h; | |||||
w = src->w; | |||||
h = src->h; | |||||
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 = FLAG_GRAY ? pipi_getpixels(dst, PIPI_PIXELS_Y_F) | |||||
: pipi_getpixels(dst, PIPI_PIXELS_RGBA_F); | |||||
dstdata = (float *)dstp->pixels; | |||||
buffer = malloc(w * h * (FLAG_GRAY ? 1 : 4) * sizeof(double)); | |||||
for(y = 0; y < h; y++) | |||||
{ | |||||
for(x = 0; x < w; x++) | |||||
{ | |||||
if(FLAG_GRAY) | |||||
{ | |||||
double Y = 0.; | |||||
int x2; | |||||
for(i = 0; i < m; i++) | |||||
{ | |||||
x2 = x + i - m / 2; | |||||
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]; | |||||
} | |||||
buffer[y * w + x] = Y; | |||||
} | |||||
else | |||||
{ | |||||
double R = 0., G = 0., B = 0.; | |||||
int x2, off = 4 * (y * w + x); | |||||
for(i = 0; i < m; i++) | |||||
{ | |||||
double f = hvec[i]; | |||||
x2 = x + i - m / 2; | |||||
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]; | |||||
B += f * srcdata[(y * w + x2) * 4 + 2]; | |||||
} | |||||
buffer[off] = R; | |||||
buffer[off + 1] = G; | |||||
buffer[off + 2] = B; | |||||
} | |||||
} | |||||
} | |||||
for(y = 0; y < h; y++) | |||||
{ | |||||
for(x = 0; x < w; x++) | |||||
{ | |||||
if(FLAG_GRAY) | |||||
{ | |||||
double Y = 0.; | |||||
int y2; | |||||
for(j = 0; j < n; j++) | |||||
{ | |||||
y2 = y + j - n / 2; | |||||
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]; | |||||
} | |||||
dstdata[y * w + x] = Y < 0.0 ? 0.0 : Y > 1.0 ? 1.0 : Y; | |||||
} | |||||
else | |||||
{ | |||||
double R = 0., G = 0., B = 0.; | |||||
int y2, off = 4 * (y * w + x); | |||||
for(j = 0; j < n; j++) | |||||
{ | |||||
double f = vvec[j]; | |||||
y2 = y + j - n / 2; | |||||
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]; | |||||
B += f * buffer[(y2 * w + x) * 4 + 2]; | |||||
} | |||||
dstdata[off] = R < 0.0 ? 0.0 : R > 1.0 ? 1.0 : R; | |||||
dstdata[off + 1] = G < 0.0 ? 0.0 : G > 1.0 ? 1.0 : G; | |||||
dstdata[off + 2] = B < 0.0 ? 0.0 : B > 1.0 ? 1.0 : B; | |||||
} | |||||
} | |||||
} | |||||
free(buffer); | |||||
return dst; | |||||
} | |||||
#endif | |||||
@@ -1,227 +0,0 @@ | |||||
/* | |||||
* libpipi Proper image processing implementation library | |||||
* Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org> | |||||
* All Rights Reserved | |||||
* | |||||
* $Id$ | |||||
* | |||||
* This library is free software. It comes without any warranty, to | |||||
* the extent permitted by applicable law. You can redistribute it | |||||
* and/or modify it under the terms of the Do What The Fuck You Want | |||||
* To Public License, Version 2, as published by Sam Hocevar. See | |||||
* http://sam.zoy.org/wtfpl/COPYING for more details. | |||||
*/ | |||||
/* | |||||
* convolution_template.h: convolution templates | |||||
* required macros: | |||||
* FUNC1 standard function name | |||||
* FUNC2 separable function name | |||||
* PIXEL pixel type | |||||
* FLAGS 1 (grayscale) | |||||
* 2 (loop) | |||||
*/ | |||||
static pipi_image_t *FUNC1(pipi_image_t *src, int m, int n, double mat[]); | |||||
static pipi_image_t *FUNC2(pipi_image_t *src, int m, double hvec[], | |||||
int n, double vvec[]); | |||||
static pipi_image_t *FUNC1(pipi_image_t *src, int m, int n, double mat[]) | |||||
{ | |||||
pipi_image_t *dst; | |||||
pipi_pixels_t *srcp, *dstp; | |||||
PIXEL *srcdata, *dstdata; | |||||
int x, y, i, j, w, h; | |||||
w = src->w; | |||||
h = src->h; | |||||
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 = 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(FLAG_GRAY) | |||||
{ | |||||
double Y = 0.; | |||||
int x2, y2; | |||||
for(j = 0; j < n; j++) | |||||
{ | |||||
y2 = y + j - n / 2; | |||||
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 = 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]; | |||||
} | |||||
} | |||||
dstdata[y * w + x] = Y < 0.0 ? 0.0 : Y > 1.0 ? 1.0 : Y; | |||||
} | |||||
else | |||||
{ | |||||
double R = 0., G = 0., B = 0.; | |||||
int x2, y2, off = 4 * (y * w + x); | |||||
for(j = 0; j < n; j++) | |||||
{ | |||||
y2 = y + j - n / 2; | |||||
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 = 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]; | |||||
B += f * srcdata[(y2 * w + x2) * 4 + 2]; | |||||
} | |||||
} | |||||
dstdata[off] = R < 0.0 ? 0.0 : R > 1.0 ? 1.0 : R; | |||||
dstdata[off + 1] = G < 0.0 ? 0.0 : G > 1.0 ? 1.0 : G; | |||||
dstdata[off + 2] = B < 0.0 ? 0.0 : B > 1.0 ? 1.0 : B; | |||||
} | |||||
} | |||||
} | |||||
return dst; | |||||
} | |||||
static pipi_image_t *FUNC2(pipi_image_t *src, | |||||
int m, double hvec[], int n, double vvec[]) | |||||
{ | |||||
pipi_image_t *dst; | |||||
pipi_pixels_t *srcp, *dstp; | |||||
PIXEL *srcdata, *dstdata; | |||||
double *buffer; | |||||
int x, y, i, j, w, h; | |||||
w = src->w; | |||||
h = src->h; | |||||
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 = FLAG_GRAY ? pipi_getpixels(dst, PIPI_PIXELS_Y_F) | |||||
: pipi_getpixels(dst, PIPI_PIXELS_RGBA_F); | |||||
dstdata = (PIXEL *)dstp->pixels; | |||||
buffer = malloc(w * h * (FLAG_GRAY ? 1 : 4) * sizeof(double)); | |||||
for(y = 0; y < h; y++) | |||||
{ | |||||
for(x = 0; x < w; x++) | |||||
{ | |||||
if(FLAG_GRAY) | |||||
{ | |||||
double Y = 0.; | |||||
int x2; | |||||
for(i = 0; i < m; i++) | |||||
{ | |||||
x2 = x + i - m / 2; | |||||
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]; | |||||
} | |||||
buffer[y * w + x] = Y; | |||||
} | |||||
else | |||||
{ | |||||
double R = 0., G = 0., B = 0.; | |||||
int x2, off = 4 * (y * w + x); | |||||
for(i = 0; i < m; i++) | |||||
{ | |||||
double f = hvec[i]; | |||||
x2 = x + i - m / 2; | |||||
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]; | |||||
B += f * srcdata[(y * w + x2) * 4 + 2]; | |||||
} | |||||
buffer[off] = R; | |||||
buffer[off + 1] = G; | |||||
buffer[off + 2] = B; | |||||
} | |||||
} | |||||
} | |||||
for(y = 0; y < h; y++) | |||||
{ | |||||
for(x = 0; x < w; x++) | |||||
{ | |||||
if(FLAG_GRAY) | |||||
{ | |||||
double Y = 0.; | |||||
int y2; | |||||
for(j = 0; j < n; j++) | |||||
{ | |||||
y2 = y + j - n / 2; | |||||
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]; | |||||
} | |||||
dstdata[y * w + x] = Y < 0.0 ? 0.0 : Y > 1.0 ? 1.0 : Y; | |||||
} | |||||
else | |||||
{ | |||||
double R = 0., G = 0., B = 0.; | |||||
int y2, off = 4 * (y * w + x); | |||||
for(j = 0; j < n; j++) | |||||
{ | |||||
double f = vvec[j]; | |||||
y2 = y + j - n / 2; | |||||
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]; | |||||
B += f * buffer[(y2 * w + x) * 4 + 2]; | |||||
} | |||||
dstdata[off] = R < 0.0 ? 0.0 : R > 1.0 ? 1.0 : R; | |||||
dstdata[off + 1] = G < 0.0 ? 0.0 : G > 1.0 ? 1.0 : G; | |||||
dstdata[off + 2] = B < 0.0 ? 0.0 : B > 1.0 ? 1.0 : B; | |||||
} | |||||
} | |||||
} | |||||
free(buffer); | |||||
return dst; | |||||
} | |||||
@@ -19,6 +19,9 @@ | |||||
#ifndef __PIPI_INTERNALS_H__ | #ifndef __PIPI_INTERNALS_H__ | ||||
#define __PIPI_INTERNALS_H__ | #define __PIPI_INTERNALS_H__ | ||||
#define SET_FLAG_GRAY 0x00000001 | |||||
#define SET_FLAG_WRAP 0x00000002 | |||||
/* pipi_image_t: the image structure. This is probably going to be the most | /* pipi_image_t: the image structure. This is probably going to be the most | ||||
* complex structure in the library, but right now it only has fairly normal | * complex structure in the library, but right now it only has fairly normal | ||||
* stuff, like width and height and pointers to pixel areas. */ | * stuff, like width and height and pointers to pixel areas. */ | ||||
@@ -0,0 +1,68 @@ | |||||
/* | |||||
* libpipi Proper image processing implementation library | |||||
* Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org> | |||||
* All Rights Reserved | |||||
* | |||||
* $Id$ | |||||
* | |||||
* This library is free software. It comes without any warranty, to | |||||
* the extent permitted by applicable law. You can redistribute it | |||||
* and/or modify it under the terms of the Do What The Fuck You Want | |||||
* To Public License, Version 2, as published by Sam Hocevar. See | |||||
* http://sam.zoy.org/wtfpl/COPYING for more details. | |||||
*/ | |||||
/* pipi_template.h: the magic template preprocessing file | |||||
* | |||||
* Define the following macros before including this file: | |||||
* * TEMPLATE_FLAGS is set to a list of toggle flags, a binary OR of: | |||||
* - SET_FLAG_GRAY | |||||
* - SET_FLAG_WRAP | |||||
* * TEMPLATE_FILE is set to the template file. The following macros | |||||
* will be defined when including it. Their value depend on the flags | |||||
* specified above: | |||||
* - FLAG_GRAY is set to 0 or 1 | |||||
* - FLAG_WRAP is set to 0 or 1 | |||||
* - SUFFIX(x) expands x by adding relevant information, eg. x##_gray_wrap | |||||
*/ | |||||
#if !defined FLAG_GRAY | |||||
# if (TEMPLATE_FLAGS) & SET_FLAG_GRAY | |||||
# define FLAG_GRAY 1 | |||||
# include __FILE__ | |||||
# undef FLAG_GRAY | |||||
# endif | |||||
# define FLAG_GRAY 0 | |||||
# include __FILE__ | |||||
# undef FLAG_GRAY | |||||
#elif !defined FLAG_WRAP | |||||
# if (TEMPLATE_FLAGS) & SET_FLAG_WRAP | |||||
# define FLAG_WRAP 1 | |||||
# include __FILE__ | |||||
# undef FLAG_WRAP | |||||
# endif | |||||
# define FLAG_WRAP 0 | |||||
# include __FILE__ | |||||
# undef FLAG_WRAP | |||||
#else | |||||
/* FIXME: I couldn't find a way to do this in one preprocessor pass, | |||||
* too many levels of indirection seem to be needed. */ | |||||
# if FLAG_GRAY | |||||
# if FLAG_WRAP | |||||
# define SUFFIX(x) x##_gray_wrap | |||||
# else | |||||
# define SUFFIX(x) x##_gray | |||||
# endif | |||||
# else | |||||
# if FLAG_WRAP | |||||
# define SUFFIX(x) x##_wrap | |||||
# else | |||||
# define SUFFIX(x) x | |||||
# endif | |||||
# endif | |||||
# include TEMPLATE_FILE | |||||
# undef SUFFIX | |||||
#endif | |||||