This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project gfxprim.git.
The branch, master has been updated via 268e020540d7c79ee472d75c1f959228f419b82b (commit) from cac343079cd56a28eac9e54ca3ab4aeee3fba683 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- http://repo.or.cz/w/gfxprim.git/commit/268e020540d7c79ee472d75c1f959228f419b...
commit 268e020540d7c79ee472d75c1f959228f419b82b Author: Cyril Hrubis metan@ucw.cz Date: Sat Nov 26 21:10:09 2011 +0100
filters: Fixed and edhanced bicubic interpolation.
* Fixed the filter so it's stable (the image looks same after number of 1:1 interpolations)
* Added integer version of the filter - slightly faster on PC, expected to rock on ARM
diff --git a/demos/fbshow/fbshow.c b/demos/fbshow/fbshow.c index 27af5e3..8c1a2e7 100644 --- a/demos/fbshow/fbshow.c +++ b/demos/fbshow/fbshow.c @@ -155,9 +155,9 @@ static void *image_loader(void *ptr) GP_Context *ret;
- //callback.priv = "Blurring Image"; - //if (GP_FilterGaussianBlur(img, img, 0.25/rat, 0.25/rat, &callback) == NULL) - // return NULL; + callback.priv = "Blurring Image"; + if (GP_FilterGaussianBlur(img, img, 0.3/rat, 0.3/rat, &callback) == NULL) + return NULL; callback.priv = "Resampling Image"; ret = GP_FilterResize(img, NULL, GP_INTERP_CUBIC, img->w * rat, img->h * rat, &callback); diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c index 2a9ec43..09081c7 100644 --- a/demos/grinder/grinder.c +++ b/demos/grinder/grinder.c @@ -81,6 +81,7 @@ static void print_error(const char *error) static const char *resize_algs[] = { "nn", "cubic", + "cubic-int", NULL };
@@ -135,6 +136,7 @@ static GP_RetCode resize(GP_Context **c, const char *params) static const char *scale_algs[] = { "nn", "cubic", + "cubic-int", NULL };
diff --git a/include/filters/GP_Resize.h b/include/filters/GP_Resize.h index 692339c..fcae054 100644 --- a/include/filters/GP_Resize.h +++ b/include/filters/GP_Resize.h @@ -47,8 +47,9 @@ #include "GP_Filter.h"
typedef enum GP_InterpolationType { - GP_INTERP_NN, /* Nearest Neighbour */ - GP_INTERP_CUBIC, /* Bicubic */ + GP_INTERP_NN, /* Nearest Neighbour */ + GP_INTERP_CUBIC, /* Bicubic */ + GP_INTERP_CUBIC_INT, /* Bicubic - integer arithmetics */ } GP_InterpolationType;
/* diff --git a/libs/filters/GP_Resize.c b/libs/filters/GP_Resize.c index baf7db5..ac5ea0d 100644 --- a/libs/filters/GP_Resize.c +++ b/libs/filters/GP_Resize.c @@ -103,21 +103,21 @@ int GP_FilterInterpolate_Cubic(const GP_Context *src, GP_Context *dst, 1.00 * dst->w / src->w, 1.00 * dst->h / src->h);
for (i = 0; i < dst->w; i++) { - float x = (1.00 * i / dst->w) * (src->w - 4.5) + 2.5; + float x = (1.00 * i / dst->w) * src->w; v4f cvx; int xi = x - 1; - - cvx.f[0] = cubic(x - xi); - cvx.f[1] = cubic(x - xi - 1); - cvx.f[2] = cubic(x - xi - 2); - cvx.f[3] = cubic(x - xi - 3); if (xi < 0) xi = 0;
if (xi > (int)src->w - 4) xi = src->w - 4; - + + cvx.f[0] = cubic(x - xi); + cvx.f[1] = cubic(x - xi - 1); + cvx.f[2] = cubic(x - xi - 2); + cvx.f[3] = cubic(x - xi - 3); + /* Generate interpolated column */ for (j = 0; j < src->h; j++) { v4f rv, gv, bv; @@ -154,22 +154,22 @@ int GP_FilterInterpolate_Cubic(const GP_Context *src, GP_Context *dst,
/* now interpolate column for new image */ for (j = 0; j < dst->h; j++) { - float y = (1.00 * j / dst->h) * (src->h - 4.5) + 2.5; + float y = (1.00 * j / dst->h) * src->h; v4f cvy, rv, gv, bv; float r, g, b; - int yi = y - 1; + int yi = y; - cvy.f[0] = cubic(y - yi); - cvy.f[1] = cubic(y - yi - 1); - cvy.f[2] = cubic(y - yi - 2); - cvy.f[3] = cubic(y - yi - 3); - if (yi < 0) yi = 0;
if (yi > (int)src->h - 4) yi = src->h - 4; + cvy.f[0] = cubic(y - yi); + cvy.f[1] = cubic(y - yi - 1); + cvy.f[2] = cubic(y - yi - 2); + cvy.f[3] = cubic(y - yi - 3); + rv.f[0] = col_r[yi]; rv.f[1] = col_r[yi + 1]; rv.f[2] = col_r[yi + 2]; @@ -223,6 +223,150 @@ int GP_FilterInterpolate_Cubic(const GP_Context *src, GP_Context *dst, return 0; }
+#define MUL 2048 + +#define MUL_I(a, b) ({ + a[0] *= b[0]; + a[1] *= b[1]; + a[2] *= b[2]; + a[3] *= b[3]; +}) + +#define SUM_I(a) + ((a)[0] + (a)[1] + (a)[2] + (a)[3]) + +int GP_FilterInterpolate_CubicInt(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) +{ + int32_t col_r[src->h], col_g[src->h], col_b[src->h]; + uint32_t i, j; + + GP_DEBUG(1, "Scaling image %ux%u -> %ux%u %2.2f %2.2f", + src->w, src->h, dst->w, dst->h, + 1.00 * dst->w / src->w, 1.00 * dst->h / src->h); + + for (i = 0; i < dst->w; i++) { + float x = (1.00 * i / dst->w) * src->w; + int32_t cvx[4]; + int xi = x - 1; + + if (xi < 0) + xi = 0; + + if (xi > (int)src->w - 4) + xi = src->w - 4; + + cvx[0] = cubic(x - xi) * MUL + 0.5; + cvx[1] = cubic(x - xi - 1) * MUL + 0.5; + cvx[2] = cubic(x - xi - 2) * MUL + 0.5; + cvx[3] = cubic(x - xi - 3) * MUL + 0.5; + + /* Generate interpolated column */ + for (j = 0; j < src->h; j++) { + int32_t rv[4], gv[4], bv[4]; + GP_Pixel pix[4]; + + pix[0] = GP_GetPixel_Raw_24BPP(src, xi, j); + pix[1] = GP_GetPixel_Raw_24BPP(src, xi + 1, j); + pix[2] = GP_GetPixel_Raw_24BPP(src, xi + 2, j); + pix[3] = GP_GetPixel_Raw_24BPP(src, xi + 3, j); + + rv[0] = GP_Pixel_GET_R_RGB888(pix[0]); + rv[1] = GP_Pixel_GET_R_RGB888(pix[1]); + rv[2] = GP_Pixel_GET_R_RGB888(pix[2]); + rv[3] = GP_Pixel_GET_R_RGB888(pix[3]); + + gv[0] = GP_Pixel_GET_G_RGB888(pix[0]); + gv[1] = GP_Pixel_GET_G_RGB888(pix[1]); + gv[2] = GP_Pixel_GET_G_RGB888(pix[2]); + gv[3] = GP_Pixel_GET_G_RGB888(pix[3]); + + bv[0] = GP_Pixel_GET_B_RGB888(pix[0]); + bv[1] = GP_Pixel_GET_B_RGB888(pix[1]); + bv[2] = GP_Pixel_GET_B_RGB888(pix[2]); + bv[3] = GP_Pixel_GET_B_RGB888(pix[3]); + + MUL_I(rv, cvx); + MUL_I(gv, cvx); + MUL_I(bv, cvx); + + col_r[j] = SUM_I(rv); + col_g[j] = SUM_I(gv); + col_b[j] = SUM_I(bv); + } + + /* now interpolate column for new image */ + for (j = 0; j < dst->h; j++) { + float y = (1.00 * j / dst->h) * src->h; + int32_t cvy[4], rv[4], gv[4], bv[4]; + int32_t r, g, b; + int yi = y - 1; + + if (yi < 0) + yi = 0; + + if (yi > (int)src->h - 4) + yi = src->h - 4; + + cvy[0] = cubic(y - yi) * MUL + 0.5; + cvy[1] = cubic(y - yi - 1) * MUL + 0.5; + cvy[2] = cubic(y - yi - 2) * MUL + 0.5; + cvy[3] = cubic(y - yi - 3) * MUL + 0.5; + + rv[0] = col_r[yi]; + rv[1] = col_r[yi + 1]; + rv[2] = col_r[yi + 2]; + rv[3] = col_r[yi + 3]; + + gv[0] = col_g[yi]; + gv[1] = col_g[yi + 1]; + gv[2] = col_g[yi + 2]; + gv[3] = col_g[yi + 3]; + + bv[0] = col_b[yi]; + bv[1] = col_b[yi + 1]; + bv[2] = col_b[yi + 2]; + bv[3] = col_b[yi + 3]; + + MUL_I(rv, cvy); + MUL_I(gv, cvy); + MUL_I(bv, cvy); + + r = (SUM_I(rv) + MUL*MUL/2) / MUL / MUL; + g = (SUM_I(gv) + MUL*MUL/2) / MUL / MUL; + b = (SUM_I(bv) + MUL*MUL/2) / MUL / MUL; + + if (r > 255) + r = 255; + + if (r < 0) + r = 0; + + if (g > 255) + g = 255; + + if (g < 0) + g = 0; + + if (b > 255) + b = 255; + + if (b < 0) + b = 0; + + GP_Pixel pix = GP_Pixel_CREATE_RGB888((uint8_t)r, (uint8_t)g, (uint8_t)b); + GP_PutPixel_Raw_24BPP(dst, i, j, pix); + } + + if (GP_ProgressCallbackReport(callback, i, dst->w, dst->h)) + return 1; + } + + GP_ProgressCallbackDone(callback); + return 0; +} + + int GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst, GP_InterpolationType type, GP_ProgressCallback *callback) @@ -232,6 +376,8 @@ int GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst, return GP_FilterInterpolate_NN(src, dst, callback); case GP_INTERP_CUBIC: return GP_FilterInterpolate_Cubic(src, dst, callback); + case GP_INTERP_CUBIC_INT: + return GP_FilterInterpolate_CubicInt(src, dst, callback); }
return 1;
-----------------------------------------------------------------------
Summary of changes: demos/fbshow/fbshow.c | 6 +- demos/grinder/grinder.c | 2 + include/filters/GP_Resize.h | 5 +- libs/filters/GP_Resize.c | 174 +++++++++++++++++++++++++++++++++++++++---- 4 files changed, 168 insertions(+), 19 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos@gmail.com if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.