From 17fbbaa58362c09e069e8720b98d776556e0ad4b Mon Sep 17 00:00:00 2001 From: Niels Martin Hansen Date: Sat, 18 Aug 2007 13:42:37 +0000 Subject: [PATCH] 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. --- OverLua/image.h | 94 +++++++++++++++++++++++------------------- OverLua/raster_ops.cpp | 24 +++++------ 2 files changed, 63 insertions(+), 55 deletions(-) diff --git a/OverLua/image.h b/OverLua/image.h index 6bedb1110..04c075d2d 100644 --- a/OverLua/image.h +++ b/OverLua/image.h @@ -588,66 +588,74 @@ typedef BaseImageAggregateImpl ImageABGR; // Access pixels with various edge conditions namespace EdgeCondition { template - inline PixFmt &blackness(BaseImage &img, int x, int y) - { - if (x < 0 || y < 0 || x >= img.width || x >= img.height) { - return PixFmt(); // all construct with all zeroes - } else { + struct Blackness { + static inline PixFmt &get(BaseImage &img, int x, int y) + { + if (x < 0 || y < 0 || x >= img.width || x >= img.height) { + return PixFmt(); // all construct with all zeroes + } else { + return img.Pixel(x,y); + } + } + }; + + template + struct Closest { + static inline PixFmt &get(BaseImage &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); } - } + }; template - inline PixFmt &closest(BaseImage &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); - } + struct Repeat { + static inline PixFmt &get(BaseImage &img, int x, int y) + { + while (x < 0) x += img.width; + while (y < 0) y += img.height; + while (x >= img.width) x -= img.width; + while (y >= img.height) y -= img.height; + return img.Pixel(x,y); + } + }; template - inline PixFmt &repeat(BaseImage &img, int x, int y) - { - while (x < 0) x += img.width; - while (y < 0) y += img.height; - while (x >= img.width) x -= img.width; - while (y >= img.height) y -= img.height; - return img.Pixel(x,y); - } - - template - inline PixFmt &mirror(BaseImage &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); - } + struct Mirror { + static inline PixFmt &get(BaseImage &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 // when instantiated with one of the EdgeCondition functions for EdgeCond -template +template inline PixFmt GetPixelBilinear(BaseImage &img, double x, double y) { PixFmt res; double xpct = x - floor(x), ypct = y - floor(y); - const PixFmt &src11 = EdgeCond(img, (int)x, (int)y); - const PixFmt &src12 = EdgeCond(img, (int)x, 1+(int)y); - const PixFmt &src21 = EdgeCond(img, 1+(int)x, (int)y); - const PixFmt &src22 = EdgeCond(img, 1+(int)x, 1+(int)y); + const PixFmt &src11 = EdgeCond::get(img, (int)x, (int)y); + const PixFmt &src12 = EdgeCond::get(img, (int)x, 1+(int)y); + const PixFmt &src21 = EdgeCond::get(img, 1+(int)x, (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.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.A() += (1-xpct) * (1-ypct) * src11.A() + (1-xpct) * ypct * src12.A() + xpct * (1-ypct) * src21.A() + xpct * ypct * src22.A(); + 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.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(); return res; } diff --git a/OverLua/raster_ops.cpp b/OverLua/raster_ops.cpp index e5fabfc56..cae633416 100644 --- a/OverLua/raster_ops.cpp +++ b/OverLua/raster_ops.cpp @@ -429,8 +429,8 @@ struct DirectionalBlurFilter { { int a = 0; for (int t = -gk.width/2, i = 0; i < gk.width; t++, i++) { - //PixelFormat::A8 &srcpx = GetPixelBilinear(src, x+xstep*t, y+ystep*t); - PixelFormat::A8 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t)); + PixelFormat::A8 &srcpx = GetPixelBilinear >(src, x+xstep*t, y+ystep*t); + //PixelFormat::A8 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t)); a += srcpx.A() * gk.kernel[i]; } PixelFormat::A8 res; @@ -442,8 +442,8 @@ struct DirectionalBlurFilter { { int r = 0, g = 0, b = 0; for (int t = -gk.width/2, i = 0; i < gk.width; t++, i++) { - //PixelFormat::cairo_rgb24 &srcpx = GetPixelBilinear(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 = GetPixelBilinear >(src, x+xstep*t, y+ystep*t); + //PixelFormat::cairo_rgb24 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t)); r += srcpx.R() * gk.kernel[i]; g += srcpx.G() * gk.kernel[i]; b += srcpx.B() * gk.kernel[i]; @@ -461,8 +461,8 @@ struct DirectionalBlurFilter { { int a = 0, r = 0, g = 0, b = 0; for (int t = -gk.width/2, i = 0; i < gk.width; t++, i++) { - //PixelFormat::cairo_argb32 &srcpx = GetPixelBilinear(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 = GetPixelBilinear >(src, x+xstep*t, y+ystep*t); + //PixelFormat::cairo_argb32 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t)); a += srcpx.A() * gk.kernel[i]; r += srcpx.R() * gk.kernel[i]; g += srcpx.G() * gk.kernel[i]; @@ -510,8 +510,8 @@ struct RadialBlurFilter { int divisor = 0; int a = 0; for (int t = 0, i = gk.width/2; i < gk.width; t++, i++) { - //PixelFormat::A8 &srcpx = GetPixelBilinear(src, x+xstep*t, y+ystep*t); - PixelFormat::A8 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t)); + PixelFormat::A8 &srcpx = GetPixelBilinear >(src, x+xstep*t, y+ystep*t); + //PixelFormat::A8 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t)); a += srcpx.A() * gk.kernel[i]; divisor += gk.kernel[i]; } @@ -528,8 +528,8 @@ struct RadialBlurFilter { int divisor = 0; int r = 0, g = 0, b = 0; for (int t = 0, i = gk.width/2; i < gk.width; t++, i++) { - //PixelFormat::A8 &srcpx = GetPixelBilinear(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 = GetPixelBilinear >(src, x+xstep*t, y+ystep*t); + //PixelFormat::cairo_rgb24 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t)); r += srcpx.R() * gk.kernel[i]; g += srcpx.G() * gk.kernel[i]; b += srcpx.B() * gk.kernel[i]; @@ -552,8 +552,8 @@ struct RadialBlurFilter { int divisor = 0; int a = 0, r = 0, g = 0, b = 0; for (int t = 0, i = gk.width/2; i < gk.width; t++, i++) { - //PixelFormat::A8 &srcpx = GetPixelBilinear(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 = GetPixelBilinear >(src, x+xstep*t, y+ystep*t); + //PixelFormat::cairo_argb32 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t)); a += srcpx.A() * gk.kernel[i]; r += srcpx.R() * gk.kernel[i]; g += srcpx.G() * gk.kernel[i];