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 d17743a7cfa2617c5f50d47f801f8722480553fc (commit) from 66cbe1a3b25ba7d4c3361d420fa9de364c02557e (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/d17743a7cfa2617c5f50d47f801f872248055...
commit d17743a7cfa2617c5f50d47f801f8722480553fc Author: Cyril Hrubis metan@ucw.cz Date: Mon Jan 23 16:57:24 2012 +0100
filters: Added Bilinear interpolation.
diff --git a/include/filters/GP_Resize.h b/include/filters/GP_Resize.h index fcae054..53cca92 100644 --- a/include/filters/GP_Resize.h +++ b/include/filters/GP_Resize.h @@ -31,6 +31,10 @@ edges mostly consisting of big one color regions (eg doesn't blur the result on upscaling).
+ Bilinear + ~~~~~~~~ + + Faster than Bicubic, but less precise.
Bicubic ~~~~~~~ @@ -47,9 +51,10 @@ #include "GP_Filter.h"
typedef enum GP_InterpolationType { - GP_INTERP_NN, /* Nearest Neighbour */ - GP_INTERP_CUBIC, /* Bicubic */ - GP_INTERP_CUBIC_INT, /* Bicubic - integer arithmetics */ + GP_INTERP_NN, /* Nearest Neighbour */ + GP_INTERP_LINEAR_INT, /* Bilinear - fixed point arithmetics */ + GP_INTERP_CUBIC, /* Bicubic */ + GP_INTERP_CUBIC_INT, /* Bicubic - fixed point arithmetics */ } GP_InterpolationType;
/* diff --git a/libs/filters/GP_Resize.c b/libs/filters/GP_Resize.c index a29ec0d..a812599 100644 --- a/libs/filters/GP_Resize.c +++ b/libs/filters/GP_Resize.c @@ -32,18 +32,30 @@ int GP_FilterInterpolate_NN(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback) { + uint32_t xmap[dst->w]; + uint32_t ymap[dst->h]; + uint32_t i; GP_Coord x, y; 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);
+ /* Pre-compute mapping for interpolation */ + uint32_t xstep = (src->w << 16) / dst->w; + + for (i = 0; i < dst->w + 1; i++) + xmap[i] = ((i * xstep) + (1<<15)) >> 16; + + uint32_t ystep = (src->h << 16) / dst->h; + + for (i = 0; i < dst->h + 1; i++) + ymap[i] = ((i * ystep) + (1<<15)) >> 16; + + /* Interpolate */ for (y = 0; y < (GP_Coord)dst->h; y++) { for (x = 0; x < (GP_Coord)dst->w; x++) { - GP_Coord xi = (1.00 * x / dst->w) * src->w; - GP_Coord yi = (1.00 * y / dst->h) * src->h; - - GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, xi, yi); + GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, xmap[x], ymap[y]);
GP_PutPixel_Raw_24BPP(dst, x, y, pix); } @@ -379,6 +391,92 @@ int GP_FilterInterpolate_CubicInt(const GP_Context *src, GP_Context *dst, return 0; }
+int GP_FilterInterpolate_LinearInt(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) +{ + uint32_t xmap[dst->w + 1]; + uint32_t ymap[dst->h + 1]; + uint8_t xoff[dst->w + 1]; + uint8_t yoff[dst->h + 1]; + 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); + + /* Pre-compute mapping for interpolation */ + uint32_t xstep = (src->w << 16) / dst->w; + + for (i = 0; i < dst->w + 1; i++) { + uint32_t val = i * xstep; + xmap[i] = val >> 16; + xoff[i] = (val >> 8) & 0xff; + } + + uint32_t ystep = (src->h << 16) / dst->h; + + for (i = 0; i < dst->h + 1; i++) { + uint32_t val = i * ystep; + ymap[i] = val >> 16; + yoff[i] = (val >> 8) & 0xff; + } + + /* Interpolate */ + for (i = 0; i < dst->h; i++) { + for (j = 0; j < dst->w; j++) { + GP_Pixel pix00, pix01, pix10, pix11; + uint32_t r0, r1, g0, g1, b0, b1; + GP_Coord x0, x1, y0, y1; + + x0 = xmap[j]; + x1 = xmap[j] + 1; + + if (x1 >= (GP_Coord)src->w) + x1 = src->w - 1; + + y0 = ymap[i]; + y1 = ymap[i] + 1; + + if (y1 >= (GP_Coord)src->h) + y1 = src->h - 1; + + pix00 = GP_GetPixel_Raw_24BPP(src, x0, y0); + pix10 = GP_GetPixel_Raw_24BPP(src, x1, y0); + pix01 = GP_GetPixel_Raw_24BPP(src, x0, y1); + pix11 = GP_GetPixel_Raw_24BPP(src, x1, y1); + + r0 = GP_Pixel_GET_R_RGB888(pix00) * (255 - xoff[j]); + g0 = GP_Pixel_GET_G_RGB888(pix00) * (255 - xoff[j]); + b0 = GP_Pixel_GET_B_RGB888(pix00) * (255 - xoff[j]); + + r0 += GP_Pixel_GET_R_RGB888(pix10) * xoff[j]; + g0 += GP_Pixel_GET_G_RGB888(pix10) * xoff[j]; + b0 += GP_Pixel_GET_B_RGB888(pix10) * xoff[j]; + + r1 = GP_Pixel_GET_R_RGB888(pix01) * (255 - xoff[j]); + g1 = GP_Pixel_GET_G_RGB888(pix01) * (255 - xoff[j]); + b1 = GP_Pixel_GET_B_RGB888(pix01) * (255 - xoff[j]); + + r1 += GP_Pixel_GET_R_RGB888(pix11) * xoff[j]; + g1 += GP_Pixel_GET_G_RGB888(pix11) * xoff[j]; + b1 += GP_Pixel_GET_B_RGB888(pix11) * xoff[j]; + + r0 = (r1 * yoff[i] + r0 * (255 - yoff[i])) >> 16; + g0 = (g1 * yoff[i] + g0 * (255 - yoff[i])) >> 16; + b0 = (b1 * yoff[i] + b0 * (255 - yoff[i])) >> 16; + + GP_PutPixel_Raw_24BPP(dst, j, i, + GP_Pixel_CREATE_RGB888(r0, g0, b0)); + } + + if (GP_ProgressCallbackReport(callback, i, dst->h, dst->w)) + return 1; + } + + GP_ProgressCallbackDone(callback); + return 0; +} + int GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst, GP_InterpolationType type, GP_ProgressCallback *callback) @@ -386,6 +484,8 @@ int GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst, switch (type) { case GP_INTERP_NN: return GP_FilterInterpolate_NN(src, dst, callback); + case GP_INTERP_LINEAR_INT: + return GP_FilterInterpolate_LinearInt(src, dst, callback); case GP_INTERP_CUBIC: return GP_FilterInterpolate_Cubic(src, dst, callback); case GP_INTERP_CUBIC_INT:
-----------------------------------------------------------------------
Summary of changes: include/filters/GP_Resize.h | 11 +++- libs/filters/GP_Resize.c | 108 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 112 insertions(+), 7 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.