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 e4962e78d7114be162c9c83e6068f03e9455fb01 (commit) via 3e363191fedfbf7391ffe5fafc3fa8a3fb3fc78f (commit) from f4da6fbfe83e00302e52a89265b2f2e84283df4c (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/e4962e78d7114be162c9c83e6068f03e9455f...
commit e4962e78d7114be162c9c83e6068f03e9455fb01 Merge: 3e36319 f4da6fb Author: Cyril Hrubis metan@ucw.cz Date: Mon Jun 18 13:19:37 2012 +0200
Merge ssh://repo.or.cz/srv/git/gfxprim
http://repo.or.cz/w/gfxprim.git/commit/3e363191fedfbf7391ffe5fafc3fa8a3fb3fc...
commit 3e363191fedfbf7391ffe5fafc3fa8a3fb3fc78f Author: Cyril Hrubis metan@ucw.cz Date: Mon Jun 18 13:17:51 2012 +0200
filters: Add generated cubic resampling (with gamma) yay!
diff --git a/libs/filters/GP_Cubic.h b/libs/filters/GP_Cubic.h index 3e7dbef..213031a 100644 --- a/libs/filters/GP_Cubic.h +++ b/libs/filters/GP_Cubic.h @@ -29,7 +29,7 @@ #ifndef FILTERS_GP_CUBIC_H #define FILTERS_GP_CUBIC_H
-#define A 0.5 +#define Ap 0.5
static inline float cubic_float(float x) { @@ -37,10 +37,10 @@ static inline float cubic_float(float x) x = -x;
if (x < 1) - return (2 - A)*x*x*x + (A - 3)*x*x + 1; + return (2 - Ap)*x*x*x + (Ap - 3)*x*x + 1;
if (x < 2) - return -A*x*x*x + 5*A*x*x - 8*A*x + 4*A; + return -Ap*x*x*x + 5*Ap*x*x - 8*Ap*x + 4*Ap;
return 0; } diff --git a/libs/filters/GP_Resize.c b/libs/filters/GP_Resize.c index 79362ef..022ba99 100644 --- a/libs/filters/GP_Resize.c +++ b/libs/filters/GP_Resize.c @@ -30,6 +30,7 @@
#include "GP_Resize.h"
+/* See GP_ResizeNN.gen.c */ int GP_FilterResizeNN_Raw(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback);
@@ -58,6 +59,35 @@ GP_Context *GP_FilterResizeNNAlloc(const GP_Context *src, return res; }
+/* See GP_ResizeCubic.gen.c */ +int GP_FilterResizeCubicInt_Raw(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback); + +int GP_FilterResizeCubicInt(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) +{ + GP_ASSERT(src->pixel_type == dst->pixel_type); + + return GP_FilterResizeCubicInt_Raw(src, dst, callback); +} + +GP_Context *GP_FilterResizeCubicIntAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_ProgressCallback *callback) +{ + GP_Context *res = GP_ContextAlloc(w, h, src->pixel_type); + + if (res == NULL) + return NULL; + + if (GP_FilterResizeCubicInt_Raw(src, res, callback)) { + GP_ContextFree(res); + return NULL; + } + + return res; +} + static const char *interp_types[] = { "Nearest Neighbour", "Linear (Int)", @@ -252,213 +282,6 @@ int GP_FilterInterpolate_Cubic(const GP_Context *src, GP_Context *dst, return 0; }
-#include "GP_Cubic.h" - -#define MUL 1024 - -#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]) - -#include "core/GP_GammaCorrection.h" - -int GP_FilterInterpolate_CubicInt(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) -{ - int32_t col_r[src->w], col_g[src->w], col_b[src->w]; - 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); - - uint16_t *R_2_LIN = NULL; - uint16_t *G_2_LIN = NULL; - uint16_t *B_2_LIN = NULL; - - uint8_t *R_2_GAMMA = NULL; - uint8_t *G_2_GAMMA = NULL; - uint8_t *B_2_GAMMA = NULL; - - if (src->gamma) { - R_2_LIN = src->gamma->tables[0]->u16; - G_2_LIN = src->gamma->tables[1]->u16; - B_2_LIN = src->gamma->tables[2]->u16; - - R_2_GAMMA = src->gamma->tables[3]->u8; - G_2_GAMMA = src->gamma->tables[4]->u8; - B_2_GAMMA = src->gamma->tables[5]->u8; - } - - /* pre-generate x mapping and constants */ - int32_t xmap[dst->w][4]; - int32_t xmap_c[dst->w][4]; - - for (i = 0; i < dst->w; i++) { - float x = (1.00 * i / (dst->w - 1)) * (src->w - 1); - - xmap[i][0] = floor(x - 1); - xmap[i][1] = x; - xmap[i][2] = x + 1; - xmap[i][3] = x + 2; - - - xmap_c[i][0] = cubic_int((xmap[i][0] - x) * MUL + 0.5); - xmap_c[i][1] = cubic_int((xmap[i][1] - x) * MUL + 0.5); - xmap_c[i][2] = cubic_int((xmap[i][2] - x) * MUL + 0.5); - xmap_c[i][3] = cubic_int((xmap[i][3] - x) * MUL + 0.5); - - if (xmap[i][0] < 0) - xmap[i][0] = 0; - - if (xmap[i][3] >= (int32_t)src->w) - xmap[i][3] = src->w - 1; - } - - /* cubic resampling */ - for (i = 0; i < dst->h; i++) { - float y = (1.00 * i / (dst->h - 1)) * (src->h - 1); - int32_t cvy[4]; - int yi[4]; - - yi[0] = floor(y - 1); - yi[1] = y; - yi[2] = y + 1; - yi[3] = y + 2; - - cvy[0] = cubic_int((yi[0] - y) * MUL + 0.5); - cvy[1] = cubic_int((yi[1] - y) * MUL + 0.5); - cvy[2] = cubic_int((yi[2] - y) * MUL + 0.5); - cvy[3] = cubic_int((yi[3] - y) * MUL + 0.5); - - if (yi[0] < 0) - yi[0] = 0; - - if (yi[3] >= (int)src->h) - yi[3] = src->h - 1; - - /* Generate interpolated row */ - for (j = 0; j < src->w; j++) { - int32_t rv[4], gv[4], bv[4]; - GP_Pixel pix[4]; - - pix[0] = GP_GetPixel_Raw_24BPP(src, j, yi[0]); - pix[1] = GP_GetPixel_Raw_24BPP(src, j, yi[1]); - pix[2] = GP_GetPixel_Raw_24BPP(src, j, yi[2]); - pix[3] = GP_GetPixel_Raw_24BPP(src, j, yi[3]); - - 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]); - - - if (src->gamma) { - rv[0] = R_2_LIN[rv[0]]; - rv[1] = R_2_LIN[rv[1]]; - rv[2] = R_2_LIN[rv[2]]; - rv[3] = R_2_LIN[rv[3]]; - - gv[0] = G_2_LIN[gv[0]]; - gv[1] = G_2_LIN[gv[1]]; - gv[2] = G_2_LIN[gv[2]]; - gv[3] = G_2_LIN[gv[3]]; - - bv[0] = G_2_LIN[bv[0]]; - bv[1] = G_2_LIN[bv[1]]; - bv[2] = G_2_LIN[bv[2]]; - bv[3] = G_2_LIN[bv[3]]; - } - - MUL_I(rv, cvy); - MUL_I(gv, cvy); - MUL_I(bv, cvy); - - 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->w; j++) { - int32_t rv[4], gv[4], bv[4]; - int32_t r, g, b; - - rv[0] = col_r[xmap[j][0]]; - rv[1] = col_r[xmap[j][1]]; - rv[2] = col_r[xmap[j][2]]; - rv[3] = col_r[xmap[j][3]]; - - gv[0] = col_g[xmap[j][0]]; - gv[1] = col_g[xmap[j][1]]; - gv[2] = col_g[xmap[j][2]]; - gv[3] = col_g[xmap[j][3]]; - - bv[0] = col_b[xmap[j][0]]; - bv[1] = col_b[xmap[j][1]]; - bv[2] = col_b[xmap[j][2]]; - bv[3] = col_b[xmap[j][3]]; - - MUL_I(rv, xmap_c[j]); - MUL_I(gv, xmap_c[j]); - MUL_I(bv, xmap_c[j]); - - 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 (src->gamma) { - if (r > 1023) - r = 1023; - if (g > 1023) - g = 1023; - if (b > 1023) - b = 1023; - - if (r < 0) - r = 0; - if (g < 0) - g = 0; - if (b < 0) - b = 0; - - r = R_2_GAMMA[r]; - g = G_2_GAMMA[g]; - b = B_2_GAMMA[b]; - } else { - CLAMP(r); - CLAMP(g); - CLAMP(b); - } - - GP_Pixel pix = GP_Pixel_CREATE_RGB888((uint8_t)r, (uint8_t)g, (uint8_t)b); - GP_PutPixel_Raw_24BPP(dst, j, i, pix); - } - - if (GP_ProgressCallbackReport(callback, i, dst->h, dst->w)) - return 1; - } - - GP_ProgressCallbackDone(callback); - return 0; -} - /* * Sample row. * @@ -742,7 +565,7 @@ int GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst, case GP_INTERP_CUBIC: return GP_FilterInterpolate_Cubic(src, dst, callback); case GP_INTERP_CUBIC_INT: - return GP_FilterInterpolate_CubicInt(src, dst, callback); + return GP_FilterResizeCubicInt_Raw(src, dst, callback); }
return 1; diff --git a/libs/filters/GP_ResizeCubic.gen.c.t b/libs/filters/GP_ResizeCubic.gen.c.t new file mode 100644 index 0000000..f782b39 --- /dev/null +++ b/libs/filters/GP_ResizeCubic.gen.c.t @@ -0,0 +1,210 @@ +%% extends "filter.c.t" + +{% block descr %}Nearest Neighbour resampling{% endblock %} + +%% block body + +#include <math.h> + +#include "core/GP_Context.h" +#include "core/GP_GetPutPixel.h" +#include "core/GP_Gamma.h" +#include "core/GP_Debug.h" + +#include "GP_Cubic.h" + +#include "GP_Resize.h" + +#define MUL 1024 + +#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]) + +#define CLAMP(val, max) do { + if (val < 0) + val = 0; + if (val > max) + val = max; +} while (0) + +%% for pt in pixeltypes +%% if not pt.is_unknown() and not pt.is_palette() + +static int GP_FilterResizeCubicInt_{{ pt.name }}_Raw(const GP_Context *src, + GP_Context *dst, GP_ProgressCallback *callback) +{ + %% for c in pt.chanslist + int32_t col_{{ c[0] }}[src->w]; + %% endfor + + 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); + +{{ fetch_gamma_tables(pt, "src") }} + + /* pre-generate x mapping and constants */ + int32_t xmap[dst->w][4]; + int32_t xmap_c[dst->w][4]; + + for (i = 0; i < dst->w; i++) { + float x = (1.00 * i / (dst->w - 1)) * (src->w - 1); + + xmap[i][0] = floor(x - 1); + xmap[i][1] = x; + xmap[i][2] = x + 1; + xmap[i][3] = x + 2; + + xmap_c[i][0] = cubic_int((xmap[i][0] - x) * MUL + 0.5); + xmap_c[i][1] = cubic_int((xmap[i][1] - x) * MUL + 0.5); + xmap_c[i][2] = cubic_int((xmap[i][2] - x) * MUL + 0.5); + xmap_c[i][3] = cubic_int((xmap[i][3] - x) * MUL + 0.5); + + if (xmap[i][0] < 0) + xmap[i][0] = 0; + + if (xmap[i][2] >= (int32_t)src->w) + xmap[i][2] = src->w - 1; + + if (xmap[i][3] >= (int32_t)src->w) + xmap[i][3] = src->w - 1; + } + + /* cubic resampling */ + for (i = 0; i < dst->h; i++) { + float y = (1.00 * i / (dst->h - 1)) * (src->h - 1); + int32_t cvy[4]; + int yi[4]; + + yi[0] = floor(y - 1); + yi[1] = y; + yi[2] = y + 1; + yi[3] = y + 2; + + cvy[0] = cubic_int((yi[0] - y) * MUL + 0.5); + cvy[1] = cubic_int((yi[1] - y) * MUL + 0.5); + cvy[2] = cubic_int((yi[2] - y) * MUL + 0.5); + cvy[3] = cubic_int((yi[3] - y) * MUL + 0.5); + + if (yi[0] < 0) + yi[0] = 0; + + if (yi[2] >= (int)src->h) + yi[2] = src->h - 1; + + if (yi[3] >= (int)src->h) + yi[3] = src->h - 1; + + /* Generate interpolated row */ + for (j = 0; j < src->w; j++) { + %% for c in pt.chanslist + int32_t {{ c[0] }}v[4]; + %% endfor + GP_Pixel pix[4]; + + pix[0] = GP_GetPixel_Raw_{{ pt.pixelsize.suffix }}(src, j, yi[0]); + pix[1] = GP_GetPixel_Raw_{{ pt.pixelsize.suffix }}(src, j, yi[1]); + pix[2] = GP_GetPixel_Raw_{{ pt.pixelsize.suffix }}(src, j, yi[2]); + pix[3] = GP_GetPixel_Raw_{{ pt.pixelsize.suffix }}(src, j, yi[3]); + + %% for c in pt.chanslist + {{ c[0] }}v[0] = GP_Pixel_GET_{{ c[0] }}_{{ pt.name }}(pix[0]); + {{ c[0] }}v[1] = GP_Pixel_GET_{{ c[0] }}_{{ pt.name }}(pix[1]); + {{ c[0] }}v[2] = GP_Pixel_GET_{{ c[0] }}_{{ pt.name }}(pix[2]); + {{ c[0] }}v[3] = GP_Pixel_GET_{{ c[0] }}_{{ pt.name }}(pix[3]); + %% endfor + + if (src->gamma) { + %% for c in pt.chanslist + {{ c[0] }}v[0] = {{ c[0] }}_2_LIN[{{ c[0] }}v[0]]; + {{ c[0] }}v[1] = {{ c[0] }}_2_LIN[{{ c[0] }}v[1]]; + {{ c[0] }}v[2] = {{ c[0] }}_2_LIN[{{ c[0] }}v[2]]; + {{ c[0] }}v[3] = {{ c[0] }}_2_LIN[{{ c[0] }}v[3]]; + %% endfor + } + + %% for c in pt.chanslist + MUL_I({{ c[0] }}v, cvy); + %% endfor + + %% for c in pt.chanslist + col_{{ c[0] }}[j] = SUM_I({{ c[0] }}v); + %% endfor + } + + /* now interpolate column for new image */ + for (j = 0; j < dst->w; j++) { + %% for c in pt.chanslist + int32_t {{ c[0] }}v[4]; + int32_t {{ c[0] }}; + %% endfor + + %% for c in pt.chanslist + {{ c[0] }}v[0] = col_{{ c[0] }}[xmap[j][0]]; + {{ c[0] }}v[1] = col_{{ c[0] }}[xmap[j][1]]; + {{ c[0] }}v[2] = col_{{ c[0] }}[xmap[j][2]]; + {{ c[0] }}v[3] = col_{{ c[0] }}[xmap[j][3]]; + %% endfor + + %% for c in pt.chanslist + MUL_I({{ c[0] }}v, xmap_c[j]); + %% endfor + + %% for c in pt.chanslist + {{ c[0] }} = (SUM_I({{ c[0] }}v) + MUL*MUL/2) / MUL / MUL; + %% endfor + + if (src->gamma) { + %% for c in pt.chanslist + CLAMP({{ c[0] }}, {{ 2 ** (c[2] + 2) - 1 }}); + %% endfor + %% for c in pt.chanslist + {{ c[0] }} = {{ c[0] }}_2_GAMMA[{{ c[0] }}]; + %% endfor + } else { + %% for c in pt.chanslist + CLAMP({{ c[0] }}, {{ 2 ** c[2] - 1 }}); + %% endfor + } + + GP_Pixel pix = GP_Pixel_CREATE_{{ pt.name }}({{ expand_chanslist(pt, "(uint8_t)") }}); + GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, j, i, pix); + } + + if (GP_ProgressCallbackReport(callback, i, dst->h, dst->w)) + return 1; + } + + GP_ProgressCallbackDone(callback); + return 0; +} + +%% endif +%% endfor + +int GP_FilterResizeCubicInt_Raw(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) +{ + switch (src->pixel_type) { + %% for pt in pixeltypes + %% if not pt.is_unknown() and not pt.is_palette() + case GP_PIXEL_{{ pt.name }}: + return GP_FilterResizeCubicInt_{{ pt.name }}_Raw(src, dst, callback); + break; + %% endif + %% endfor + default: + return -1; + } +} + +%% endblock body diff --git a/libs/filters/Makefile b/libs/filters/Makefile index e07d92a..c9661e6 100644 --- a/libs/filters/Makefile +++ b/libs/filters/Makefile @@ -8,7 +8,7 @@ POINT_FILTERS=GP_Contrast.gen.c GP_Brightness.gen.c GP_Invert.gen.c ARITHMETIC_FILTERS=GP_Difference.gen.c GP_Addition.gen.c GP_Min.gen.c GP_Max.gen.c GP_Multiply.gen.c
-RESAMPLING_FILTERS=GP_ResizeNN.gen.c GP_Cubic.gen.c +RESAMPLING_FILTERS=GP_ResizeNN.gen.c GP_Cubic.gen.c GP_ResizeCubic.gen.c
GENSOURCES=GP_MirrorV.gen.c GP_Rotate.gen.c GP_FloydSteinberg.gen.c GP_HilbertPeano.gen.c $(POINT_FILTERS) $(ARITHMETIC_FILTERS) $(STATS_FILTERS) $(RESAMPLING_FILTERS) diff --git a/pylib/templates/common.c.t b/pylib/templates/common.c.t index 785174d..30f3814 100644 --- a/pylib/templates/common.c.t +++ b/pylib/templates/common.c.t @@ -13,11 +13,42 @@ /* * Converts channels to params */ -{% macro expand_chanslist(chlist) %} {{ chlist[0][0] }}{% for i in chlist %}, {{ i[0] }}{% endfor %}{% endmacro %} - +{% macro expand_chanslist(pt, pref="", suff="") %}{{ pref+pt.chanslist[0][0]+suff }}{% for c in pt.chanslist[1:] %}, {{ pref+c[0]+suff }}{% endfor %}{% endmacro %} /* * Clamps n-bits value */ %%macro clamp_val(val, bits) if ({{ val }} > {{ 2 ** bits - 1 }}) {{ val }} = {{ 2 ** bits - 1}}; %% endmacro + +{% macro gamma_in_bits(size) %}{% if size + 2 > 8 %}16{% else %}8{% endif %}{% endmacro %} +{% macro gamma_out_bits(size) %}{% if size > 8 %}16{% else %}8{% endif %}{% endmacro %} + +/* + * Prepares pointers to Gamma tables. + */ +%% macro fetch_gamma_tables(pt, ctx, pref="", suff="") + /* prepare Gamma tables */ + %% for c in pt.chanslist + uint{{ gamma_in_bits(c[2]) }}_t *{{ pref+c[0] }}_2_LIN{{ suff }} = NULL; + %% endfor + + %% for c in pt.chanslist + uint{{ gamma_out_bits(c[2]) }}_t *{{ pref+c[0] }}_2_GAMMA{{ suff }} = NULL; + %% endfor + + %% set i = 0 + if ({{ ctx }}->gamma) { + %% for c in pt.chanslist + {{ pref+c[0] }}_2_LIN{{ suff }} = {{ ctx }}->gamma->tables[{{ i }}]->u{{ gamma_in_bits(c[2]) }}; + %% set i = i + 1 + %% endfor + + %% set i = len(pt.chanslist) + %% for c in pt.chanslist + {{ pref+c[0] }}_2_GAMMA{{ suff }} = {{ ctx }}->gamma->tables[{{ i }}]->u{{ gamma_out_bits(c[2]) }}; + %% set i = i + 1 + %% endfor + } +%% endmacro +
-----------------------------------------------------------------------
Summary of changes: libs/filters/GP_Cubic.h | 6 +- libs/filters/GP_Resize.c | 239 +++++------------------------------ libs/filters/GP_ResizeCubic.gen.c.t | 210 ++++++++++++++++++++++++++++++ libs/filters/Makefile | 2 +- pylib/templates/common.c.t | 35 +++++- 5 files changed, 278 insertions(+), 214 deletions(-) create mode 100644 libs/filters/GP_ResizeCubic.gen.c.t
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.