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, generate has been updated via a26eff704d1d896d04efccb273cab42593b9efde (commit) from 8bed60585798f64bb79328f012a738f44746cc81 (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/a26eff704d1d896d04efccb273cab42593b9e...
commit a26eff704d1d896d04efccb273cab42593b9efde Author: Cyril Hrubis metan@ucw.cz Date: Wed Sep 28 23:30:03 2011 +0200
Added grinder demo on gfxprim bitmap filters.
diff --git a/Makefile b/Makefile index fac8f9b..5c4d45f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ TOPDIR=. -SUBDIRS=libs tests pylib +SUBDIRS=libs tests pylib demos include include.mk
# diff --git a/demos/Makefile b/demos/Makefile new file mode 100644 index 0000000..571580a --- /dev/null +++ b/demos/Makefile @@ -0,0 +1,3 @@ +TOPDIR=.. +SUBDIRS=grinder +include $(TOPDIR)/include.mk diff --git a/demos/grinder/Makefile b/demos/grinder/Makefile new file mode 100644 index 0000000..7cf1e72 --- /dev/null +++ b/demos/grinder/Makefile @@ -0,0 +1,13 @@ +TOPDIR=../.. + +CSOURCES=$(shell echo *.c) + +INCLUDE=core gfx SDL backends +LDLIBS+=-lGP -L$(TOPDIR)/build/ -lpng + +APPS=grinder + +grinder: params.o + +include $(TOPDIR)/include.mk +include $(TOPDIR)/app.mk diff --git a/demos/grinder/README b/demos/grinder/README new file mode 100644 index 0000000..749485f --- /dev/null +++ b/demos/grinder/README @@ -0,0 +1,12 @@ +BITMAP GRINDER +~~~~~~~~~~~~~~ + +Simple utility to load image, apply gfxprim filters and save result. + +The usage is: + +grinder -f filter_name:filter_params... -f filter_name:filter_params... -f filter_name:filter_params... image1 image2 ... + +Which will apply pipeline of filters to each image and store results to out_X.ppm + +see grinder -h for list of filters and options diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c new file mode 100644 index 0000000..73c2d4b --- /dev/null +++ b/demos/grinder/grinder.c @@ -0,0 +1,343 @@ +/***************************************************************************** + * 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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include "GP.h" + +#include "params.h" + +/* resize filter */ + +static const char *resize_algs[] = { + "nn", + "cubic", + NULL +}; + +static struct param resize_params[] = { + {"alg", PARAM_ENUM, resize_algs, NULL}, + {"ratio", PARAM_FLOAT, NULL, NULL}, + {NULL, 0, NULL, NULL} +}; + +static GP_RetCode resize(GP_Context **c, const char *params) +{ + int alg = 1; + float ratio = -1; + + param_parse(params, resize_params, &alg, &ratio); + + if (ratio == -1) + return GP_EINVAL; + + GP_Size w = ratio * (*c)->w; + GP_Size h = ratio * (*c)->h; + GP_Context *res = NULL; + + switch (alg) { + case 0: + res = GP_Scale_NN(*c, w, h); + break; + case 1: + res = GP_Scale_BiCubic(*c, w, h); + break; + } + + if (res == NULL) + return GP_EINVAL; + + GP_ContextFree(*c); + *c = res; + + return GP_ESUCCESS; +} + +/* scale filter */ + +static const char *scale_algs[] = { + "nn", + "cubic", + NULL +}; + +static int scale_check_size(const struct param *self __attribute__((unused)), + void *val) +{ + int i = *((int*)val); + + if (i <= 0) + return 1; + + return 0; +} + +static struct param scale_params[] = { + {"alg", PARAM_ENUM, scale_algs, NULL}, + {"w", PARAM_INT, NULL, scale_check_size}, + {"h", PARAM_INT, NULL, scale_check_size}, + {NULL, 0, NULL, NULL} +}; + +static GP_RetCode scale(GP_Context **c, const char *params) +{ + int alg = 1; + int w = -1; + int h = -1; + + param_parse(params, scale_params, &alg, &w, &h); + + if (w == -1 || h == -1) + return GP_EINVAL; + + GP_Context *res = NULL; + + switch (alg) { + case 0: + res = GP_Scale_NN(*c, w, h); + break; + case 1: + res = GP_Scale_BiCubic(*c, w, h); + break; + } + + if (res == NULL) + return GP_EINVAL; + + GP_ContextFree(*c); + *c = res; + + return GP_ESUCCESS; +} + +/* rotate filter */ + +static const char *rotate_rots[] = { + "90", + "180", + "270", +}; + +static struct param rotate_params[] = { + {"rot", PARAM_ENUM, rotate_rots, NULL}, + {NULL, 0, NULL, NULL} +}; + +static GP_RetCode rotate(GP_Context **c, const char *params) +{ + int rot = -1; + + param_parse(params, rotate_params, &rot); + + if (rot == -1) + return GP_EINVAL; + + switch (rot) { + case 0: + GP_RotateCW(*c); + break; + case 1: + GP_MirrorV(*c); + break; + case 2: + GP_RotateCCW(*c); + break; + } + + return GP_ESUCCESS; +} + +/* brightness filter */ + +static struct param bright_params[] = { + {"val", PARAM_INT, NULL, NULL}, + {NULL, 0, NULL, NULL} +}; + +static GP_RetCode bright(GP_Context **c, const char *params) +{ + int bright = 0; + + param_parse(params, bright_params, &bright); + + GP_Context *res = GP_FilterBrightness(*c, bright); + + if (res == NULL) + return GP_EINVAL; + + GP_ContextFree(*c); + *c = res; + + return GP_ESUCCESS; +} + +/* filters */ + +struct filter { + char *name; + char *param_help; + GP_RetCode (*apply)(GP_Context **c, const char *params); +}; + +static struct filter filter_table[] = { + {"resize", "alg=nn|cubic:ratio=float", resize}, + {"scale", "alg=nn|cubic:w=int:h=int", scale}, + {"rotate", "rot=90|180|270", rotate}, + {"bright", "val=int", bright}, + {NULL, NULL, NULL} +}; + +static struct filter *get_filter(const char *name) +{ + unsigned int i; + + for (i = 0; filter_table[i].name != NULL; i++) { + if (!strcasecmp(filter_table[i].name, name)) + return &filter_table[i]; + } + + return NULL; +} + +static void print_filter_help(const char *prefix) +{ + unsigned int i; + + for (i = 0; filter_table[i].name != NULL; i++) { + printf("%s%s : %sn", prefix, filter_table[i].name, + filter_table[i].param_help); + } +} + +/* application */ + +#define FILTERS_MAX 255 + +static const char *filter_params[FILTERS_MAX]; +static const struct filter *filters[FILTERS_MAX]; +static unsigned int filter_cnt = 0; + +static void add_filter(char *params) +{ + if (filter_cnt >= FILTERS_MAX) { + fprintf(stderr, "Maximal number of filters exceeded (%u), " + "increase and recompile.", FILTERS_MAX); + exit(1); + } + + const char *name = strsep(¶ms, ":"); + + filters[filter_cnt] = get_filter(name); + + if (filters[filter_cnt] == NULL) { + fprintf(stderr, "Invalid filter name '%s'n", name); + exit(1); + } + + filter_params[filter_cnt++] = params; +} + +static void apply_filters(GP_Context **src) +{ + unsigned int i; + GP_RetCode ret; + + for (i = 0; i < filter_cnt; i++) + if ((ret = filters[i]->apply(src, filter_params[i]))) { + fprintf(stderr, "Error: %sn", GP_RetCodeName(ret)); + exit(1); + } +} + +static const char *app_help = { + " <- Bitmap Grinder -> n" + " n" + "-h : prints this help n" + "-v int : sets gfxprim verbosity level n" + "-f params : apply filter, multiple filters may be usedn" + " n" + " List of filters n" +}; + +static void print_help(void) +{ + puts(app_help); + print_filter_help(" "); +} + +int main(int argc, char *argv[]) +{ + GP_Context *bitmap; + GP_RetCode ret; + int opt, i; + + while ((opt = getopt(argc, argv, "f:hv:")) != -1) { + switch (opt) { + case 'h': + print_help(); + return 0; + break; + case 'v': + GP_SetDebugLevel(atoi(optarg)); + break; + case 'f': + add_filter(optarg); + break; + default: + print_help(); + return 1; + } + } + + if (optind >= argc) { + fprintf(stderr, "Expected bitmap filenamesn"); + print_help(); + return 1; + } + + for (i = optind; i < argc; i++) { + char buf[255]; + + snprintf(buf, sizeof(buf), "out_%i.ppm", i - optind + 1); + fprintf(stderr, "Processing '%s' -> '%s'n", argv[i], buf); + + if ((ret = GP_LoadImage(argv[i], &bitmap))) { + fprintf(stderr, "Failed to load bitmap: %sn", + GP_RetCodeName(ret)); + return 1; + } + + apply_filters(&bitmap); + + + if ((ret = GP_SavePPM(buf, bitmap, "b"))) { + fprintf(stderr, "Failed to load bitmap: %sn", GP_RetCodeName(ret)); + return 1; + } + + } + + return 0; +} diff --git a/demos/grinder/params.c b/demos/grinder/params.c new file mode 100644 index 0000000..405c8bd --- /dev/null +++ b/demos/grinder/params.c @@ -0,0 +1,185 @@ +/***************************************************************************** + * 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 <stdio.h> +#include <string.h> +#include <ctype.h> +#include <stdlib.h> +#include <stdarg.h> + +#include "params.h" + +static unsigned int count_params(const char *params) +{ + unsigned int ret = 1, i; + char prev = ':'; + + for (i = 0; params[i] != '0'; i++) { + + if (params[i] == ':' && prev != ':') + ret++; + + prev = params[i]; + } + + return ret; +} + +static void split_params(char *params, char **names) +{ + unsigned int i, n = 0; + char prev = ':'; + + for (i = 0; params[i] != '0'; i++) { + + if (params[i] != ':' && prev == ':') + names[n++] = ¶ms[i]; + + prev = params[i]; + + if (params[i] == ':') + params[i] = '0'; + } +} + +static void do_split(char *param, char **value) +{ + unsigned int i; + + *value = NULL; + + for (i = 0; param[i] != '0'; i++) { + + if (param[i] == '=' || isspace(param[i])) { + param[i] = '0'; + *value = ¶m[i+1]; + } + } +} + +static void split_values(char **names, char **values, unsigned int n) +{ + unsigned int i; + + for (i = 0; i < n; i++) + do_split(names[i], &values[i]); +} + +int param_pos(char *names[], const char *name, unsigned int start, unsigned int n) +{ + unsigned int i; + + for (i = start; i < n; i++) + if (!strcasecmp(names[i], name)) + return i; + + return -1; +} + +int set_int(int *res, char *val) +{ + //TODO: error checks + *res = atoi(val); + + return 0; +} + +int set_float(float *res, char *val) +{ + //TODO: error checks + *res = atof(val); + + return 0; +} + +int set_enum(int *res, char *val, const char *enums[]) +{ + unsigned int i; + + for (i = 0; enums[i] != NULL; i++) + if (!strcasecmp(enums[i], val)) { + *res = i; + return 0; + } + + return 1; +} + +int param_parse(const char *params, const struct param *param_desc, ...) +{ + char *par = strdup(params); + unsigned int n, i; + va_list va; + + if (par == NULL) { + fprintf(stderr, "Malloc failed :(n"); + return 1; + } + + n = count_params(params); + + char *names[n]; + char *values[n]; + + split_params(par, names); + split_values(names, values, n); + + va_start(va, param_desc); + + for (i = 0; param_desc[i].name != NULL; i++) { + void *arg = va_arg(va, void*); + int pos = 0, ret; + + while ((pos = param_pos(names, param_desc[i].name, pos, n)) >= 0) { + switch (param_desc[i].type) { + case PARAM_BOOL: + + break; + case PARAM_INT: + if ((ret = set_int(arg, values[pos]))) + return ret; + break; + case PARAM_FLOAT: + if ((ret = set_float(arg, values[pos]))) + return ret; + break; + case PARAM_STR: + + break; + case PARAM_ENUM: + if ((ret = set_enum(arg, values[pos], + param_desc[i].enum_table))) + return ret; + break; + } + + if (param_desc[i].check != NULL) + param_desc[i].check(¶m_desc[i], arg); + pos++; + } + } + + va_end(va); + free(par); + + return 0; +} diff --git a/demos/grinder/params.h b/demos/grinder/params.h new file mode 100644 index 0000000..f397bb7 --- /dev/null +++ b/demos/grinder/params.h @@ -0,0 +1,44 @@ +/***************************************************************************** + * 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 * + * * + *****************************************************************************/ + +#ifndef PARAMS_H +#define PARAMS_H + +enum param_type { + PARAM_BOOL, + PARAM_INT, + PARAM_FLOAT, + PARAM_STR, + PARAM_ENUM, +}; + +struct param { + const char *name; + enum param_type type; + const char **enum_table; + + int (*check)(const struct param *self, void *val); +}; + +int param_parse(const char *params, const struct param *param_desc, ...); + +#endif /* PARAMS_H */ diff --git a/demos/grinder/runtest.sh b/demos/grinder/runtest.sh new file mode 100755 index 0000000..73c9f61 --- /dev/null +++ b/demos/grinder/runtest.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# +# Run dynamically linked test. +# + +PROG="$1" +shift + +echo "LD_LIBRARY_PATH=../../build/ ./$PROG $@" +LD_LIBRARY_PATH=../../build/ ./$PROG $@
-----------------------------------------------------------------------
Summary of changes: Makefile | 2 +- {tests => demos}/Makefile | 2 +- demos/grinder/Makefile | 13 + demos/grinder/README | 12 + demos/grinder/grinder.c | 343 ++++++++++++++++++++ demos/grinder/params.c | 185 +++++++++++ .../filters/GP_Linear.h => demos/grinder/params.h | 25 +- {tests/SDL => demos/grinder}/runtest.sh | 0 8 files changed, 572 insertions(+), 10 deletions(-) copy {tests => demos}/Makefile (53%) create mode 100644 demos/grinder/Makefile create mode 100644 demos/grinder/README create mode 100644 demos/grinder/grinder.c create mode 100644 demos/grinder/params.c copy include/filters/GP_Linear.h => demos/grinder/params.h (82%) copy {tests/SDL => demos/grinder}/runtest.sh (100%)
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.