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 8b760eccced962d0cb0549dee86778454483671a (commit) via 4886a093e1a9d194c8f92da783afd21ec58c5940 (commit) via 8815a10ac7ad2cc177dfc732620c8b9dad31c559 (commit) via 80c1b9e8fa6cd34760429146757061a0b1884025 (commit) via 97642c5d7b2f345498d28ea7ce843bb7a3b9e838 (commit) from 2dd37fda71656537c85e16407173aec2ab2db70a (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/8b760eccced962d0cb0549dee867784544836...
commit 8b760eccced962d0cb0549dee86778454483671a Merge: 4886a09 2dd37fd Author: Cyril Hrubis metan@ucw.cz Date: Tue Nov 22 22:59:33 2011 +0100
Merge ssh://repo.or.cz/srv/git/gfxprim
http://repo.or.cz/w/gfxprim.git/commit/4886a093e1a9d194c8f92da783afd21ec58c5...
commit 4886a093e1a9d194c8f92da783afd21ec58c5940 Author: Cyril Hrubis metan@ucw.cz Date: Tue Nov 22 22:55:59 2011 +0100
filters: Add general point (but slow) filter + fixes.
diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c index e6ca749..2a9ec43 100644 --- a/demos/grinder/grinder.c +++ b/demos/grinder/grinder.c @@ -266,7 +266,7 @@ static GP_RetCode mirror(GP_Context **c, const char *params)
static struct param bright_params[] = { {"inc", PARAM_INT, "brightness increment", NULL, NULL}, - {"chann", PARAM_STR, "channel name {R, G, B, A, V, ...}", NULL, NULL}, + {"chann", PARAM_STR, "Channel name {R, G, B, A, V, ...}", NULL, NULL}, {NULL, 0, NULL, NULL, NULL} };
@@ -291,7 +291,7 @@ static GP_RetCode bright(GP_Context **c, const char *params) GP_FilterParam *param = GP_FilterParamChannel(filter_params, chann); if (param == NULL) { - print_error("bright: invalid channel name"); + print_error("bright: Invalid channel name"); return GP_EINVAL; }
@@ -308,7 +308,7 @@ static GP_RetCode bright(GP_Context **c, const char *params)
static struct param contrast_params[] = { {"mul", PARAM_FLOAT, "contrast (1.5 = +50%, 0.5 = -50%)", NULL, NULL}, - {"chann", PARAM_STR, "channel name {R, G, B, A, V, ...}", NULL, NULL}, + {"chann", PARAM_STR, "Channel name {R, G, B, A, V, ...}", NULL, NULL}, {NULL, 0, NULL, NULL, NULL} };
@@ -333,7 +333,7 @@ static GP_RetCode contrast(GP_Context **c, const char *params) GP_FilterParam *param = GP_FilterParamChannel(filter_params, chann); if (param == NULL) { - print_error("contrast: invalid channel name"); + print_error("contrast: Invalid channel name"); return GP_EINVAL; }
@@ -498,6 +498,68 @@ static GP_RetCode save_png(GP_Context **c, const char *params) return GP_ESUCCESS; }
+static struct param add_noise_params[] = { + {"percents", PARAM_FLOAT, "Percents of noise to add", NULL, NULL}, + {"chann", PARAM_STR, "Channel name {R, G, B, A, V, ...}", NULL, NULL}, + {NULL, 0, NULL, NULL, NULL} +}; + +static uint32_t add_noise_op(uint32_t val, uint8_t bits, GP_FilterParam *param) +{ + float perc; + int max = (1<<bits) - 1; + int ret; + + perc = param->val.f; + + ret = val * (1 - perc) + (random() % max) * perc; + + if (ret < 0) + ret = 0; + + if (ret > max) + ret = max; + + return ret; +} + +static uint32_t no_op(uint32_t val) +{ + return val; +} + +static GP_RetCode add_noise(GP_Context **c, const char *params) +{ + float percents = 0; + char *chann = NULL; + + if (param_parse(params, add_noise_params, "add_noise", param_err, &percents, &chann)) + return GP_EINVAL; + + GP_FILTER_PARAMS((*c)->pixel_type, priv); + GP_FilterParamSetFloatAll(priv, percents/100); + GP_FILTER_PARAMS((*c)->pixel_type, op_callbacks); + + if (chann == NULL) { + GP_FilterParamSetPtrAll(op_callbacks, add_noise_op); + } else { + GP_FilterParam *param = GP_FilterParamChannel(op_callbacks, chann); + + if (param == NULL) { + print_error("add_noise: Invalid channel name"); + return GP_EINVAL; + } + + + GP_FilterParamSetPtrAll(op_callbacks, no_op); + param->val.ptr = add_noise_op; + } + + GP_FilterPoint(*c, *c, op_callbacks, priv, progress_callback); + + return GP_ESUCCESS; +} + /* filters */
struct filter { @@ -508,18 +570,19 @@ struct filter { };
static struct filter filter_table[] = { - {"rotate", "rotate image", rotate_params, rotate}, - {"mirror", "mirror vertically/horizontally", mirror_params, mirror}, - {"scale", "scale image to given width and height", scale_params, scale}, - {"resize", "resize image by given ratio", resize_params, resize}, - {"bright", "alter image brightness", bright_params, bright}, - {"contrast", "alter image contrast", contrast_params, contrast}, - {"invert", "inverts image", invert_params, invert}, - {"blur", "gaussian blur", blur_params, blur}, - {"dither", "dithers bitmap", dither_params, dither}, - {"jpg", "save jpg image", save_jpg_params, save_jpg}, - {"png", "save png image", save_png_params, save_png}, - {NULL, NULL, NULL, NULL} + {"rotate", "rotate image", rotate_params, rotate}, + {"mirror", "mirror vertically/horizontally", mirror_params, mirror}, + {"scale", "scale image to given width and height", scale_params, scale}, + {"resize", "resize image by given ratio", resize_params, resize}, + {"bright", "alter image brightness", bright_params, bright}, + {"contrast", "alter image contrast", contrast_params, contrast}, + {"invert", "inverts image", invert_params, invert}, + {"add_noise", "adds noise", add_noise_params, add_noise}, + {"blur", "gaussian blur", blur_params, blur}, + {"dither", "dithers bitmap", dither_params, dither}, + {"jpg", "save jpg image", save_jpg_params, save_jpg}, + {"png", "save png image", save_png_params, save_png}, + {NULL, NULL, NULL, NULL} };
static struct filter *get_filter(const char *name) diff --git a/include/filters/GP_FilterParam.h b/include/filters/GP_FilterParam.h index dbf9749..d073305 100644 --- a/include/filters/GP_FilterParam.h +++ b/include/filters/GP_FilterParam.h @@ -104,4 +104,16 @@ void GP_FilterParamSetIntAll(GP_FilterParam params[], void GP_FilterParamSetFloatAll(GP_FilterParam params[], float val);
+/* + * Sets all values to unsigned integer value. + */ +void GP_FilterParamSetUIntAll(GP_FilterParam params[], + uint32_t val); + +/* + * Sets all values to pointer value. + */ +void GP_FilterParamSetPtrAll(GP_FilterParam params[], + void *ptr); + #endif /* FILTERS_GP_FILTER_PARAM_H */ diff --git a/include/filters/GP_Point.h b/include/filters/GP_Point.h index e6aaeda..1ab3756 100644 --- a/include/filters/GP_Point.h +++ b/include/filters/GP_Point.h @@ -71,4 +71,17 @@ int GP_FilterInvert_Raw(const GP_Context *src, GP_Context *dst, GP_Context *GP_FilterInvert(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback);
+/* + * Generic slow point filter. + * + * The filter_callback[] is expected to be filled with pointers + * to functions of type uint32_t (*func)(uint32_t chan_val, uint8_t chan_size, GP_FilterParam *priv) + * + * The priv[] is free for your use and corresponding + */ +GP_Context *GP_FilterPoint(const GP_Context *src, GP_Context *dst, + GP_FilterParam filter_callback[], + GP_FilterParam priv[], + GP_ProgressCallback *callback); + #endif /* FILTERS_GP_POINT_H */ diff --git a/libs/filters/GP_Brightness.gen.c.t b/libs/filters/GP_Brightness.gen.c.t index adf0642..b0fa776 100644 --- a/libs/filters/GP_Brightness.gen.c.t +++ b/libs/filters/GP_Brightness.gen.c.t @@ -9,24 +9,24 @@ Brightness filters -- Increments color channel(s) by a fixed value. {{ filter_include() }}
%% macro filter_op(chann_name, chann_size) -{{ chann_name }} = {{ chann_name }} + {{ chann_name }}_i; +{{ chann_name }} = {{ chann_name }} + {{ chann_name }}_inc; {{ filter_clamp_val(chann_name, chann_size) }} %% endmacro
/* * Generated brightness filters. */ -%% call(pt) filter_point_per_channel('Brightness', 'GP_FilterParam params[]', filter_op) -{{ filter_params(pt, 'params', 'int32_t', 'i') }} +%% call(pt) filter_point_per_channel('Brightness', 'GP_FilterParam incs[]', filter_op) +{{ filter_params(pt, 'incs', 'int32_t ', '_inc', 'i') }} %% endcall
/* * Generated constrast filters for pixels with one channel. */ -%% call(ps) filter_point_per_bpp('Brightness', 'GP_FilterParam params[]', filter_op) -{{ filter_param(ps, 'params', 'int32_t', 'i') }} +%% call(ps) filter_point_per_bpp('Brightness', 'GP_FilterParam incs[]', filter_op) +{{ filter_param(ps, 'incs', 'int32_t ', '_inc', 'i') }} %% endcall
-{{ filter_functions('Brightness', 'GP_FilterParam params[]', 'params') }} +{{ filter_functions('Brightness', 'GP_FilterParam incs[]', 'incs') }}
%% endblock body diff --git a/libs/filters/GP_Contrast.gen.c.t b/libs/filters/GP_Contrast.gen.c.t index abbb0c3..3153db2 100644 --- a/libs/filters/GP_Contrast.gen.c.t +++ b/libs/filters/GP_Contrast.gen.c.t @@ -9,24 +9,24 @@ Contrast filters -- Multiply color channel(s) by a fixed float value. {{ filter_include() }}
%% macro filter_op(chan_name, chan_size) -{{ chan_name }} = {{ chan_name }} * {{ chan_name }}_f + 0.5; +{{ chan_name }} = {{ chan_name }} * {{ chan_name }}_mul + 0.5; {{ filter_clamp_val(chan_name, chan_size) }} %% endmacro
/* * Generated contrast filters for pixels with several channels. */ -%% call(pt) filter_point_per_channel('Contrast', 'GP_FilterParam params[]', filter_op) -{{ filter_params(pt, 'params', 'float', 'f') }} +%% call(pt) filter_point_per_channel('Contrast', 'GP_FilterParam muls[]', filter_op) +{{ filter_params(pt, 'muls', 'float ', '_mul', 'f') }} %% endcall
/* * Generated constrast filters for pixels with one channel. */ -%% call(ps) filter_point_per_bpp('Contrast', 'GP_FilterParam params[]', filter_op) -{{ filter_param(ps, 'params', 'float', 'f') }} +%% call(ps) filter_point_per_bpp('Contrast', 'GP_FilterParam muls[]', filter_op) +{{ filter_param(ps, 'muls', 'float ', '_mul', 'f') }} %% endcall
-{{ filter_functions('Contrast', 'GP_FilterParam params[]', 'params') }} +{{ filter_functions('Contrast', 'GP_FilterParam muls[]', 'muls') }}
%% endblock body diff --git a/libs/filters/GP_FilterParam.c b/libs/filters/GP_FilterParam.c index 4277df7..c5ef345 100644 --- a/libs/filters/GP_FilterParam.c +++ b/libs/filters/GP_FilterParam.c @@ -123,3 +123,21 @@ void GP_FilterParamSetFloatAll(GP_FilterParam params[], for (i = 0; params[i].channel_name[0] != '0'; i++) params[i].val.f = val; } + +void GP_FilterParamSetUIntAll(GP_FilterParam params[], + uint32_t val) +{ + unsigned int i; + + for (i = 0; params[i].channel_name[0] != '0'; i++) + params[i].val.ui = val; +} + +void GP_FilterParamSetPtrAll(GP_FilterParam params[], + void *ptr) +{ + unsigned int i; + + for (i = 0; params[i].channel_name[0] != '0'; i++) + params[i].val.ptr = ptr; +} diff --git a/libs/filters/GP_Point.gen.c.t b/libs/filters/GP_Point.gen.c.t new file mode 100644 index 0000000..bd41579 --- /dev/null +++ b/libs/filters/GP_Point.gen.c.t @@ -0,0 +1,35 @@ +%% extends "filter.point.c.t" + +%% block descr +Point filters -- General point filter. +%% endblock + +%% block body + +{{ filter_include() }} + +typedef uint32_t (*func)(uint32_t, uint8_t, GP_FilterParam *priv); + +%% macro filter_op(chan_name, chan_size) +{{ chan_name }} = {{ chan_name }}_func({{ chan_name }}, {{ chan_size }}, {{ chan_name }}_priv); +%% endmacro + +/* + * Generated point filters for pixels with several channels. + */ +%% call(pt) filter_point_per_channel('Point', 'GP_FilterParam filter_callbacks[], GP_FilterParam priv[]', filter_op) +{{ filter_params(pt, 'filter_callbacks', 'func ', '_func', 'ptr') }} +{{ filter_params_raw(pt, 'priv', '_priv') }} +%% endcall + +/* + * Generated point filters for pixels with one channel. + */ +%% call(ps) filter_point_per_bpp('Point', 'GP_FilterParam filter_callbacks[], GP_FilterParam priv[]', filter_op) +{{ filter_param(ps, 'filter_callbacks', 'func ', '_func', 'ptr') }} +{{ filter_param_raw(ps, 'priv', '_priv') }} +%% endcall + +{{ filter_functions('Point', 'GP_FilterParam filter_callbacks[], GP_FilterParam priv[]', 'filter_callbacks, priv') }} + +%% endblock body diff --git a/libs/filters/Makefile b/libs/filters/Makefile index 2b4cdb6..3188e17 100644 --- a/libs/filters/Makefile +++ b/libs/filters/Makefile @@ -1,5 +1,5 @@ TOPDIR=../.. -GENSOURCES=GP_Contrast.gen.c GP_Brightness.gen.c GP_Invert.gen.c +GENSOURCES=GP_Contrast.gen.c GP_Brightness.gen.c GP_Invert.gen.c GP_Point.gen.c GP_MirrorV.gen.c GP_Rotate.gen.c GP_Dither.gen.c GENHEADERS= CSOURCES=$(filter-out $(wildcard *.gen.c),$(wildcard *.c)) diff --git a/pylib/templates/filter.point.c.t b/pylib/templates/filter.point.c.t index 02240ee..750c448 100644 --- a/pylib/templates/filter.point.c.t +++ b/pylib/templates/filter.point.c.t @@ -27,12 +27,21 @@ /* * Load parameters from params structure into variables */ -%% macro filter_params(pt, params, c_type, id) +%% macro filter_params(pt, params, c_type, suffix, id) GP_ASSERT(GP_FilterParamCheckPixelType({{ params }}, GP_PIXEL_{{ pt.name }}) == 0, "Invalid params channels for context pixel type"); %% for chann in pt.chanslist - {{ c_type }} {{ chann[0] }}_{{ id }} = (GP_FilterParamChannel({{ params }}, "{{ chann[0] }}"))->val.{{ id }}; + {{ c_type }}{{ chann[0] }}{{ suffix }} = (GP_FilterParamChannel({{ params }}, "{{ chann[0] }}"))->val.{{ id }}; + %% endfor +%% endmacro + +%% macro filter_params_raw(pt, params, suffix) + GP_ASSERT(GP_FilterParamCheckPixelType({{ params }}, GP_PIXEL_{{ pt.name }}) == 0, + "Invalid params channels for context pixel type"); + + %% for chann in pt.chanslist + GP_FilterParam *{{ chann[0] }}{{ suffix }} = GP_FilterParamChannel({{ params }}, "{{ chann[0] }}"); %% endfor %% endmacro
@@ -42,7 +51,7 @@ %% macro filter_point_per_channel(name, opts="", filter_op) %% for pt in pixeltypes %% if not pt.is_unknown() and len(pt.chanslist) > 1 -int GP_Filter{{ name }}_{{ pt.name }}(const GP_Context *src, GP_Context *dst, +static int GP_Filter{{ name }}_{{ pt.name }}(const GP_Context *src, GP_Context *dst, {{ maybe_opts2(opts) }}GP_ProgressCallback *callback) { {{ caller(pt) }} @@ -79,11 +88,18 @@ int GP_Filter{{ name }}_{{ pt.name }}(const GP_Context *src, GP_Context *dst, /* * Load parameters from params structure into variable */ -%% macro filter_param(ps, params, c_type, val) +%% macro filter_param(ps, params, c_type, suffix, id) + GP_ASSERT(GP_FilterParamChannels({{ params }}) != 1, + "Expected only one channel"); + + {{ c_type }}pix{{ suffix }} = {{ params }}[0].val.{{ id }}; +%% endmacro + +%% macro filter_param_raw(ps, params, suffix) GP_ASSERT(GP_FilterParamChannels({{ params }}) != 1, "Expected only one channel");
- {{ c_type }} pix_{{ val }} = params[0].val.{{ val }}; + GP_FilterParam *pix{{ suffix }} = &{{ params }}[0]; %% endmacro
/* @@ -92,7 +108,7 @@ int GP_Filter{{ name }}_{{ pt.name }}(const GP_Context *src, GP_Context *dst, %% macro filter_point_per_bpp(name, opts="", filter_op) %% for ps in pixelsizes %% if ps.size <= 8 and ps.size > 1 -int GP_Filter{{ name }}_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst, +static int GP_Filter{{ name }}_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst, {{ maybe_opts2(opts) }}GP_ProgressCallback *callback) { {{ caller(ps) }} @@ -132,6 +148,7 @@ int GP_Filter{{ name }}_Raw(const GP_Context *src, GP_Context *dst{{ maybe_opts( %% if pt.is_unknown() or pt.pixelsize.size < 2 return 1; %% elif len(pt.chanslist) == 1: + //TODO: BITENDIAN return GP_Filter{{ name }}_{{ pt.pixelsize.suffix }}(src, dst{{ maybe_opts(params) }}, callback); %% else return GP_Filter{{ name }}_{{ pt.name }}(src, dst{{ maybe_opts(params) }}, callback);
http://repo.or.cz/w/gfxprim.git/commit/8815a10ac7ad2cc177dfc732620c8b9dad31c...
commit 8815a10ac7ad2cc177dfc732620c8b9dad31c559 Author: Cyril Hrubis metan@ucw.cz Date: Tue Nov 22 20:07:52 2011 +0100
grinder: Basic filter per channel support.
diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c index 97f8cd8..e6ca749 100644 --- a/demos/grinder/grinder.c +++ b/demos/grinder/grinder.c @@ -265,15 +265,17 @@ static GP_RetCode mirror(GP_Context **c, const char *params) /* brightness filter */
static struct param bright_params[] = { - {"inc", PARAM_INT, "brightness increment", NULL, NULL}, - {NULL, 0, NULL, NULL, NULL} + {"inc", PARAM_INT, "brightness increment", NULL, NULL}, + {"chann", PARAM_STR, "channel name {R, G, B, A, V, ...}", NULL, NULL}, + {NULL, 0, NULL, NULL, NULL} };
static GP_RetCode bright(GP_Context **c, const char *params) { int bright = 0; + char *chann = NULL;
- if (param_parse(params, bright_params, "bright", param_err, &bright)) + if (param_parse(params, bright_params, "bright", param_err, &bright, &chann)) return GP_EINVAL;
if (bright == 0) { @@ -282,7 +284,20 @@ static GP_RetCode bright(GP_Context **c, const char *params) }
GP_FILTER_PARAMS((*c)->pixel_type, filter_params); - GP_FilterParamSetIntAll(filter_params, bright); + + if (chann == NULL) { + GP_FilterParamSetIntAll(filter_params, bright); + } else { + GP_FilterParam *param = GP_FilterParamChannel(filter_params, chann); + + if (param == NULL) { + print_error("bright: invalid channel name"); + return GP_EINVAL; + } + + GP_FilterParamSetIntAll(filter_params, 0); + param->val.i = bright; + }
GP_FilterBrightness(*c, *c, filter_params, progress_callback);
@@ -293,14 +308,16 @@ static GP_RetCode bright(GP_Context **c, const char *params)
static struct param contrast_params[] = { {"mul", PARAM_FLOAT, "contrast (1.5 = +50%, 0.5 = -50%)", NULL, NULL}, + {"chann", PARAM_STR, "channel name {R, G, B, A, V, ...}", NULL, NULL}, {NULL, 0, NULL, NULL, NULL} };
static GP_RetCode contrast(GP_Context **c, const char *params) { float mul = 0; + char *chann = NULL;
- if (param_parse(params, contrast_params, "contrast", param_err, &mul)) + if (param_parse(params, contrast_params, "contrast", param_err, &mul, &chann)) return GP_EINVAL;
if (mul <= 0) { @@ -309,7 +326,20 @@ static GP_RetCode contrast(GP_Context **c, const char *params) } GP_FILTER_PARAMS((*c)->pixel_type, filter_params); - GP_FilterParamSetFloatAll(filter_params, mul); + + if (chann == NULL) { + GP_FilterParamSetFloatAll(filter_params, mul); + } else { + GP_FilterParam *param = GP_FilterParamChannel(filter_params, chann); + + if (param == NULL) { + print_error("contrast: invalid channel name"); + return GP_EINVAL; + } + + GP_FilterParamSetFloatAll(filter_params, 1); + param->val.f = mul; + }
GP_FilterContrast(*c, *c, filter_params, progress_callback);
http://repo.or.cz/w/gfxprim.git/commit/80c1b9e8fa6cd34760429146757061a0b1884...
commit 80c1b9e8fa6cd34760429146757061a0b1884025 Author: Cyril Hrubis metan@ucw.cz Date: Tue Nov 22 19:57:55 2011 +0100
build: Add more generated files into .gitignore
diff --git a/.gitignore b/.gitignore index 1d500c6..52f0d89 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ *.swp libGP.so* libGP.a - +config.h +config.gen.mk
http://repo.or.cz/w/gfxprim.git/commit/97642c5d7b2f345498d28ea7ce843bb7a3b9e...
commit 97642c5d7b2f345498d28ea7ce843bb7a3b9e838 Author: Cyril Hrubis metan@ucw.cz Date: Tue Nov 22 19:56:56 2011 +0100
filters: Add per channel parameter passing support.
diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c index 6f86e69..97f8cd8 100644 --- a/demos/grinder/grinder.c +++ b/demos/grinder/grinder.c @@ -281,7 +281,10 @@ static GP_RetCode bright(GP_Context **c, const char *params) return GP_EINVAL; }
- GP_FilterBrightness(*c, *c, bright, progress_callback); + GP_FILTER_PARAMS((*c)->pixel_type, filter_params); + GP_FilterParamSetIntAll(filter_params, bright); + + GP_FilterBrightness(*c, *c, filter_params, progress_callback);
return GP_ESUCCESS; } @@ -304,8 +307,11 @@ static GP_RetCode contrast(GP_Context **c, const char *params) print_error("contrast: mul parameter must be >= 0"); return GP_EINVAL; } + + GP_FILTER_PARAMS((*c)->pixel_type, filter_params); + GP_FilterParamSetFloatAll(filter_params, mul);
- GP_FilterContrast(*c, *c, mul, progress_callback); + GP_FilterContrast(*c, *c, filter_params, progress_callback);
return GP_ESUCCESS; } diff --git a/include/filters/GP_Filter.h b/include/filters/GP_Filter.h index e986ae6..af02bd0 100644 --- a/include/filters/GP_Filter.h +++ b/include/filters/GP_Filter.h @@ -32,4 +32,6 @@ #include "core/GP_Context.h" #include "core/GP_ProgressCallback.h"
+#include "GP_FilterParam.h" + #endif /* FILTERS_GP_FILTER_H */ diff --git a/include/filters/GP_FilterParam.h b/include/filters/GP_FilterParam.h new file mode 100644 index 0000000..dbf9749 --- /dev/null +++ b/include/filters/GP_FilterParam.h @@ -0,0 +1,107 @@ +/***************************************************************************** + * 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-2011 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + +/* + + Filter per channel parameter passing code. + + */ + +#ifndef FILTERS_GP_FILTER_PARAM_H +#define FILTERS_GP_FILTER_PARAM_H + +#include "core/GP_Pixel.h" + +#include <stdint.h> + +typedef union GP_FilterParamVal { + float f; + uint32_t ui; + int32_t i; + void *ptr; +} GP_FilterParamVal; + +/* + * Filter parameter structure for one channel. + * + * Filter takes, empty channel name terminated, arrray of these as parameter. + */ +typedef struct GP_FilterParam { + //TODO: this must be >= for maximal channel name (now it's 2) + char channel_name[2]; + union GP_FilterParamVal val; +} GP_FilterParam; + +/* + * Takes array of filter parameters and returns channel. + * + * Returns NULL if channel wasn't found. + */ +GP_FilterParam *GP_FilterParamChannel(GP_FilterParam params[], + const char *channel_name); + +/* + * Returns number of filter channels. + */ +uint32_t GP_FilterParamChannels(GP_FilterParam params[]); + +/* + * Compares param channels and pixel type channels. Returns zero if channels + * match. + */ +int GP_FilterParamCheckPixelType(GP_FilterParam params[], + GP_PixelType type); + +/* + * Returns zero only if params have exactly same channels as array of + * channel_names. + */ +int GP_FilterParamCheckChannels(GP_FilterParam params[], + const char *channel_names[]); + +/* + * Create and initalize the structure on the stack + */ +#define GP_FILTER_PARAMS(pixel_type, name) + GP_FilterParam name[GP_PixelTypes[pixel_type].numchannels + 1]; + GP_FilterParamInitChannels(name, pixel_type); +/* + * Initalize param names and terminator. + * + * Sets all values to 0. + */ +void GP_FilterParamInitChannels(GP_FilterParam params[], + GP_PixelType type); + +/* + * Sets all values to integer value. + */ +void GP_FilterParamSetIntAll(GP_FilterParam params[], + int32_t val); + +/* + * Sets all values to float value. + */ +void GP_FilterParamSetFloatAll(GP_FilterParam params[], + float val); + +#endif /* FILTERS_GP_FILTER_PARAM_H */ diff --git a/include/filters/GP_Filters.h b/include/filters/GP_Filters.h index 4a38cb6..f5cb848 100644 --- a/include/filters/GP_Filters.h +++ b/include/filters/GP_Filters.h @@ -32,6 +32,9 @@ #ifndef GP_FILTERS_H #define GP_FILTERS_H
+/* Filter per channel parameter passing interface */ +#include "filters/GP_FilterParam.h" + /* Image rotations (90 180 270 grads) and mirroring */ #include "filters/GP_Rotate.h"
diff --git a/include/filters/GP_Point.h b/include/filters/GP_Point.h index c5b53a8..e6aaeda 100644 --- a/include/filters/GP_Point.h +++ b/include/filters/GP_Point.h @@ -36,30 +36,37 @@ * * Increments each pixel channel by a given value. */ -void GP_FilterBrightness_Raw(const GP_Context *src, GP_Context *dst, - int32_t inc, GP_ProgressCallback *callback); +int GP_FilterBrightness_Raw(const GP_Context *src, GP_Context *dst, + GP_FilterParam params[], + GP_ProgressCallback *callback);
GP_Context *GP_FilterBrightness(const GP_Context *src, GP_Context *dst, - int32_t inc, GP_ProgressCallback *callback); + GP_FilterParam params[], + GP_ProgressCallback *callback);
/* * Contrast filter. * - * Multiplies each pixel channel by a given value. + * Multiplies each pixel channel by a given float value. + * + * The parameters should have the same pixel channels as + * source pixel type and are expected to be float numbers. */ -GP_Context *GP_FilterContrast_Raw(const GP_Context *src, GP_Context *dst, - float mul, GP_ProgressCallback *callback); +int GP_FilterContrast_Raw(const GP_Context *src, GP_Context *dst, + GP_FilterParam params[], + GP_ProgressCallback *callback);
GP_Context *GP_FilterContrast(const GP_Context *src, GP_Context *dst, - float mul, GP_ProgressCallback *callback); + GP_FilterParam params[], + GP_ProgressCallback *callback);
/* * Invert filter. * * Inverts each pixel channel (eg. val = max - val) */ -GP_Context *GP_FilterInvert_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); +int GP_FilterInvert_Raw(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback);
GP_Context *GP_FilterInvert(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback); diff --git a/libs/filters/GP_Brightness.gen.c.t b/libs/filters/GP_Brightness.gen.c.t index 1ba6fb9..adf0642 100644 --- a/libs/filters/GP_Brightness.gen.c.t +++ b/libs/filters/GP_Brightness.gen.c.t @@ -1,23 +1,32 @@ %% extends "filter.point.c.t"
%% block descr -Brightness filters -- Increments all color channels by a fixed value. +Brightness filters -- Increments color channel(s) by a fixed value. %% endblock
%% block body
{{ filter_include() }}
-%% call(ps) filter_per_pixel_size('Brightness', 'int32_t inc') -pix = pix + inc; -{{ filter_clamp_val('pix', ps.size) }} +%% macro filter_op(chann_name, chann_size) +{{ chann_name }} = {{ chann_name }} + {{ chann_name }}_i; +{{ filter_clamp_val(chann_name, chann_size) }} +%% endmacro + +/* + * Generated brightness filters. + */ +%% call(pt) filter_point_per_channel('Brightness', 'GP_FilterParam params[]', filter_op) +{{ filter_params(pt, 'params', 'int32_t', 'i') }} %% endcall
-%% call(chan) filter_per_pixel_type('Brightness', 'int32_t inc') -{{ chan[0] }} = {{ chan[0] }} + inc; -{{ filter_clamp_val(chan[0], chan[2]) }} +/* + * Generated constrast filters for pixels with one channel. + */ +%% call(ps) filter_point_per_bpp('Brightness', 'GP_FilterParam params[]', filter_op) +{{ filter_param(ps, 'params', 'int32_t', 'i') }} %% endcall
-{{ filter_functions('Brightness', 'int32_t inc', 'inc', "inc=%i") }} +{{ filter_functions('Brightness', 'GP_FilterParam params[]', 'params') }}
%% endblock body diff --git a/libs/filters/GP_Contrast.gen.c.t b/libs/filters/GP_Contrast.gen.c.t index 3398d1a..abbb0c3 100644 --- a/libs/filters/GP_Contrast.gen.c.t +++ b/libs/filters/GP_Contrast.gen.c.t @@ -1,23 +1,32 @@ %% extends "filter.point.c.t"
%% block descr -Contrast filters -- Multiply all color channels by a fixed value. +Contrast filters -- Multiply color channel(s) by a fixed float value. %% endblock
%% block body
{{ filter_include() }}
-%% call(ps) filter_per_pixel_size('Contrast', 'float mul') -pix = 1.00 * pix * mul; -{{ filter_clamp_val('pix', ps.size) }} +%% macro filter_op(chan_name, chan_size) +{{ chan_name }} = {{ chan_name }} * {{ chan_name }}_f + 0.5; +{{ filter_clamp_val(chan_name, chan_size) }} +%% endmacro + +/* + * Generated contrast filters for pixels with several channels. + */ +%% call(pt) filter_point_per_channel('Contrast', 'GP_FilterParam params[]', filter_op) +{{ filter_params(pt, 'params', 'float', 'f') }} %% endcall
-%% call(chan) filter_per_pixel_type('Contrast', 'float mul') -{{ chan[0] }} = mul * {{ chan[0] }} + 0.5; -{{ filter_clamp_val(chan[0], chan[2]) }} +/* + * Generated constrast filters for pixels with one channel. + */ +%% call(ps) filter_point_per_bpp('Contrast', 'GP_FilterParam params[]', filter_op) +{{ filter_param(ps, 'params', 'float', 'f') }} %% endcall
-{{ filter_functions('Contrast', 'float mul', 'mul', "mul=%2.3f") }} +{{ filter_functions('Contrast', 'GP_FilterParam params[]', 'params') }}
%% endblock body diff --git a/libs/filters/GP_FilterParam.c b/libs/filters/GP_FilterParam.c new file mode 100644 index 0000000..4277df7 --- /dev/null +++ b/libs/filters/GP_FilterParam.c @@ -0,0 +1,125 @@ +/***************************************************************************** + * 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-2011 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + +#include <string.h> + +#include <GP_Debug.h> + +#include "GP_FilterParam.h" + +static unsigned int count_channels(GP_FilterParam params[]) +{ + unsigned int i = 0; + + while (params[i].channel_name[0] != '0') + i++; + + return i; +} + +GP_FilterParam *GP_FilterParamChannel(GP_FilterParam params[], + const char *channel_name) +{ + unsigned int i; + + for (i = 0; params[i].channel_name[0] != '0'; i++) + if (!strcmp(params[i].channel_name, channel_name)) + return ¶ms[i]; + + return NULL; +} + +uint32_t GP_FilterParamChannels(GP_FilterParam params[]) +{ + return count_channels(params); +} + +int GP_FilterParamCheckPixelType(GP_FilterParam params[], + GP_PixelType pixel_type) +{ + unsigned int i, num_channels; + const GP_PixelTypeChannel *channels; + + num_channels = GP_PixelTypes[pixel_type].numchannels; + channels = GP_PixelTypes[pixel_type].channels; + + i = count_channels(params); + + if (i != num_channels) + return 1; + + for (i = 0; i < num_channels; i++) + if (GP_FilterParamChannel(params, channels[i].name) == NULL) + return 1; + + return 0; +} + +int GP_FilterParamCheckChannels(GP_FilterParam params[], + const char *channel_names[]) +{ + unsigned int i; + + for (i = 0; channel_names[i] != NULL; i++) + if (GP_FilterParamChannel(params, channel_names[i]) == NULL) + return 1; + + if (i != count_channels(params)) + return 1; + + return 0; +} + +void GP_FilterParamInitChannels(GP_FilterParam params[], + GP_PixelType pixel_type) +{ + unsigned int i, num_channels; + const GP_PixelTypeChannel *channels; + + num_channels = GP_PixelTypes[pixel_type].numchannels; + channels = GP_PixelTypes[pixel_type].channels; + + for (i = 0; i < num_channels; i++) { + strcpy(params[i].channel_name, channels[i].name); + memset(¶ms[i].val, 0, sizeof(GP_FilterParamVal)); + } + + params[i].channel_name[0] = '0'; +} + +void GP_FilterParamSetIntAll(GP_FilterParam params[], + int32_t val) +{ + unsigned int i; + + for (i = 0; params[i].channel_name[0] != '0'; i++) + params[i].val.i = val; +} + +void GP_FilterParamSetFloatAll(GP_FilterParam params[], + float val) +{ + unsigned int i; + + for (i = 0; params[i].channel_name[0] != '0'; i++) + params[i].val.f = val; +} diff --git a/libs/filters/GP_Invert.gen.c.t b/libs/filters/GP_Invert.gen.c.t index 1c11b30..e6d4b24 100644 --- a/libs/filters/GP_Invert.gen.c.t +++ b/libs/filters/GP_Invert.gen.c.t @@ -8,12 +8,14 @@ Invert filters -- Invert image
{{ filter_include() }}
-%% call(ps) filter_per_pixel_size('Invert') -pix = {{ 2 ** ps.size - 1 }} - pix; +%% macro filter_op(chann_name, chann_size) +{{ chann_name }} = {{ 2 ** chann_size - 1 }} - {{ chann_name }}; +%% endmacro + +%% call(pt) filter_point_per_channel('Invert', '', filter_op) %% endcall
-%% call(chan) filter_per_pixel_type('Invert') -{{ chan[0] }} = {{ 2 ** chan[2] - 1 }} - {{ chan[0] }}; +%% call(ps) filter_point_per_bpp('Invert', '', filter_op) %% endcall
{{ filter_functions('Invert') }} diff --git a/libs/filters/Makefile b/libs/filters/Makefile index 1608647..2b4cdb6 100644 --- a/libs/filters/Makefile +++ b/libs/filters/Makefile @@ -1,5 +1,5 @@ TOPDIR=../.. -GENSOURCES=GP_Brightness.gen.c GP_Contrast.gen.c GP_Invert.gen.c+GENSOURCES=GP_Contrast.gen.c GP_Brightness.gen.c GP_Invert.gen.c GP_MirrorV.gen.c GP_Rotate.gen.c GP_Dither.gen.c GENHEADERS= CSOURCES=$(filter-out $(wildcard *.gen.c),$(wildcard *.c)) diff --git a/pylib/templates/filter.point.c.t b/pylib/templates/filter.point.c.t index 9a925cf..02240ee 100644 --- a/pylib/templates/filter.point.c.t +++ b/pylib/templates/filter.point.c.t @@ -2,52 +2,50 @@
{% macro maybe_opts(opts) %}{% if opts %}, {{ opts }}{% endif %}{% endmacro %}
+{% macro maybe_opts2(opts) %}{% if opts %}{{ opts }}, {% endif %}{% endmacro %} + %% macro filter_include() #include "core/GP_Context.h" #include "core/GP_Pixel.h" #include "core/GP_GetPutPixel.h" #include "core/GP_Debug.h" +#include "GP_Point.h" #include "GP_Filter.h" %% endmacro
/* - * Filter per pixel size, used for one channel images. + * Value clamping macro */ -%% macro filter_per_pixel_size(name, opts="") -%% for ps in pixelsizes -%% if ps.size <= 8 and ps.size > 1 -int GP_Filter{{ name }}_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst{{ maybe_opts(opts) }}, - GP_ProgressCallback *callback) -{ - uint32_t x, y; +%% macro filter_clamp_val(var, size) + if ({{ var }} < 0) + {{ var }} = 0;
- for (y = 0; y < src->h; y++) { - for (x = 0; x < src->w; x++) { - int32_t pix = GP_GetPixel_Raw_{{ ps.suffix }}(src, x, y); - {{ caller(ps) }} - GP_PutPixel_Raw_{{ ps.suffix }}(dst, x, y, pix); - } - - if (GP_ProgressCallbackReport(callback, y, src->h, src->w)) - return 1; - } + if ({{ var }} > {{ 2 ** size - 1}}) + {{ var }} = {{ 2 ** size - 1}}; +%% endmacro
- GP_ProgressCallbackDone(callback); - return 0; -} -%% endif -%% endfor +/* + * Load parameters from params structure into variables + */ +%% macro filter_params(pt, params, c_type, id) + GP_ASSERT(GP_FilterParamCheckPixelType({{ params }}, GP_PIXEL_{{ pt.name }}) == 0, + "Invalid params channels for context pixel type"); + + %% for chann in pt.chanslist + {{ c_type }} {{ chann[0] }}_{{ id }} = (GP_FilterParamChannel({{ params }}, "{{ chann[0] }}"))->val.{{ id }}; + %% endfor %% endmacro
/* * Filter per pixel type, used for images with more than one channel per pixel */ -%% macro filter_per_pixel_type(name, opts="") +%% macro filter_point_per_channel(name, opts="", filter_op) %% for pt in pixeltypes %% if not pt.is_unknown() and len(pt.chanslist) > 1 -int GP_Filter{{ name }}_{{ pt.name }}(const GP_Context *src, GP_Context *dst{{ maybe_opts(opts) }}, - GP_ProgressCallback *callback) +int GP_Filter{{ name }}_{{ pt.name }}(const GP_Context *src, GP_Context *dst, + {{ maybe_opts2(opts) }}GP_ProgressCallback *callback) { +{{ caller(pt) }} uint32_t x, y;
for (y = 0; y < src->h; y++) { @@ -58,11 +56,11 @@ int GP_Filter{{ name }}_{{ pt.name }}(const GP_Context *src, GP_Context *dst{{ m %% endfor
%% for c in pt.chanslist - {{ caller(c) }} + {{ filter_op(c[0], c[2]) }} %% endfor
pix = GP_Pixel_CREATE_{{ pt.name }}({{ pt.chanslist[0][0] }}{% for c in pt.chanslist[1:] %}, {{ c[0] }}{% endfor %}); - + GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, x, y, pix); } @@ -79,15 +77,45 @@ int GP_Filter{{ name }}_{{ pt.name }}(const GP_Context *src, GP_Context *dst{{ m %% endmacro
/* - * Value clamping macro + * Load parameters from params structure into variable */ -%% macro filter_clamp_val(var, size) - if ({{ var }} < 0) - {{ var }} = 0; +%% macro filter_param(ps, params, c_type, val) + GP_ASSERT(GP_FilterParamChannels({{ params }}) != 1, + "Expected only one channel");
- if ({{ var }} > {{ 2 ** size - 1}}) - {{ var }} = {{ 2 ** size - 1}}; -%% endmacro + {{ c_type }} pix_{{ val }} = params[0].val.{{ val }}; +%% endmacro + +/* + * Point filter per bpp (used for 1 channel pixels to save space). + */ +%% macro filter_point_per_bpp(name, opts="", filter_op) +%% for ps in pixelsizes +%% if ps.size <= 8 and ps.size > 1 +int GP_Filter{{ name }}_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst, + {{ maybe_opts2(opts) }}GP_ProgressCallback *callback) +{ +{{ caller(ps) }} + uint32_t x, y; + + for (y = 0; y < src->h; y++) { + for (x = 0; x < src->w; x++) { + int32_t pix = GP_GetPixel_Raw_{{ ps.suffix }}(src, x, y); + {{ filter_op('pix', ps.size) }} + GP_PutPixel_Raw_{{ ps.suffix }}(dst, x, y, pix); + } + + if (GP_ProgressCallbackReport(callback, y, src->h, src->w)) + return 1; + } + + GP_ProgressCallbackDone(callback); + return 0; +} + +%% endif +%% endfor +%% endmacro
/* * Switch per pixel sizes or pixel types. @@ -96,7 +124,7 @@ int GP_Filter{{ name }}_{{ pt.name }}(const GP_Context *src, GP_Context *dst{{ m int GP_Filter{{ name }}_Raw(const GP_Context *src, GP_Context *dst{{ maybe_opts(opts) }}, GP_ProgressCallback *callback) { - GP_DEBUG(1, "Running filter {{ name }} {{ fmt }}"{{ maybe_opts(params) }}); + GP_DEBUG(1, "Running filter {{ name }}");
switch (src->pixel_type) { %% for pt in pixeltypes @@ -145,4 +173,3 @@ GP_Context *GP_Filter{{ name }}(const GP_Context *src, GP_Context *dst{{ maybe_o return res; } %% endmacro -
-----------------------------------------------------------------------
Summary of changes: .gitignore | 3 +- demos/grinder/grinder.c | 135 +++++++++++++++++++++++++++++----- include/filters/GP_Filter.h | 2 + include/filters/GP_FilterParam.h | 119 ++++++++++++++++++++++++++++++ include/filters/GP_Filters.h | 3 + include/filters/GP_Point.h | 38 +++++++-- libs/filters/GP_Brightness.gen.c.t | 25 ++++-- libs/filters/GP_Contrast.gen.c.t | 25 ++++-- libs/filters/GP_FilterParam.c | 143 ++++++++++++++++++++++++++++++++++++ libs/filters/GP_Invert.gen.c.t | 10 ++- libs/filters/GP_Point.gen.c.t | 35 +++++++++ libs/filters/Makefile | 2 +- pylib/templates/filter.point.c.t | 118 ++++++++++++++++++++--------- 13 files changed, 572 insertions(+), 86 deletions(-) create mode 100644 include/filters/GP_FilterParam.h create mode 100644 libs/filters/GP_FilterParam.c create mode 100644 libs/filters/GP_Point.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.