Made bilinear interpolation function work, and edge conditions into structs with static functions rather than plain functions (in order to make bilinear interpolation work.)
Originally committed to SVN as r1511.
This commit is contained in:
parent
8e5e70cf8b
commit
17fbbaa583
2 changed files with 63 additions and 55 deletions
|
@ -588,66 +588,74 @@ typedef BaseImageAggregateImpl<PixelFormat::ABGR> ImageABGR;
|
||||||
// Access pixels with various edge conditions
|
// Access pixels with various edge conditions
|
||||||
namespace EdgeCondition {
|
namespace EdgeCondition {
|
||||||
template<class PixFmt>
|
template<class PixFmt>
|
||||||
inline PixFmt &blackness(BaseImage<PixFmt> &img, int x, int y)
|
struct Blackness {
|
||||||
{
|
static inline PixFmt &get(BaseImage<PixFmt> &img, int x, int y)
|
||||||
if (x < 0 || y < 0 || x >= img.width || x >= img.height) {
|
{
|
||||||
return PixFmt(); // all construct with all zeroes
|
if (x < 0 || y < 0 || x >= img.width || x >= img.height) {
|
||||||
} else {
|
return PixFmt(); // all construct with all zeroes
|
||||||
|
} else {
|
||||||
|
return img.Pixel(x,y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class PixFmt>
|
||||||
|
struct Closest {
|
||||||
|
static inline PixFmt &get(BaseImage<PixFmt> &img, int x, int y)
|
||||||
|
{
|
||||||
|
if (x < 0) x = 0;
|
||||||
|
if (y < 0) y = 0;
|
||||||
|
if (x >= img.width) x = img.width-1;
|
||||||
|
if (y >= img.height) y = img.height - 1;
|
||||||
return img.Pixel(x,y);
|
return img.Pixel(x,y);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
template<class PixFmt>
|
template<class PixFmt>
|
||||||
inline PixFmt &closest(BaseImage<PixFmt> &img, int x, int y)
|
struct Repeat {
|
||||||
{
|
static inline PixFmt &get(BaseImage<PixFmt> &img, int x, int y)
|
||||||
if (x < 0) x = 0;
|
{
|
||||||
if (y < 0) y = 0;
|
while (x < 0) x += img.width;
|
||||||
if (x >= img.width) x = img.width-1;
|
while (y < 0) y += img.height;
|
||||||
if (y >= img.height) y = img.height - 1;
|
while (x >= img.width) x -= img.width;
|
||||||
return img.Pixel(x,y);
|
while (y >= img.height) y -= img.height;
|
||||||
}
|
return img.Pixel(x,y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<class PixFmt>
|
template<class PixFmt>
|
||||||
inline PixFmt &repeat(BaseImage<PixFmt> &img, int x, int y)
|
struct Mirror {
|
||||||
{
|
static inline PixFmt &get(BaseImage<PixFmt> &img, int x, int y)
|
||||||
while (x < 0) x += img.width;
|
{
|
||||||
while (y < 0) y += img.height;
|
while (x < 0) x += img.width*2;
|
||||||
while (x >= img.width) x -= img.width;
|
while (y < 0) y += img.height*2;
|
||||||
while (y >= img.height) y -= img.height;
|
while (x >= img.width*2) x -= img.width*2;
|
||||||
return img.Pixel(x,y);
|
while (y >= img.height*2) y -= img.height*2;
|
||||||
}
|
if (x >= img.width) x = img.width - x;
|
||||||
|
if (y >= img.height) y = img.height - y;
|
||||||
template<class PixFmt>
|
return img.Pixel(x,y);
|
||||||
inline PixFmt &mirror(BaseImage<PixFmt> &img, int x, int y)
|
}
|
||||||
{
|
};
|
||||||
while (x < 0) x += img.width*2;
|
|
||||||
while (y < 0) y += img.height*2;
|
|
||||||
while (x >= img.width*2) x -= img.width*2;
|
|
||||||
while (y >= img.height*2) y -= img.height*2;
|
|
||||||
if (x >= img.width) x = img.width - x;
|
|
||||||
if (y >= img.height) y = img.height - y;
|
|
||||||
return img.Pixel(x,y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIXME: this is completely broken, the compiler won't accept it
|
// FIXME: this is completely broken, the compiler won't accept it
|
||||||
// when instantiated with one of the EdgeCondition functions for EdgeCond
|
// when instantiated with one of the EdgeCondition functions for EdgeCond
|
||||||
template<class PixFmt, class EdgeCond>
|
template<class PixFmt, typename EdgeCond>
|
||||||
inline PixFmt GetPixelBilinear(BaseImage<PixFmt> &img, double x, double y)
|
inline PixFmt GetPixelBilinear(BaseImage<PixFmt> &img, double x, double y)
|
||||||
{
|
{
|
||||||
PixFmt res;
|
PixFmt res;
|
||||||
double xpct = x - floor(x), ypct = y - floor(y);
|
double xpct = x - floor(x), ypct = y - floor(y);
|
||||||
|
|
||||||
const PixFmt &src11 = EdgeCond(img, (int)x, (int)y);
|
const PixFmt &src11 = EdgeCond::get(img, (int)x, (int)y);
|
||||||
const PixFmt &src12 = EdgeCond(img, (int)x, 1+(int)y);
|
const PixFmt &src12 = EdgeCond::get(img, (int)x, 1+(int)y);
|
||||||
const PixFmt &src21 = EdgeCond(img, 1+(int)x, (int)y);
|
const PixFmt &src21 = EdgeCond::get(img, 1+(int)x, (int)y);
|
||||||
const PixFmt &src22 = EdgeCond(img, 1+(int)x, 1+(int)y);
|
const PixFmt &src22 = EdgeCond::get(img, 1+(int)x, 1+(int)y);
|
||||||
|
|
||||||
res.R() += (1-xpct) * (1-ypct) * src11.R() + (1-xpct) * ypct * src12.R() + xpct * (1-ypct) * src21.R() + xpct * ypct * src22.R();
|
res.R() = (1-xpct) * (1-ypct) * src11.R() + (1-xpct) * ypct * src12.R() + xpct * (1-ypct) * src21.R() + xpct * ypct * src22.R();
|
||||||
res.G() += (1-xpct) * (1-ypct) * src11.G() + (1-xpct) * ypct * src12.G() + xpct * (1-ypct) * src21.G() + xpct * ypct * src22.G();
|
res.G() = (1-xpct) * (1-ypct) * src11.G() + (1-xpct) * ypct * src12.G() + xpct * (1-ypct) * src21.G() + xpct * ypct * src22.G();
|
||||||
res.B() += (1-xpct) * (1-ypct) * src11.B() + (1-xpct) * ypct * src12.B() + xpct * (1-ypct) * src21.B() + xpct * ypct * src22.B();
|
res.B() = (1-xpct) * (1-ypct) * src11.B() + (1-xpct) * ypct * src12.B() + xpct * (1-ypct) * src21.B() + xpct * ypct * src22.B();
|
||||||
res.A() += (1-xpct) * (1-ypct) * src11.A() + (1-xpct) * ypct * src12.A() + xpct * (1-ypct) * src21.A() + xpct * ypct * src22.A();
|
res.A() = (1-xpct) * (1-ypct) * src11.A() + (1-xpct) * ypct * src12.A() + xpct * (1-ypct) * src21.A() + xpct * ypct * src22.A();
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -429,8 +429,8 @@ struct DirectionalBlurFilter {
|
||||||
{
|
{
|
||||||
int a = 0;
|
int a = 0;
|
||||||
for (int t = -gk.width/2, i = 0; i < gk.width; t++, i++) {
|
for (int t = -gk.width/2, i = 0; i < gk.width; t++, i++) {
|
||||||
//PixelFormat::A8 &srcpx = GetPixelBilinear<PixelFormat::A8, EdgeCondition::repeat>(src, x+xstep*t, y+ystep*t);
|
PixelFormat::A8 &srcpx = GetPixelBilinear<PixelFormat::A8, EdgeCondition::Repeat<PixelFormat::A8> >(src, x+xstep*t, y+ystep*t);
|
||||||
PixelFormat::A8 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
//PixelFormat::A8 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
||||||
a += srcpx.A() * gk.kernel[i];
|
a += srcpx.A() * gk.kernel[i];
|
||||||
}
|
}
|
||||||
PixelFormat::A8 res;
|
PixelFormat::A8 res;
|
||||||
|
@ -442,8 +442,8 @@ struct DirectionalBlurFilter {
|
||||||
{
|
{
|
||||||
int r = 0, g = 0, b = 0;
|
int r = 0, g = 0, b = 0;
|
||||||
for (int t = -gk.width/2, i = 0; i < gk.width; t++, i++) {
|
for (int t = -gk.width/2, i = 0; i < gk.width; t++, i++) {
|
||||||
//PixelFormat::cairo_rgb24 &srcpx = GetPixelBilinear<PixelFormat::cairo_rgb24, EdgeCondition::repeat>(src, x+xstep*t, y+ystep*t);
|
PixelFormat::cairo_rgb24 &srcpx = GetPixelBilinear<PixelFormat::cairo_rgb24, EdgeCondition::Repeat<PixelFormat::cairo_rgb24> >(src, x+xstep*t, y+ystep*t);
|
||||||
PixelFormat::cairo_rgb24 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
//PixelFormat::cairo_rgb24 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
||||||
r += srcpx.R() * gk.kernel[i];
|
r += srcpx.R() * gk.kernel[i];
|
||||||
g += srcpx.G() * gk.kernel[i];
|
g += srcpx.G() * gk.kernel[i];
|
||||||
b += srcpx.B() * gk.kernel[i];
|
b += srcpx.B() * gk.kernel[i];
|
||||||
|
@ -461,8 +461,8 @@ struct DirectionalBlurFilter {
|
||||||
{
|
{
|
||||||
int a = 0, r = 0, g = 0, b = 0;
|
int a = 0, r = 0, g = 0, b = 0;
|
||||||
for (int t = -gk.width/2, i = 0; i < gk.width; t++, i++) {
|
for (int t = -gk.width/2, i = 0; i < gk.width; t++, i++) {
|
||||||
//PixelFormat::cairo_argb32 &srcpx = GetPixelBilinear<PixelFormat::cairo_argb32, EdgeCondition::repeat>(src, x+xstep*t, y+ystep*t);
|
PixelFormat::cairo_argb32 &srcpx = GetPixelBilinear<PixelFormat::cairo_argb32, EdgeCondition::Repeat<PixelFormat::cairo_argb32> >(src, x+xstep*t, y+ystep*t);
|
||||||
PixelFormat::cairo_argb32 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
//PixelFormat::cairo_argb32 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
||||||
a += srcpx.A() * gk.kernel[i];
|
a += srcpx.A() * gk.kernel[i];
|
||||||
r += srcpx.R() * gk.kernel[i];
|
r += srcpx.R() * gk.kernel[i];
|
||||||
g += srcpx.G() * gk.kernel[i];
|
g += srcpx.G() * gk.kernel[i];
|
||||||
|
@ -510,8 +510,8 @@ struct RadialBlurFilter {
|
||||||
int divisor = 0;
|
int divisor = 0;
|
||||||
int a = 0;
|
int a = 0;
|
||||||
for (int t = 0, i = gk.width/2; i < gk.width; t++, i++) {
|
for (int t = 0, i = gk.width/2; i < gk.width; t++, i++) {
|
||||||
//PixelFormat::A8 &srcpx = GetPixelBilinear<PixelFormat::A8, EdgeCondition::repeat>(src, x+xstep*t, y+ystep*t);
|
PixelFormat::A8 &srcpx = GetPixelBilinear<PixelFormat::A8, EdgeCondition::Repeat<PixelFormat::A8> >(src, x+xstep*t, y+ystep*t);
|
||||||
PixelFormat::A8 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
//PixelFormat::A8 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
||||||
a += srcpx.A() * gk.kernel[i];
|
a += srcpx.A() * gk.kernel[i];
|
||||||
divisor += gk.kernel[i];
|
divisor += gk.kernel[i];
|
||||||
}
|
}
|
||||||
|
@ -528,8 +528,8 @@ struct RadialBlurFilter {
|
||||||
int divisor = 0;
|
int divisor = 0;
|
||||||
int r = 0, g = 0, b = 0;
|
int r = 0, g = 0, b = 0;
|
||||||
for (int t = 0, i = gk.width/2; i < gk.width; t++, i++) {
|
for (int t = 0, i = gk.width/2; i < gk.width; t++, i++) {
|
||||||
//PixelFormat::A8 &srcpx = GetPixelBilinear<PixelFormat::A8, EdgeCondition::repeat>(src, x+xstep*t, y+ystep*t);
|
PixelFormat::cairo_rgb24 &srcpx = GetPixelBilinear<PixelFormat::cairo_rgb24, EdgeCondition::Repeat<PixelFormat::cairo_rgb24> >(src, x+xstep*t, y+ystep*t);
|
||||||
PixelFormat::cairo_rgb24 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
//PixelFormat::cairo_rgb24 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
||||||
r += srcpx.R() * gk.kernel[i];
|
r += srcpx.R() * gk.kernel[i];
|
||||||
g += srcpx.G() * gk.kernel[i];
|
g += srcpx.G() * gk.kernel[i];
|
||||||
b += srcpx.B() * gk.kernel[i];
|
b += srcpx.B() * gk.kernel[i];
|
||||||
|
@ -552,8 +552,8 @@ struct RadialBlurFilter {
|
||||||
int divisor = 0;
|
int divisor = 0;
|
||||||
int a = 0, r = 0, g = 0, b = 0;
|
int a = 0, r = 0, g = 0, b = 0;
|
||||||
for (int t = 0, i = gk.width/2; i < gk.width; t++, i++) {
|
for (int t = 0, i = gk.width/2; i < gk.width; t++, i++) {
|
||||||
//PixelFormat::A8 &srcpx = GetPixelBilinear<PixelFormat::A8, EdgeCondition::repeat>(src, x+xstep*t, y+ystep*t);
|
PixelFormat::cairo_argb32 &srcpx = GetPixelBilinear<PixelFormat::cairo_argb32, EdgeCondition::Repeat<PixelFormat::cairo_argb32> >(src, x+xstep*t, y+ystep*t);
|
||||||
PixelFormat::cairo_argb32 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
//PixelFormat::cairo_argb32 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
||||||
a += srcpx.A() * gk.kernel[i];
|
a += srcpx.A() * gk.kernel[i];
|
||||||
r += srcpx.R() * gk.kernel[i];
|
r += srcpx.R() * gk.kernel[i];
|
||||||
g += srcpx.G() * gk.kernel[i];
|
g += srcpx.G() * gk.kernel[i];
|
||||||
|
|
Loading…
Reference in a new issue