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 43f5f45fcff837cf1f091fb9933d454e36800f3e (commit) via d09f22f7d44d377319e81eba29ef18a2bf752328 (commit) via b949577b1a210f9822c39afcbe914e9d5c5bec05 (commit) from c42e0dadc0536639298fe8d898726f565c7b2168 (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/43f5f45fcff837cf1f091fb9933d454e36800...
commit 43f5f45fcff837cf1f091fb9933d454e36800f3e Author: Cyril Hrubis metan@ucw.cz Date: Sun Jul 1 20:57:51 2012 +0200
filters: Cubic Resampling, simplify the code.
diff --git a/libs/filters/GP_ResizeCubic.gen.c.t b/libs/filters/GP_ResizeCubic.gen.c.t index 811885e..d8400d5 100644 --- a/libs/filters/GP_ResizeCubic.gen.c.t +++ b/libs/filters/GP_ResizeCubic.gen.c.t @@ -62,15 +62,10 @@ static int GP_FilterResizeCubicInt_{{ pt.name }}_Raw(const GP_Context *src, 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; + + xmap[i][0] = GP_MAX(xmap[i][0], 0); + xmap[i][2] = GP_MIN(xmap[i][2], (int)src->w - 1); + xmap[i][3] = GP_MIN(xmap[i][3], (int)src->w - 1); }
/* cubic resampling */ @@ -89,14 +84,9 @@ static int GP_FilterResizeCubicInt_{{ pt.name }}_Raw(const GP_Context *src, 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; + yi[0] = GP_MAX(yi[0], 0); + yi[2] = GP_MIN(yi[2], (int)src->h - 1); + yi[3] = GP_MIN(yi[3], (int)src->h - 1);
/* Generate interpolated row */ for (j = 0; j < src->w; j++) {
http://repo.or.cz/w/gfxprim.git/commit/d09f22f7d44d377319e81eba29ef18a2bf752...
commit d09f22f7d44d377319e81eba29ef18a2bf752328 Author: Cyril Hrubis metan@ucw.cz Date: Sun Jul 1 20:51:51 2012 +0200
core, filters: Add clamping macros.
diff --git a/include/core/GP_Clamp.h b/include/core/GP_Clamp.h new file mode 100644 index 0000000..6b6443a --- /dev/null +++ b/include/core/GP_Clamp.h @@ -0,0 +1,65 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + + /* + + Fast clamping. + + */ + +#ifndef CORE_GP_CLAMP_H +#define CORE_GP_CLAMP_H + +#ifdef __GNUC__ +# define GP_IS_CONSTANT(x) __builtin_constant_p(x) +#else +# define GP_IS_CONSTANT(x) 0 +#endif + +#define GP_CLAMP_GENERIC(val, min, max) ({ + typeof(val) _val = (val); + typeof(max) _max = (max); + typeof(min) _min = (min); + _val = _val < _min ? _min : _val; + _val = _val > _max ? _max : _val; + _val; +}) + +/* + * Special case clamping for 8 bit values, which is sometimes faster. + * + * We first look if the number needs to be clamped and then do accordingly. + */ +#define GP_CLAMP_INT_0_255(val) ({ + typeof(val) _val = (val); + typeof(val) _mask = ~0xff; + (_val & _mask) ? (_val < 0 ? 0 : 255) : _val; +}) + +#define GP_CLAMP(val, min, max) ({ + (GP_IS_CONSTANT(min) && GP_IS_CONSTANT(max) && + min == 0 && max == 255) ? + GP_CLAMP_INT_0_255(val) : + GP_CLAMP_GENERIC(val, min, max); +}) + +#endif /* CORE_GP_CLAMP_H */ diff --git a/libs/filters/GP_Linear.c b/libs/filters/GP_Linear.c index 27575a6..b6e5983 100644 --- a/libs/filters/GP_Linear.c +++ b/libs/filters/GP_Linear.c @@ -22,6 +22,7 @@
#include "core/GP_Context.h" #include "core/GP_GetPutPixel.h" +#include "core/GP_Clamp.h"
#include "core/GP_Debug.h"
@@ -29,13 +30,6 @@
#define MUL 1024
-#define CLAMP(val) do { - if (val > 255) - val = 255; - if (val < 0) - val = 0; -} while (0) - int GP_FilterHLinearConvolution_Raw(const GP_Context *src, GP_Coord x_src, GP_Coord y_src, GP_Size w_src, GP_Size h_src, @@ -115,9 +109,9 @@ int GP_FilterHLinearConvolution_Raw(const GP_Context *src, b /= ikern_div; /* and clamp just to be extra sure */ - CLAMP(r); - CLAMP(g); - CLAMP(b); + r = GP_CLAMP(r, 0, 255); + g = GP_CLAMP(g, 0, 255); + b = GP_CLAMP(b, 0, 255);
GP_PutPixel_Raw_24BPP(dst, x_dst + x, y_dst + y, GP_Pixel_CREATE_RGB888(r, g, b)); @@ -210,9 +204,9 @@ int GP_FilterVLinearConvolution_Raw(const GP_Context *src, b /= ikern_div; /* and clamp just to be extra sure */ - CLAMP(r); - CLAMP(g); - CLAMP(b); + r = GP_CLAMP(r, 0, 255); + g = GP_CLAMP(g, 0, 255); + b = GP_CLAMP(b, 0, 255);
GP_PutPixel_Raw_24BPP(dst, x_dst + x, y_dst + y, GP_Pixel_CREATE_RGB888(r, g, b)); @@ -303,18 +297,8 @@ int GP_FilterLinearConvolution_Raw(const GP_Context *src, int xi = x_src + i - kw/2; int yi = y_src + y + j - kh/2;
- if (xi < 0) - xi = 0; - - if (xi > (int)src->w - 1) - xi = src->w - 1; - - if (yi < 0) - yi = 0; - - if (yi > (int)src->h - 1) - yi = src->h - 1; - + xi = GP_CLAMP(xi, 0, (int)src->w - 1); + yi = GP_CLAMP(yi, 0, (int)src->h - 1); pix = GP_GetPixel_Raw_24BPP(src, xi, yi);
@@ -333,17 +317,8 @@ int GP_FilterLinearConvolution_Raw(const GP_Context *src, int xi = x_src + x + kw/2; int yi = y_src + y + j - kh/2; - if (xi < 0) - xi = 0; - - if (xi > (int)src->w - 1) - xi = src->w - 1; - - if (yi < 0) - yi = 0; - - if (yi > (int)src->h - 1) - yi = src->h - 1; + xi = GP_CLAMP(xi, 0, (int)src->w - 1); + yi = GP_CLAMP(yi, 0, (int)src->h - 1);
pix = GP_GetPixel_Raw_24BPP(src, xi, yi);
@@ -374,18 +349,9 @@ int GP_FilterLinearConvolution_Raw(const GP_Context *src, b /= kern_div;
/* and clamp just to be extra sure */ - 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; + r = GP_CLAMP((int)r, 0, 255); + g = GP_CLAMP((int)g, 0, 255); + b = GP_CLAMP((int)b, 0, 255);
pix = GP_Pixel_CREATE_RGB888((uint32_t)r, (uint32_t)g, (uint32_t)b);
diff --git a/libs/filters/GP_ResizeCubic.gen.c.t b/libs/filters/GP_ResizeCubic.gen.c.t index 901e253..811885e 100644 --- a/libs/filters/GP_ResizeCubic.gen.c.t +++ b/libs/filters/GP_ResizeCubic.gen.c.t @@ -9,6 +9,7 @@ #include "core/GP_Context.h" #include "core/GP_GetPutPixel.h" #include "core/GP_Gamma.h" +#include "core/GP_Clamp.h" #include "core/GP_Debug.h"
#include "GP_Cubic.h" @@ -27,13 +28,6 @@ #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()
@@ -165,14 +159,14 @@ static int GP_FilterResizeCubicInt_{{ pt.name }}_Raw(const GP_Context *src,
if (src->gamma) { %% for c in pt.chanslist - CLAMP({{ c[0] }}, {{ 2 ** (c[2] + 2) - 1 }}); + {{ c[0] }} = GP_CLAMP_GENERIC({{ c[0] }}, 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 }}); + {{ c[0] }} = GP_CLAMP_GENERIC({{ c[0] }}, 0, {{ 2 ** c[2] - 1 }}); %% endfor }
http://repo.or.cz/w/gfxprim.git/commit/b949577b1a210f9822c39afcbe914e9d5c5be...
commit b949577b1a210f9822c39afcbe914e9d5c5bec05 Author: Cyril Hrubis metan@ucw.cz Date: Sun Jul 1 18:22:55 2012 +0200
filters: Move gaussian blur into separate file.
diff --git a/include/filters/GP_Filters.h b/include/filters/GP_Blur.h similarity index 57% copy from include/filters/GP_Filters.h copy to include/filters/GP_Blur.h index 3b0a95f..22694bc 100644 --- a/include/filters/GP_Filters.h +++ b/include/filters/GP_Blur.h @@ -16,50 +16,49 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos * - * jiri.bluebear.dluhos@gmail.com * - * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
/*
- GP_Context filters. + Gaussian blur implementation.
*/
-#ifndef GP_FILTERS_H -#define GP_FILTERS_H - -/* Filter per channel parameter passing interface */ -#include "filters/GP_FilterParam.h" - -/* Point filters, brightness, contrast ... */ -#include "filters/GP_Point.h" - -/* Addition, difference, min, max ... */ -#include "filters/GP_Arithmetic.h" - -/* Histograms, ... */ -#include "filters/GP_Stats.h" - -/* Image rotations (90 180 270 grads) and mirroring */ -#include "filters/GP_Rotate.h" +#ifndef FILTERS_GP_BLUR_H +#define FILTERS_GP_BLUR_H
-/* Linear convolution Raw API */ -#include "filters/GP_Linear.h" +#include "GP_Filter.h"
-/* Convolution filters */ -#include "filters/GP_Convolution.h" - -/* Image scaling (resampling) */ -#include "filters/GP_Resize.h" - -/* Bitmap dithering */ -#include "filters/GP_Dither.h" +/* + * Gaussian blur + * + * The sigma parameters defines the blur radii in horizontal and vertical + * direction. + * + * Internaly this is implemented as separable linear filter (calls vertical and + * horizontal convolution with generated gaussian kernel). + * + * This variant could work in-place so it's perectly okay to call + * + * GP_FilterGaussianBlur_Raw(context, context, ...); + */ +int GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst, + float sigma_x, float sigma_y, + GP_ProgressCallback *callback);
-/* Laplace based filters */ -#include "filters/GP_Laplace.h" +/* + * Gaussian blur. + * + * If dst is NULL, new bitmap is allocated. + * + * This variant could work in-place. + * + * Returns pointer to destination bitmap or NULL if allocation failed. + */ +GP_Context *GP_FilterGaussianBlur(const GP_Context *src, GP_Context *dst, + float sigma_x, float sigma_y, + GP_ProgressCallback *callback);
-#endif /* GP_FILTERS_H */ +#endif /* FILTERS_GP_BLUR_H */ diff --git a/include/filters/GP_Filters.h b/include/filters/GP_Filters.h index 3b0a95f..1bcc6f8 100644 --- a/include/filters/GP_Filters.h +++ b/include/filters/GP_Filters.h @@ -53,6 +53,9 @@ /* Convolution filters */ #include "filters/GP_Convolution.h"
+/* Blur filters */ +#include "filters/GP_Blur.h" + /* Image scaling (resampling) */ #include "filters/GP_Resize.h"
diff --git a/libs/filters/GP_Blur.c b/libs/filters/GP_Blur.c new file mode 100644 index 0000000..22b99fd --- /dev/null +++ b/libs/filters/GP_Blur.c @@ -0,0 +1,143 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + +#include <math.h> + +#include "core/GP_Debug.h" + +#include "GP_Linear.h" + +#include "GP_Blur.h" + +static inline unsigned int gaussian_kernel_size(float sigma) +{ + int center = 3 * sigma; + + return 2 * center + 1; +} + +static inline float gaussian_kernel_init(float sigma, float *kernel) +{ + int i, center = 3 * sigma; + int N = 2 * center + 1; + float ret = 0; + + double sigma2 = sigma * sigma; + + for (i = 0; i < N; i++) { + double r = center - i; + kernel[i] = exp(-0.5 * (r * r) / sigma2); + ret += kernel[i]; + } + + return ret; +} + +static int gaussian_callback_horiz(GP_ProgressCallback *self) +{ + GP_ProgressCallback *callback = self->priv; + + callback->percentage = self->percentage / 2; + return callback->callback(callback); +} + +static int gaussian_callback_vert(GP_ProgressCallback *self) +{ + GP_ProgressCallback *callback = self->priv; + + callback->percentage = self->percentage / 2 + 50; + return callback->callback(callback); +} + +int GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst, + float sigma_x, float sigma_y, + GP_ProgressCallback *callback) +{ + unsigned int size_x = gaussian_kernel_size(sigma_x); + unsigned int size_y = gaussian_kernel_size(sigma_y); + + GP_DEBUG(1, "Gaussian blur sigma_x=%2.3f sigma_y=%2.3f kernel %ix%i image %ux%u", + sigma_x, sigma_y, size_x, size_y, src->w, src->h); + + GP_ProgressCallback *new_callback = NULL; + + GP_ProgressCallback gaussian_callback = { + .callback = gaussian_callback_horiz, + .priv = callback + }; + + if (callback != NULL) + new_callback = &gaussian_callback; + + /* compute kernel and apply in horizontal direction */ + if (sigma_x > 0) { + float kernel_x[size_x]; + float sum = gaussian_kernel_init(sigma_x, kernel_x); + + if (GP_FilterHLinearConvolution_Raw(src, 0, 0, src->w, src->h, + dst, 0, 0, kernel_x, size_x, + sum, new_callback)) + return 1; + } + + if (new_callback != NULL) + new_callback->callback = gaussian_callback_vert; + + /* compute kernel and apply in vertical direction */ + if (sigma_y > 0) { + float kernel_y[size_y]; + float sum = gaussian_kernel_init(sigma_y, kernel_y); + + if (GP_FilterVLinearConvolution_Raw(dst, 0, 0, src->w, src->h, + dst, 0, 0, kernel_y, size_y, + sum, new_callback)) + return 1; + } + + GP_ProgressCallbackDone(callback); + return 0; +} + +GP_Context *GP_FilterGaussianBlur(const GP_Context *src, GP_Context *dst, + float sigma_x, float sigma_y, + GP_ProgressCallback *callback) +{ + /* TODO: templatetize */ + if (src->pixel_type != GP_PIXEL_RGB888) + return NULL; + + if (dst == NULL) { + dst = GP_ContextCopy(src, 0); + + if (dst == NULL) + return NULL; + } else { + GP_ASSERT(src->pixel_type == dst->pixel_type, + "The src and dst pixel types must match"); + GP_ASSERT(src->w <= dst->w && src->h <= dst->h, + "Destination is not big enough"); + } + + GP_FilterGaussianBlur_Raw(src, dst, sigma_x, sigma_y, callback); + + return dst; +} diff --git a/libs/filters/GP_Linear.c b/libs/filters/GP_Linear.c index 54ec6c9..27575a6 100644 --- a/libs/filters/GP_Linear.c +++ b/libs/filters/GP_Linear.c @@ -20,8 +20,6 @@ * * *****************************************************************************/
-#include <math.h> - #include "core/GP_Context.h" #include "core/GP_GetPutPixel.h"
@@ -29,120 +27,6 @@
#include "GP_Linear.h"
-static inline unsigned int gaussian_kernel_size(float sigma) -{ - int center = 3 * sigma; - - return 2 * center + 1; -} - -static inline float gaussian_kernel_init(float sigma, float *kernel) -{ - int i, center = 3 * sigma; - int N = 2 * center + 1; - float ret = 0; - - double sigma2 = sigma * sigma; - - for (i = 0; i < N; i++) { - double r = center - i; - kernel[i] = exp(-0.5 * (r * r) / sigma2); - ret += kernel[i]; - } - - return ret; -} - -static int gaussian_callback_horiz(GP_ProgressCallback *self) -{ - GP_ProgressCallback *callback = self->priv; - - callback->percentage = self->percentage / 2; - return callback->callback(callback); -} - -static int gaussian_callback_vert(GP_ProgressCallback *self) -{ - GP_ProgressCallback *callback = self->priv; - - callback->percentage = self->percentage / 2 + 50; - return callback->callback(callback); -} - -int GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst, - float sigma_x, float sigma_y, - GP_ProgressCallback *callback) -{ - unsigned int size_x = gaussian_kernel_size(sigma_x); - unsigned int size_y = gaussian_kernel_size(sigma_y); - - GP_DEBUG(1, "Gaussian blur sigma_x=%2.3f sigma_y=%2.3f kernel %ix%i image %ux%u", - sigma_x, sigma_y, size_x, size_y, src->w, src->h); - - GP_ProgressCallback *new_callback = NULL; - - GP_ProgressCallback gaussian_callback = { - .callback = gaussian_callback_horiz, - .priv = callback - }; - - if (callback != NULL) - new_callback = &gaussian_callback; - - /* compute kernel and apply in horizontal direction */ - if (sigma_x > 0) { - float kernel_x[size_x]; - float sum = gaussian_kernel_init(sigma_x, kernel_x); - - if (GP_FilterHLinearConvolution_Raw(src, 0, 0, src->w, src->h, - dst, 0, 0, kernel_x, size_x, - sum, new_callback)) - return 1; - } - - if (new_callback != NULL) - new_callback->callback = gaussian_callback_vert; - - /* compute kernel and apply in vertical direction */ - if (sigma_y > 0) { - float kernel_y[size_y]; - float sum = gaussian_kernel_init(sigma_y, kernel_y); - - if (GP_FilterVLinearConvolution_Raw(dst, 0, 0, src->w, src->h, - dst, 0, 0, kernel_y, size_y, - sum, new_callback)) - return 1; - } - - GP_ProgressCallbackDone(callback); - return 0; -} - -GP_Context *GP_FilterGaussianBlur(const GP_Context *src, GP_Context *dst, - float sigma_x, float sigma_y, - GP_ProgressCallback *callback) -{ - /* TODO: templatetize */ - if (src->pixel_type != GP_PIXEL_RGB888) - return NULL; - - if (dst == NULL) { - dst = GP_ContextCopy(src, 0); - - if (dst == NULL) - return NULL; - } else { - GP_ASSERT(src->pixel_type == dst->pixel_type, - "The src and dst pixel types must match"); - GP_ASSERT(src->w <= dst->w && src->h <= dst->h, - "Destination is not big enough"); - } - - GP_FilterGaussianBlur_Raw(src, dst, sigma_x, sigma_y, callback); - - return dst; -} - #define MUL 1024
#define CLAMP(val) do { -----------------------------------------------------------------------
Summary of changes: include/{loaders/GP_TmpFile.h => core/GP_Clamp.h} | 55 ++++--- include/filters/{GP_Laplace.h => GP_Blur.h} | 47 +++--- include/filters/GP_Filters.h | 3 + libs/filters/GP_Blur.c | 143 +++++++++++++++++ libs/filters/GP_Linear.c | 178 ++------------------- libs/filters/GP_ResizeCubic.gen.c.t | 36 ++--- 6 files changed, 226 insertions(+), 236 deletions(-) copy include/{loaders/GP_TmpFile.h => core/GP_Clamp.h} (60%) copy include/filters/{GP_Laplace.h => GP_Blur.h} (64%) create mode 100644 libs/filters/GP_Blur.c
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.