Gfxprim
Threads by month
- ----- 2026 -----
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- 929 discussions
[repo.or.cz] gfxprim.git branch master updated: eaa73f8e7eea739d3d14c830622c455acd6717c6
by metan 21 Jul '12
by metan 21 Jul '12
21 Jul '12
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 eaa73f8e7eea739d3d14c830622c455acd6717c6 (commit)
from b704cc579b2db0db8015f46acbc8c69ffcf81aa7 (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/eaa73f8e7eea739d3d14c830622c455acd67…
commit eaa73f8e7eea739d3d14c830622c455acd6717c6
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 21 19:17:22 2012 +0200
filters: Median make use of GP_TempAlloc.
diff --git a/libs/filters/GP_Median.c b/libs/filters/GP_Median.c
index 9e60d60..db58806 100644
--- a/libs/filters/GP_Median.c
+++ b/libs/filters/GP_Median.c
@@ -31,38 +31,30 @@
#include <string.h>
-#define HIST_INIT(w) - unsigned int R[w][256]; - unsigned int G[w][256]; - unsigned int B[w][256]; - memset(R, 0, sizeof(R)); - memset(G, 0, sizeof(G)); - memset(B, 0, sizeof(B)); -
-static inline void hist_inc(unsigned int h[][256], unsigned int x, unsigned int val)
+static inline void hist_inc(unsigned int *h, unsigned int x, unsigned int val)
{
- h[x][val]++;
+ h[256 * x + val]++;
}
-static inline void hist_dec(unsigned int h[][256], unsigned int x, unsigned int val)
+static inline void hist_dec(unsigned int *h, unsigned int x, unsigned int val)
{
- h[x][val]--;
+ h[256 * x + val]--;
}
-static inline void hist_sub(unsigned int *a, unsigned int *b)
+static inline void hist_sub(unsigned int *a, unsigned int *b, unsigned int x)
{
int j;
for (j = 0; j < 256; j++)
- a[j] -= b[j];
+ a[j] -= b[256 * x + j];
}
-static inline void hist_add(unsigned int *a, unsigned int *b)
+static inline void hist_add(unsigned int *a, unsigned int *b, unsigned int x)
{
int j;
for (j = 0; j < 256; j++)
- a[j] += b[j];
+ a[j] += b[256 * x + j];
}
#define HIST_INC hist_inc
@@ -96,10 +88,20 @@ static int GP_FilterMedian_Raw(const GP_Context *src,
GP_DEBUG(1, "Median filter size %ux%u xmed=%u ymed=%u",
w_src, h_src, 2 * xmed + 1, 2 * ymed + 1);
+
+ /* The buffer is w + 2*xmed + 1 size because we read the last value but we don't use it */
+ unsigned int size = (w_src + 2 * xmed + 1) * sizeof(int);
/* Create and initalize arrays for row of histograms */
- /* The buffer is w + 2*xmed + 1 size because we read the last value but we don't use it */
- HIST_INIT(w_src + 2 * xmed + 1);
+ GP_TempAllocCreate(temp, 3 * 256 * size);
+
+ unsigned int *R = GP_TempAllocGet(temp, 256 * size);
+ unsigned int *G = GP_TempAllocGet(temp, 256 * size);
+ unsigned int *B = GP_TempAllocGet(temp, 256 * size);
+
+ memset(R, 0, 256 * size);
+ memset(G, 0, 256 * size);
+ memset(B, 0, 256 * size);
/* Prefill row of histograms */
for (x = 0; x < (int)w_src + 2*xmed; x++) {
@@ -126,9 +128,9 @@ static int GP_FilterMedian_Raw(const GP_Context *src,
/* Compute first histogram */
for (i = 0; i <= 2*xmed; i++) {
- hist_add(XR, R[i]);
- hist_add(XG, G[i]);
- hist_add(XB, B[i]);
+ hist_add(XR, R, i);
+ hist_add(XG, G, i);
+ hist_add(XB, B, i);
}
/* Generate row */
@@ -141,13 +143,13 @@ static int GP_FilterMedian_Raw(const GP_Context *src,
GP_Pixel_CREATE_RGB888(r, g, b));
/* Recompute histograms */
- hist_sub(XR, R[x]);
- hist_sub(XG, G[x]);
- hist_sub(XB, B[x]);
+ hist_sub(XR, R, x);
+ hist_sub(XG, G, x);
+ hist_sub(XB, B, x);
- hist_add(XR, R[x + 2 * xmed + 1]);
- hist_add(XG, G[x + 2 * xmed + 1]);
- hist_add(XB, B[x + 2 * xmed + 1]);
+ hist_add(XR, R, (x + 2 * xmed + 1));
+ hist_add(XG, G, (x + 2 * xmed + 1));
+ hist_add(XB, B, (x + 2 * xmed + 1));
}
/* Recompute histograms, remove y - ymed pixel add y + ymed + 1 */
@@ -171,11 +173,12 @@ static int GP_FilterMedian_Raw(const GP_Context *src,
}
if (GP_ProgressCallbackReport(callback, y, h_src, w_src)) {
- // GP_TempAllocFree(temp);
+ GP_TempAllocFree(temp);
return 1;
}
}
+ GP_TempAllocFree(temp);
GP_ProgressCallbackDone(callback);
return 0;
-----------------------------------------------------------------------
Summary of changes:
libs/filters/GP_Median.c | 59 ++++++++++++++++++++++++---------------------
1 files changed, 31 insertions(+), 28 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: b704cc579b2db0db8015f46acbc8c69ffcf81aa7
by metan 21 Jul '12
by metan 21 Jul '12
21 Jul '12
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 b704cc579b2db0db8015f46acbc8c69ffcf81aa7 (commit)
via 12843d60dfc09f14d451d1e73cd0beb3e491b4db (commit)
from 7609f2afad8b10921084c8d2fe14283873e75ff2 (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/b704cc579b2db0db8015f46acbc8c69ffcf8…
commit b704cc579b2db0db8015f46acbc8c69ffcf81aa7
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 21 18:50:50 2012 +0200
demos: Add median filter to grinder.
diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c
index a2192b7..f001ff6 100644
--- a/demos/grinder/grinder.c
+++ b/demos/grinder/grinder.c
@@ -591,6 +591,42 @@ static GP_RetCode add_noise(GP_Context **c, const char *params)
return GP_ESUCCESS;
}
+/* median filter */
+
+static struct param median_params[] = {
+ {"radius", PARAM_INT, "median radius for both x and y", NULL, NULL},
+ {"radius_x", PARAM_INT, "median radius for x", NULL, NULL},
+ {"radius_y", PARAM_INT, "median radius for y", NULL, NULL},
+ {NULL, 0, NULL, NULL, NULL}
+};
+
+static GP_RetCode median(GP_Context **c, const char *params)
+{
+ int rad = -1, rad_x, rad_y;
+
+ if (param_parse(params, median_params, "median", param_err, &rad, &rad_x, &rad_y))
+ return GP_EINVAL;
+
+ if (rad != -1) {
+ rad_x = rad;
+ rad_y = rad;
+ }
+
+ if (rad_x < 0 || rad_y < 0)
+ return GP_EINVAL;
+
+ GP_Context *ret = GP_FilterMedianAlloc(*c, rad_x, rad_y, progress_callback);
+
+ if (ret == NULL)
+ return GP_ENOMEM;
+
+ GP_ContextFree(*c);
+ *c = ret;
+
+ return GP_ESUCCESS;
+}
+
+
/* arithmetics */
static const char *arithmetic_ops[] = {
@@ -702,6 +738,7 @@ static struct filter filter_table[] = {
{"dither", "dithers bitmap", dither_params, dither},
{"arithmetic", "arithmetic operation", arithmetic_params, arithmetic},
{"histogram", "save histogram into image file", histogram_params, histogram},
+ {"median", "median filter", median_params, median},
{"jpg", "save jpg image", save_jpg_params, save_jpg},
{"png", "save png image", save_png_params, save_png},
{NULL, NULL, NULL, NULL}
http://repo.or.cz/w/gfxprim.git/commit/12843d60dfc09f14d451d1e73cd0beb3e491…
commit 12843d60dfc09f14d451d1e73cd0beb3e491b4db
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 21 18:50:22 2012 +0200
pywrap: Update filter.i for median filter.
diff --git a/pylib/gfxprim/filters/filters.i b/pylib/gfxprim/filters/filters.i
index dec3bba..caecd35 100644
--- a/pylib/gfxprim/filters/filters.i
+++ b/pylib/gfxprim/filters/filters.i
@@ -56,3 +56,7 @@
%newobject GP_FilterBlurAlloc;
%newobject GP_FilterBlurExAlloc;
%include "GP_Blur.h"
+
+%newobject GP_FilterMedianAlloc;
+%newobject GP_FilterMedianExAlloc;
+%include "GP_Median.h"
-----------------------------------------------------------------------
Summary of changes:
demos/grinder/grinder.c | 37 +++++++++++++++++++++++++++++++++++++
pylib/gfxprim/filters/filters.i | 4 ++++
2 files changed, 41 insertions(+), 0 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 7609f2afad8b10921084c8d2fe14283873e75ff2
by metan 21 Jul '12
by metan 21 Jul '12
21 Jul '12
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
discards 9b8d0d259aedd7b0ce02b082a328f434a7107e5f (commit)
via 7609f2afad8b10921084c8d2fe14283873e75ff2 (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (9b8d0d259aedd7b0ce02b082a328f434a7107e5f)
N -- N -- N (7609f2afad8b10921084c8d2fe14283873e75ff2)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
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/7609f2afad8b10921084c8d2fe14283873e7…
commit 7609f2afad8b10921084c8d2fe14283873e75ff2
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 21 18:26:07 2012 +0200
filters: Add initial median filter implementation.
diff --git a/include/filters/GP_Filters.h b/include/filters/GP_Filters.h
index 1bcc6f8..a6a6f92 100644
--- a/include/filters/GP_Filters.h
+++ b/include/filters/GP_Filters.h
@@ -65,4 +65,7 @@
/* Laplace based filters */
#include "filters/GP_Laplace.h"
+/* Median filter */
+#include "filters/GP_Median.h"
+
#endif /* GP_FILTERS_H */
diff --git a/include/filters/GP_Median.h b/include/filters/GP_Median.h
new file mode 100644
index 0000000..891ae70
--- /dev/null
+++ b/include/filters/GP_Median.h
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * 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(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+ /*
+
+ Constant time Median Filter (the computational complexity is independend of
+ radius).
+
+ The xmed and ymed are radius values for x and y. The algorithm uses xmed
+ respectively ymed pixel neighbours from each side so the result is median
+ of rectangle of 2 * xmed + 1 x 2 * ymed + 1 pixels.
+
+ */
+
+#ifndef GP_FILTERS_MEDIAN_H
+#define GP_FILTERS_MEDIAN_H
+
+#include "GP_Filter.h"
+
+int GP_FilterMedianEx(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterMedianExAlloc(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback);
+
+static inline int GP_FilterMedian(const GP_Context *src,
+ GP_Context *dst,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback)
+{
+ return GP_FilterMedianEx(src, 0, 0, src->w, src->h,
+ dst, 0, 0, xmed, ymed, callback);
+}
+
+static inline GP_Context *GP_FilterMedianAlloc(const GP_Context *src,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback)
+{
+ return GP_FilterMedianExAlloc(src, 0, 0, src->w, src->h,
+ xmed, ymed, callback);
+}
+
+#endif /* GP_FILTERS_MEDIAN_H */
diff --git a/libs/filters/GP_Median.c b/libs/filters/GP_Median.c
new file mode 100644
index 0000000..9e60d60
--- /dev/null
+++ b/libs/filters/GP_Median.c
@@ -0,0 +1,228 @@
+/*****************************************************************************
+ * 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(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include "core/GP_Context.h"
+#include "core/GP_GetPutPixel.h"
+#include "core/GP_TempAlloc.h"
+#include "core/GP_Clamp.h"
+
+#include "core/GP_Debug.h"
+
+#include "GP_Median.h"
+
+#include <string.h>
+
+#define HIST_INIT(w) + unsigned int R[w][256]; + unsigned int G[w][256]; + unsigned int B[w][256]; + memset(R, 0, sizeof(R)); + memset(G, 0, sizeof(G)); + memset(B, 0, sizeof(B)); +
+static inline void hist_inc(unsigned int h[][256], unsigned int x, unsigned int val)
+{
+ h[x][val]++;
+}
+
+static inline void hist_dec(unsigned int h[][256], unsigned int x, unsigned int val)
+{
+ h[x][val]--;
+}
+
+static inline void hist_sub(unsigned int *a, unsigned int *b)
+{
+ int j;
+
+ for (j = 0; j < 256; j++)
+ a[j] -= b[j];
+}
+
+static inline void hist_add(unsigned int *a, unsigned int *b)
+{
+ int j;
+
+ for (j = 0; j < 256; j++)
+ a[j] += b[j];
+}
+
+#define HIST_INC hist_inc
+#define HIST_DEC hist_dec
+
+static inline unsigned int hist_median(unsigned int *hist, unsigned int len,
+ unsigned int trigger)
+{
+ unsigned int i;
+ unsigned int acc = 0;
+
+ for (i = 0; i < len; i++) {
+ acc += hist[i];
+ if (acc >= trigger)
+ return i;
+ }
+
+ GP_BUG("Trigger not reached");
+ return 0;
+}
+
+static int GP_FilterMedian_Raw(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback)
+{
+ int i, x, y;
+
+ GP_DEBUG(1, "Median filter size %ux%u xmed=%u ymed=%u",
+ w_src, h_src, 2 * xmed + 1, 2 * ymed + 1);
+
+ /* Create and initalize arrays for row of histograms */
+ /* The buffer is w + 2*xmed + 1 size because we read the last value but we don't use it */
+ HIST_INIT(w_src + 2 * xmed + 1);
+
+ /* Prefill row of histograms */
+ for (x = 0; x < (int)w_src + 2*xmed; x++) {
+ int xi = GP_CLAMP(x_src + x - xmed, 0, (int)src->w - 1);
+
+ for (y = -ymed; y <= ymed; y++) {
+ int yi = GP_CLAMP(y_src + y, 0, (int)src->h - 1);
+
+ GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, xi, yi);
+
+ HIST_INC(R, x, GP_Pixel_GET_R_RGB888(pix));
+ HIST_INC(G, x, GP_Pixel_GET_G_RGB888(pix));
+ HIST_INC(B, x, GP_Pixel_GET_B_RGB888(pix));
+ }
+ }
+
+ /* Apply the median filter */
+ for (y = 0; y < (int)h_src; y++) {
+ unsigned int XR[256], XG[256], XB[256];
+
+ memset(XR, 0, sizeof(XR));
+ memset(XG, 0, sizeof(XG));
+ memset(XB, 0, sizeof(XB));
+
+ /* Compute first histogram */
+ for (i = 0; i <= 2*xmed; i++) {
+ hist_add(XR, R[i]);
+ hist_add(XG, G[i]);
+ hist_add(XB, B[i]);
+ }
+
+ /* Generate row */
+ for (x = 0; x < (int)w_src; x++) {
+ int r = hist_median(XR, 256, (xmed + ymed + 1));
+ int g = hist_median(XG, 256, (xmed + ymed + 1));
+ int b = hist_median(XB, 256, (xmed + ymed + 1));
+
+ GP_PutPixel_Raw_24BPP(dst, x_dst + x, y_dst + y,
+ GP_Pixel_CREATE_RGB888(r, g, b));
+
+ /* Recompute histograms */
+ hist_sub(XR, R[x]);
+ hist_sub(XG, G[x]);
+ hist_sub(XB, B[x]);
+
+ hist_add(XR, R[x + 2 * xmed + 1]);
+ hist_add(XG, G[x + 2 * xmed + 1]);
+ hist_add(XB, B[x + 2 * xmed + 1]);
+ }
+
+ /* Recompute histograms, remove y - ymed pixel add y + ymed + 1 */
+ for (x = 0; x < (int)w_src + 2*xmed; x++) {
+ int xi = GP_CLAMP(x_src + x - xmed, 0, (int)src->w - 1);
+ int yi = GP_CLAMP(y_src + y - ymed, 0, (int)src->h - 1);
+
+ GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, xi, yi);
+
+ HIST_DEC(R, x, GP_Pixel_GET_R_RGB888(pix));
+ HIST_DEC(G, x, GP_Pixel_GET_G_RGB888(pix));
+ HIST_DEC(B, x, GP_Pixel_GET_B_RGB888(pix));
+
+ yi = GP_MIN(y_src + y + ymed + 1, (int)src->h - 1);
+
+ pix = GP_GetPixel_Raw_24BPP(src, xi, yi);
+
+ HIST_INC(R, x, GP_Pixel_GET_R_RGB888(pix));
+ HIST_INC(G, x, GP_Pixel_GET_G_RGB888(pix));
+ HIST_INC(B, x, GP_Pixel_GET_B_RGB888(pix));
+ }
+
+ if (GP_ProgressCallbackReport(callback, y, h_src, w_src)) {
+ // GP_TempAllocFree(temp);
+ return 1;
+ }
+ }
+
+ GP_ProgressCallbackDone(callback);
+
+ return 0;
+}
+
+int GP_FilterMedianEx(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback)
+{
+ GP_CHECK(src->pixel_type == dst->pixel_type);
+
+ /* Check that destination is large enough */
+ GP_CHECK(x_dst + (GP_Coord)w_src <= (GP_Coord)dst->w);
+ GP_CHECK(y_dst + (GP_Coord)h_src <= (GP_Coord)dst->h);
+
+ GP_CHECK(xmed >= 0 && ymed >= 0);
+
+ return GP_FilterMedian_Raw(src, x_src, y_src, w_src, h_src,
+ dst, x_dst, y_dst, xmed, ymed, callback);
+}
+
+GP_Context *GP_FilterMedianExAlloc(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback)
+{
+ int ret;
+
+ GP_CHECK(xmed >= 0 && ymed >= 0);
+
+ GP_Context *dst = GP_ContextAlloc(w_src, h_src, src->pixel_type);
+
+ if (dst == NULL)
+ return NULL;
+
+ ret = GP_FilterMedian_Raw(src, x_src, y_src, w_src, h_src,
+ dst, 0, 0, xmed, ymed, callback);
+
+ if (ret) {
+ GP_ContextFree(dst);
+ return NULL;
+ }
+
+ return dst;
+}
-----------------------------------------------------------------------
Summary of changes:
libs/filters/GP_Median.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 9b8d0d259aedd7b0ce02b082a328f434a7107e5f
by metan 21 Jul '12
by metan 21 Jul '12
21 Jul '12
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 9b8d0d259aedd7b0ce02b082a328f434a7107e5f (commit)
via bc64df2a29e4036cd29f96a77f7a1b14e6d8cea3 (commit)
via 1a0c5677192c818112454a69af5263d9ecd9c890 (commit)
from 0d669b789fdf406909b7030421d57f0c138f42cf (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/9b8d0d259aedd7b0ce02b082a328f434a710…
commit 9b8d0d259aedd7b0ce02b082a328f434a7107e5f
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 21 18:26:07 2012 +0200
filters: Add initial median filter implementation.
diff --git a/include/filters/GP_Filters.h b/include/filters/GP_Filters.h
index 1bcc6f8..a6a6f92 100644
--- a/include/filters/GP_Filters.h
+++ b/include/filters/GP_Filters.h
@@ -65,4 +65,7 @@
/* Laplace based filters */
#include "filters/GP_Laplace.h"
+/* Median filter */
+#include "filters/GP_Median.h"
+
#endif /* GP_FILTERS_H */
diff --git a/include/filters/GP_Median.h b/include/filters/GP_Median.h
new file mode 100644
index 0000000..891ae70
--- /dev/null
+++ b/include/filters/GP_Median.h
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * 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(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+ /*
+
+ Constant time Median Filter (the computational complexity is independend of
+ radius).
+
+ The xmed and ymed are radius values for x and y. The algorithm uses xmed
+ respectively ymed pixel neighbours from each side so the result is median
+ of rectangle of 2 * xmed + 1 x 2 * ymed + 1 pixels.
+
+ */
+
+#ifndef GP_FILTERS_MEDIAN_H
+#define GP_FILTERS_MEDIAN_H
+
+#include "GP_Filter.h"
+
+int GP_FilterMedianEx(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterMedianExAlloc(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback);
+
+static inline int GP_FilterMedian(const GP_Context *src,
+ GP_Context *dst,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback)
+{
+ return GP_FilterMedianEx(src, 0, 0, src->w, src->h,
+ dst, 0, 0, xmed, ymed, callback);
+}
+
+static inline GP_Context *GP_FilterMedianAlloc(const GP_Context *src,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback)
+{
+ return GP_FilterMedianExAlloc(src, 0, 0, src->w, src->h,
+ xmed, ymed, callback);
+}
+
+#endif /* GP_FILTERS_MEDIAN_H */
diff --git a/libs/filters/GP_Median.c b/libs/filters/GP_Median.c
new file mode 100644
index 0000000..0eb3d48
--- /dev/null
+++ b/libs/filters/GP_Median.c
@@ -0,0 +1,226 @@
+/*****************************************************************************
+ * 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(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include "core/GP_Context.h"
+#include "core/GP_GetPutPixel.h"
+#include "core/GP_TempAlloc.h"
+#include "core/GP_Clamp.h"
+
+#include "core/GP_Debug.h"
+
+#include "GP_Median.h"
+
+#include <string.h>
+
+#define HIST_INIT(w) + unsigned int R[w][256]; + unsigned int G[w][256]; + unsigned int B[w][256]; + memset(R, 0, sizeof(R)); + memset(G, 0, sizeof(G)); + memset(B, 0, sizeof(B)); +
+static inline void hist_inc(unsigned int h[][256], unsigned int x, unsigned int val)
+{
+ h[x][val]++;
+}
+
+static inline void hist_dec(unsigned int h[][256], unsigned int x, unsigned int val)
+{
+ h[x][val]--;
+}
+
+static inline void hist_sub(unsigned int *a, unsigned int *b)
+{
+ int j;
+
+ for (j = 0; j < 256; j++)
+ a[j] -= b[j];
+}
+
+static inline void hist_add(unsigned int *a, unsigned int *b)
+{
+ int j;
+
+ for (j = 0; j < 256; j++)
+ a[j] += b[j];
+}
+
+#define HIST_INC hist_inc
+#define HIST_DEC hist_dec
+
+static inline unsigned int hist_median(unsigned int *hist, unsigned int len,
+ unsigned int trigger)
+{
+ unsigned int i;
+ unsigned int acc = 0;
+
+ for (i = 0; i < len; i++) {
+ acc += hist[i];
+ if (acc >= trigger)
+ return i;
+ }
+
+ GP_BUG("Trigger not reached");
+ return 0;
+}
+
+static int GP_FilterMedian_Raw(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback)
+{
+ int i, x, y;
+
+ GP_DEBUG(1, "Median filter size %ux%u xmed=%u ymed=%u",
+ w_src, h_src, 2 * xmed + 1, 2 * ymed + 1);
+
+ /* Create and initalize arrays for row of histograms */
+ /* The buffer is w + 2*xmed + 1 size because we read the last value but we don't use it */
+ HIST_INIT(w_src + 2 * xmed + 1);
+
+ /* Prefill row of histograms */
+ for (x = 0; x < (int)w_src + 2*xmed; x++) {
+ int xi = GP_CLAMP(x_src + x - xmed, 0, (int)src->w - 1);
+
+ for (y = -ymed; y <= ymed; y++) {
+ int yi = GP_CLAMP(y_src + y, 0, (int)src->h - 1);
+
+ GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, xi, yi);
+
+ HIST_INC(R, x, GP_Pixel_GET_R_RGB888(pix));
+ HIST_INC(G, x, GP_Pixel_GET_G_RGB888(pix));
+ HIST_INC(B, x, GP_Pixel_GET_B_RGB888(pix));
+ }
+ }
+
+ /* Apply the median filter */
+ for (y = 0; y < (int)h_src; y++) {
+ unsigned int XR[256], XG[256], XB[256];
+
+ memset(XR, 0, sizeof(XR));
+ memset(XG, 0, sizeof(XG));
+ memset(XB, 0, sizeof(XB));
+
+ /* Compute first histogram */
+ for (i = 0; i <= 2*xmed; i++) {
+ hist_add(XR, R[i]);
+ hist_add(XG, G[i]);
+ hist_add(XB, B[i]);
+ }
+
+ /* Generate row */
+ for (x = 0; x < (int)w_src; x++) {
+ int r = hist_median(XR, 256, (xmed + ymed + 1));
+ int g = hist_median(XG, 256, (xmed + ymed + 1));
+ int b = hist_median(XB, 256, (xmed + ymed + 1));
+
+ GP_PutPixel_Raw_24BPP(dst, x_dst + x, y_dst + y,
+ GP_Pixel_CREATE_RGB888(r, g, b));
+
+ /* Recompute histograms */
+ hist_sub(XR, R[x]);
+ hist_sub(XG, G[x]);
+ hist_sub(XB, B[x]);
+
+ hist_add(XR, R[x + 2 * xmed + 1]);
+ hist_add(XG, G[x + 2 * xmed + 1]);
+ hist_add(XB, B[x + 2 * xmed + 1]);
+ }
+
+ /* Recompute histograms, remove y - ymed pixel add y + ymed + 1 */
+ for (x = 0; x < (int)w_src + 2*xmed; x++) {
+ int xi = GP_CLAMP(x_src + x - xmed, 0, (int)src->w - 1);
+ int yi = GP_CLAMP(y_src + y - ymed, 0, (int)src->h - 1);
+
+ GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, xi, yi);
+
+ HIST_DEC(R, x, GP_Pixel_GET_R_RGB888(pix));
+ HIST_DEC(G, x, GP_Pixel_GET_G_RGB888(pix));
+ HIST_DEC(B, x, GP_Pixel_GET_B_RGB888(pix));
+
+ yi = GP_MIN(y_src + y + ymed + 1, (int)src->h - 1);
+
+ pix = GP_GetPixel_Raw_24BPP(src, xi, yi);
+
+ HIST_INC(R, x, GP_Pixel_GET_R_RGB888(pix));
+ HIST_INC(G, x, GP_Pixel_GET_G_RGB888(pix));
+ HIST_INC(B, x, GP_Pixel_GET_B_RGB888(pix));
+ }
+
+ if (GP_ProgressCallbackReport(callback, y, h_src, w_src)) {
+ // GP_TempAllocFree(temp);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int GP_FilterMedianEx(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback)
+{
+ GP_CHECK(src->pixel_type == dst->pixel_type);
+
+ /* Check that destination is large enough */
+ GP_CHECK(x_dst + (GP_Coord)w_src <= (GP_Coord)dst->w);
+ GP_CHECK(y_dst + (GP_Coord)h_src <= (GP_Coord)dst->h);
+
+ GP_CHECK(xmed >= 0 && ymed >= 0);
+
+ return GP_FilterMedian_Raw(src, x_src, y_src, w_src, h_src,
+ dst, x_dst, y_dst, xmed, ymed, callback);
+}
+
+GP_Context *GP_FilterMedianExAlloc(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ int xmed, int ymed,
+ GP_ProgressCallback *callback)
+{
+ int ret;
+
+ GP_CHECK(xmed >= 0 && ymed >= 0);
+
+ GP_Context *dst = GP_ContextAlloc(w_src, h_src, src->pixel_type);
+
+ if (dst == NULL)
+ return NULL;
+
+ ret = GP_FilterMedian_Raw(src, x_src, y_src, w_src, h_src,
+ dst, 0, 0, xmed, ymed, callback);
+
+ if (ret) {
+ GP_ContextFree(dst);
+ return NULL;
+ }
+
+ return dst;
+}
http://repo.or.cz/w/gfxprim.git/commit/bc64df2a29e4036cd29f96a77f7a1b14e6d8…
commit bc64df2a29e4036cd29f96a77f7a1b14e6d8cea3
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 21 17:03:27 2012 +0200
filters: Linear Convolution: Fix progress computation.
diff --git a/libs/filters/GP_Linear.c b/libs/filters/GP_Linear.c
index ce10271..1655ca8 100644
--- a/libs/filters/GP_Linear.c
+++ b/libs/filters/GP_Linear.c
@@ -126,7 +126,7 @@ int GP_FilterHLinearConvolution_Raw(const GP_Context *src,
GP_Pixel_CREATE_RGB888(r, g, b));
}
- if (GP_ProgressCallbackReport(callback, y, dst->h, dst->w)) {
+ if (GP_ProgressCallbackReport(callback, y, h_src, w_src)) {
GP_TempAllocFree(temp);
return 1;
}
@@ -233,7 +233,7 @@ int GP_FilterVLinearConvolution_Raw(const GP_Context *src,
GP_Pixel_CREATE_RGB888(r, g, b));
}
- if (GP_ProgressCallbackReport(callback, x, dst->w, dst->h)) {
+ if (GP_ProgressCallbackReport(callback, x, w_src, h_src)) {
GP_TempAllocFree(temp);
return 1;
}
@@ -388,7 +388,7 @@ int GP_FilterLinearConvolution_Raw(const GP_Context *src,
idx = 0;
}
- if (GP_ProgressCallbackReport(callback, y, dst->h, dst->w))
+ if (GP_ProgressCallbackReport(callback, y, h_src, w_src))
return 1;
}
http://repo.or.cz/w/gfxprim.git/commit/1a0c5677192c818112454a69af5263d9ecd9…
commit 1a0c5677192c818112454a69af5263d9ecd9c890
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jul 21 14:35:53 2012 +0200
filters: Linear Convolution, another 10% speedup.
This commit saves a few instructions in the inner
cycle making the code a little faster.
diff --git a/libs/filters/GP_Linear.c b/libs/filters/GP_Linear.c
index f06d0f6..ce10271 100644
--- a/libs/filters/GP_Linear.c
+++ b/libs/filters/GP_Linear.c
@@ -41,7 +41,7 @@ int GP_FilterHLinearConvolution_Raw(const GP_Context *src,
{
GP_Coord x, y;
uint32_t i;
- int32_t ikernel[kw], ikern_div;
+ int ikernel[kw], ikern_div;
uint32_t size = w_src + kw - 1;
GP_DEBUG(1, "Horizontal linear convolution kernel width %u "
@@ -103,12 +103,13 @@ int GP_FilterHLinearConvolution_Raw(const GP_Context *src,
for (x = 0; x < (GP_Coord)w_src; x++) {
int32_t r = MUL/2, g = MUL/2, b = MUL/2;
+ int *pR = R + x, *pG = G + x, *pB = B + x;
/* count the pixel value from neighbours weighted by kernel */
for (i = 0; i < kw; i++) {
- r += R[i + x] * ikernel[i];
- g += G[i + x] * ikernel[i];
- b += B[i + x] * ikernel[i];
+ r += (*pR++) * ikernel[i];
+ g += (*pG++) * ikernel[i];
+ b += (*pB++) * ikernel[i];
}
/* divide the result */
@@ -147,7 +148,7 @@ int GP_FilterVLinearConvolution_Raw(const GP_Context *src,
{
GP_Coord x, y;
uint32_t i;
- int32_t ikernel[kh], ikern_div;
+ int ikernel[kh], ikern_div;
uint32_t size = h_src + kh - 1;
for (i = 0; i < kh; i++)
@@ -206,15 +207,16 @@ int GP_FilterVLinearConvolution_Raw(const GP_Context *src,
i++;
}
-
+
for (y = 0; y < (GP_Coord)h_src; y++) {
int32_t r = MUL/2, g = MUL/2, b = MUL/2;
-
+ int *pR = R + y, *pG = G + y, *pB = B + y;
+
/* count the pixel value from neighbours weighted by kernel */
for (i = 0; i < kh; i++) {
- r += R[y + i] * ikernel[i];
- g += G[y + i] * ikernel[i];
- b += B[y + i] * ikernel[i];
+ r += (*pR++) * ikernel[i];
+ g += (*pG++) * ikernel[i];
+ b += (*pB++) * ikernel[i];
}
/* divide the result */
-----------------------------------------------------------------------
Summary of changes:
include/filters/GP_Filters.h | 3 +
.../GP_Dither.c => include/filters/GP_Median.h | 85 +++-----
libs/filters/GP_Linear.c | 28 ++--
libs/filters/GP_Median.c | 226 ++++++++++++++++++++
4 files changed, 279 insertions(+), 63 deletions(-)
copy libs/filters/GP_Dither.c => include/filters/GP_Median.h (53%)
create mode 100644 libs/filters/GP_Median.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 0d669b789fdf406909b7030421d57f0c138f42cf
by metan 12 Jul '12
by metan 12 Jul '12
12 Jul '12
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 0d669b789fdf406909b7030421d57f0c138f42cf (commit)
from 1d8487ab33ea42b4fbf94078f939a6425e664298 (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/0d669b789fdf406909b7030421d57f0c138f…
commit 0d669b789fdf406909b7030421d57f0c138f42cf
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Jul 12 00:05:28 2012 +0200
doc: A few fixes and link.
diff --git a/doc/Makefile b/doc/Makefile
index 443e475..2b6df43 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -10,7 +10,7 @@ all: api.html examples.html $(PAGES) api_links.html
#
# Create all in one API page
#
-api.html: $(SOURCES)
+api.html: $(SOURCES) api.txt
asciidoc -a toc api.txt
#
diff --git a/doc/api.txt b/doc/api.txt
index e57953f..899df1c 100644
--- a/doc/api.txt
+++ b/doc/api.txt
@@ -2,6 +2,9 @@ GFXprim API
===========
Cyril Hrubis <metan(a)ucw.cz>
+This documentation is also available link:api_links.html[divided into several
+pages].
+
include::general.txt[]
include::basic_types.txt[]
include::environment_variables.txt[]
diff --git a/doc/debug.txt b/doc/debug.txt
index dd46820..c86e8a9 100644
--- a/doc/debug.txt
+++ b/doc/debug.txt
@@ -47,5 +47,5 @@ void GP_DebugPrint(int level, const char *file, const char *function, int line,
-------------------------------------------------------------------------------
Printf-like macros used to create debug messages. All of them calls the
-'GP_DebugPrint()' function with correct paramters.
+'GP_DebugPrint()' function with correct parameters.
-----------------------------------------------------------------------
Summary of changes:
doc/Makefile | 2 +-
doc/api.txt | 3 +++
doc/debug.txt | 2 +-
3 files changed, 5 insertions(+), 2 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 1d8487ab33ea42b4fbf94078f939a6425e664298
by metan 11 Jul '12
by metan 11 Jul '12
11 Jul '12
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 1d8487ab33ea42b4fbf94078f939a6425e664298 (commit)
via 2834bc3c2b6e45b7f34f6212407ce7a691dc5486 (commit)
from 34512b0be720afdd2179f65d590881cbd91a14a3 (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/1d8487ab33ea42b4fbf94078f939a6425e66…
commit 1d8487ab33ea42b4fbf94078f939a6425e664298
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Jul 11 23:54:51 2012 +0200
doc: Add docs for debug message layer.
diff --git a/doc/Makefile b/doc/Makefile
index 6329524..443e475 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,6 +1,6 @@
SOURCES=general.txt context.txt loaders.txt filters.txt basic_types.txt drawing_api.txt backends.txt gamma.txt grabbers.txt - environment_variables.txt
+ environment_variables.txt debug.txt
PAGES=$(subst .txt,.html,$(SOURCES))
diff --git a/doc/api.txt b/doc/api.txt
index c955dc6..e57953f 100644
--- a/doc/api.txt
+++ b/doc/api.txt
@@ -5,6 +5,7 @@ Cyril Hrubis <metan(a)ucw.cz>
include::general.txt[]
include::basic_types.txt[]
include::environment_variables.txt[]
+include::debug.txt[]
include::context.txt[]
include::gamma.txt[]
include::drawing_api.txt[]
diff --git a/doc/api_links.txt b/doc/api_links.txt
index fffdf40..2e41996 100644
--- a/doc/api_links.txt
+++ b/doc/api_links.txt
@@ -10,6 +10,10 @@ Also available in link:api.html[all in one page form].
Describes how colors and pixels are handled also describes progress callback
in great detail.
+
+. link:debug.html[Debug Messages]
+ +
+ Interface to debug layer.
+ +
. link:context.html[Context]
+
The Context is description of in-memory bitmap including some meta-data
diff --git a/doc/debug.txt b/doc/debug.txt
new file mode 100644
index 0000000..dd46820
--- /dev/null
+++ b/doc/debug.txt
@@ -0,0 +1,51 @@
+Debug Messages
+--------------
+
+The GFXprim library includes a debug messages infrastructure in order to ease
+debugging.
+
+[source,c]
+-------------------------------------------------------------------------------
+#include <core/GP_Debug.h>
+/* or */
+#include <GP.h>
+
+void GP_SetDebugLevel(unsigned int level);
+
+unsigned int GP_GetDebugLevel(void);
+-------------------------------------------------------------------------------
+
+Sets or gets library debug level. The default level is 0 at which only BUG,
+WARNING, TODO and messages with debug level 0 are shown.
+
+Increasing this number would cause the library to be more verbose in debugging
+messages.
+
+Setting debug level to 1 would expose debug messages when object was created
+or destroyed or when particular algorithm has been started.
+
+Setting debug level to value higher than 1 would expose even more verbose
+messages the current maximum used by debug messages is 4.
+
+
+[source,c]
+-------------------------------------------------------------------------------
+#include <core/GP_Debug.h>
+/* or */
+#include <GP.h>
+
+GP_DEBUG(level, ...)
+
+GP_TODO(...)
+
+GP_WARN(...)
+
+GP_BUG(...)
+
+void GP_DebugPrint(int level, const char *file, const char *function, int line,
+ const char *fmt, ...);
+-------------------------------------------------------------------------------
+
+Printf-like macros used to create debug messages. All of them calls the
+'GP_DebugPrint()' function with correct paramters.
+
http://repo.or.cz/w/gfxprim.git/commit/2834bc3c2b6e45b7f34f6212407ce7a691dc…
commit 2834bc3c2b6e45b7f34f6212407ce7a691dc5486
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Jul 9 14:04:42 2012 +0200
doc: Add docs for environment variables.
diff --git a/doc/Makefile b/doc/Makefile
index 9bc6c52..6329524 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,5 +1,6 @@
SOURCES=general.txt context.txt loaders.txt filters.txt basic_types.txt - drawing_api.txt backends.txt gamma.txt grabbers.txt
+ drawing_api.txt backends.txt gamma.txt grabbers.txt + environment_variables.txt
PAGES=$(subst .txt,.html,$(SOURCES))
diff --git a/doc/api.txt b/doc/api.txt
index 37979b4..c955dc6 100644
--- a/doc/api.txt
+++ b/doc/api.txt
@@ -4,6 +4,7 @@ Cyril Hrubis <metan(a)ucw.cz>
include::general.txt[]
include::basic_types.txt[]
+include::environment_variables.txt[]
include::context.txt[]
include::gamma.txt[]
include::drawing_api.txt[]
diff --git a/doc/api_links.txt b/doc/api_links.txt
index b4ef4d2..fffdf40 100644
--- a/doc/api_links.txt
+++ b/doc/api_links.txt
@@ -15,9 +15,13 @@ Also available in link:api.html[all in one page form].
The Context is description of in-memory bitmap including some meta-data
(size, pixel format, etc...).
+
+. link:environment_variables.html[Environment Variables]
+ +
+ Description of environment variables that affects GFXprim behavior.
+ +
. link:gamma.html[Gamma correction]
+
- The gama correction description and hanlding in GFXprim.
+ The gama correction description and handling in GFXprim.
+
. link:drawing_api.html[Drawing primitives]
+
diff --git a/doc/environment_variables.txt b/doc/environment_variables.txt
new file mode 100644
index 0000000..c120528
--- /dev/null
+++ b/doc/environment_variables.txt
@@ -0,0 +1,23 @@
+Environment Variables
+---------------------
+
+The GFXprim library behavior may be changed by a couple of environment
+variables:
+
+GP_THREADS
+~~~~~~~~~~
+
+'GP_THREADS' overrides GP_NrThreadsSet() settings. The value is the same as it
+would have been set by GP_NrThreadsSet() which is described in the table
+bellow:
+
+.GP_THREADS possible values
+[width="60%",options="header"]
+|=============================================================================
+| Value | Description
+| 0 | Use auto-detection, algorithms runs in nCPU threads unless the image
+ buffer is too small.
+| 1 | Use one thread only.
+| >=2 | Use N threads unless the image buffer is too small.
+|=============================================================================
+
-----------------------------------------------------------------------
Summary of changes:
doc/Makefile | 3 +-
doc/api.txt | 2 +
doc/api_links.txt | 10 +++++++-
doc/debug.txt | 51 +++++++++++++++++++++++++++++++++++++++++
doc/environment_variables.txt | 23 ++++++++++++++++++
5 files changed, 87 insertions(+), 2 deletions(-)
create mode 100644 doc/debug.txt
create mode 100644 doc/environment_variables.txt
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 34512b0be720afdd2179f65d590881cbd91a14a3
by metan 09 Jul '12
by metan 09 Jul '12
09 Jul '12
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 34512b0be720afdd2179f65d590881cbd91a14a3 (commit)
via e99b93446df5bad8ebf42bfb46ed23f5cbb980f0 (commit)
via fb950db4458c54107cd6244ca6f99c330f426bad (commit)
via 3fcb9b04082fb71ce8494a0e2bf880ea3c328d74 (commit)
via 842760824adccff8aef5abac186b0abd8bcda9a7 (commit)
via 3ee0312626982fff7b66086dbe903b6874819b71 (commit)
via ccaf2748930ef9e255019c50b94961f93ff29f69 (commit)
via dc222028aaf265293940f1df9dfd2d65215289a0 (commit)
from 99e04dcfb4af842f3a3be19e62fb52b9ce2ff725 (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/34512b0be720afdd2179f65d590881cbd91a…
commit 34512b0be720afdd2179f65d590881cbd91a14a3
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Jul 9 13:42:32 2012 +0200
pywrap: Update filters.i.
diff --git a/pylib/gfxprim/filters/filters.i b/pylib/gfxprim/filters/filters.i
index e321b1a..dec3bba 100644
--- a/pylib/gfxprim/filters/filters.i
+++ b/pylib/gfxprim/filters/filters.i
@@ -38,7 +38,6 @@
%newobject GP_FilterSymmetry_Alloc;
%include "GP_Rotate.h"
-
%newobject GP_FilterFloydSteinberg_RGB888_Alloc;
%newobject GP_FilterHilbertPeano_RGB888_Alloc;
%include "GP_Dither.h"
@@ -49,3 +48,11 @@
%newobject GP_FilterMaxAlloc;
%newobject GP_FilterMinAlloc;
%include "GP_Arithmetic.h"
+
+%newobject GP_FilterConvolutionAlloc;
+%newobject GP_FilterConvolutionExAlloc;
+%include "GP_Convolution.h"
+
+%newobject GP_FilterBlurAlloc;
+%newobject GP_FilterBlurExAlloc;
+%include "GP_Blur.h"
http://repo.or.cz/w/gfxprim.git/commit/e99b93446df5bad8ebf42bfb46ed23f5cbb9…
commit e99b93446df5bad8ebf42bfb46ed23f5cbb980f0
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Jul 9 13:42:16 2012 +0200
demos: blur.py a minor fix.
diff --git a/demos/py_simple/blur.py b/demos/py_simple/blur.py
index ca50658..36d9c5b 100755
--- a/demos/py_simple/blur.py
+++ b/demos/py_simple/blur.py
@@ -10,7 +10,7 @@ def main():
print("usage: blur blur-radii image")
sys.exit(1)
- radii = int(sys.argv[1])
+ radii = float(sys.argv[1])
# Load Image
img = loaders.LoadImage(sys.argv[2], None)
http://repo.or.cz/w/gfxprim.git/commit/fb950db4458c54107cd6244ca6f99c330f42…
commit fb950db4458c54107cd6244ca6f99c330f426bad
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Jul 9 13:41:44 2012 +0200
core: Add GP_Threads.h into the GP_Core.h.
diff --git a/include/core/GP_Core.h b/include/core/GP_Core.h
index 987196e..cd5555d 100644
--- a/include/core/GP_Core.h
+++ b/include/core/GP_Core.h
@@ -68,6 +68,9 @@
/* Progress callback */
#include "core/GP_ProgressCallback.h"
+/* Threads utils */
+#include "core/GP_Threads.h"
+
/* Debug counters */
#include "core/GP_Counter.h"
http://repo.or.cz/w/gfxprim.git/commit/3fcb9b04082fb71ce8494a0e2bf880ea3c32…
commit 3fcb9b04082fb71ce8494a0e2bf880ea3c328d74
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Jul 9 13:31:41 2012 +0200
doc: Update gaussian filter docs.
diff --git a/doc/filters.txt b/doc/filters.txt
index d9ac4fe..68d7180 100644
--- a/doc/filters.txt
+++ b/doc/filters.txt
@@ -537,7 +537,7 @@ The dst coordinates defines offset into the dst context.
The kernel is two-dimensional array of a size kw * kh indexed as
kernel[x + y*kw].
-The kern_div is a coeficient that is used to divide the resuting values often
+The kern_div is a coefficient that is used to divide the resulting values often
used to normalize the result.
This filter works 'in-place'.
@@ -611,7 +611,7 @@ The dst coordinates are offset into the dst.
The kernel is one-dimensional array of floats of size kw or kh.
-The kern_div is a coeficient that is used to divide the resuting values.
+The kern_div is a coefficient that is used to divide the resulting values.
The last function does both vertical and horizontal convolution and takes care
of correct progress callback.
@@ -699,14 +699,14 @@ GP_Context *GP_FilterConvolutionAlloc(const GP_Context *src,
void GP_FilterKernel2DPrint(const GP_FilterKernel2D *kernel);
-------------------------------------------------------------------------------
-Linear convolution filters, you should prefferably use this API over the _Raw
+Linear convolution filters, you should preferably use this API over the _Raw
variants.
The Ex variants takes a rectangle on which the filter should operate as well
as offset into the destination. The destination must be large enough so that
starting with offset there is at least w_dst and h_dst pixels.
-The kernel is a pointer to a structure initalized with the kernel size, divider
+The kernel is a pointer to a structure initialized with the kernel size, divider
and array of kernel values.
The last function prints convolution kernel in human-readable format into the
@@ -832,19 +832,42 @@ Gaussian Blur
[source,c]
-------------------------------------------------------------------------------
-#include <GP_Filters.h>
+#include <filters/GP_Blur.h>
+/* or */
+#include <GP.h>
-GP_Context *GP_FilterGaussianBlur(const GP_Context *src, GP_Context *dst,
- float sigma_x, float sigma_y,
- GP_ProgressCallback *callback);
--------------------------------------------------------------------------------
+int GP_FilterGaussianBlurEx(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ float x_sigma, float y_sigma,
+ GP_ProgressCallback *callback);
-Gaussian blur filter.
+GP_Context *GP_FilterGaussianBlurExAlloc(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ float x_sigma, float y_sigma,
+ GP_ProgressCallback *callback);
-Works 'in-place'.
+int GP_FilterGaussianBlur(const GP_Context *src, GP_Context *dst,
+ float x_sigma, float y_sigma,
+ GP_ProgressCallback *callback)
-'TODO:' this filter is implemented for RGB888 only.
+GP_Context *GP_FilterGaussianBlurAlloc(const GP_Context *src,
+ float x_sigma, float y_sigma,
+ GP_ProgressCallback *callback)
+-------------------------------------------------------------------------------
+
+Gaussian blur (low pass) filters implemented as bilinear separable
+convolution.
+
+The sigma denotes amount of the blur (the radius is computed accordingly
+automatically).
+The sigma values can be set for vertical and horizontal direction
+independently which may be useful when Gaussian blur is used as a low pass
+filter before image is resampled non proportionally.
Interpolation filters
~~~~~~~~~~~~~~~~~~~~~
@@ -892,7 +915,7 @@ Bilinear Interpolation
^^^^^^^^^^^^^^^^^^^^^^
Bilinear is faster than bicubic interpolation and produces quite good results
-expecially the low pass variant doesn't need additional filter on downsampling.
+especially the low pass variant doesn't need additional filter on down-sampling.
Bicubic Interpolation
^^^^^^^^^^^^^^^^^^^^^
http://repo.or.cz/w/gfxprim.git/commit/842760824adccff8aef5abac186b0abd8bcd…
commit 842760824adccff8aef5abac186b0abd8bcda9a7
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Jul 9 13:09:08 2012 +0200
examples: Minor fixes in convolution.c
diff --git a/demos/c_simple/convolution.c b/demos/c_simple/convolution.c
index e0399e3..bfbd06a 100644
--- a/demos/c_simple/convolution.c
+++ b/demos/c_simple/convolution.c
@@ -69,7 +69,7 @@ int main(int argc, char *argv[])
img = GP_LoadImage(argv[1], &callback);
if (img == NULL) {
- fprintf(stderr, "Failed to load image '%s':%sn", argv[1],
+ fprintf(stderr, "Failed to load image '%s': %sn", argv[1],
strerror(errno));
return 1;
}
@@ -105,7 +105,7 @@ int main(int argc, char *argv[])
priv.name = "out.png";
if (GP_SavePNG(img, "out.png", &callback)) {
- fprintf(stderr, "Failed to save image %s", strerror(errno));
+ fprintf(stderr, "Failed to save image: %s", strerror(errno));
return 1;
}
http://repo.or.cz/w/gfxprim.git/commit/3ee0312626982fff7b66086dbe903b687481…
commit 3ee0312626982fff7b66086dbe903b6874819b71
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Jul 9 13:08:44 2012 +0200
filters: Fix Gaussian Blur API.
diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c
index 1bc7360..a2192b7 100644
--- a/demos/grinder/grinder.c
+++ b/demos/grinder/grinder.c
@@ -420,7 +420,7 @@ static GP_RetCode blur(GP_Context **c, const char *params)
return GP_EINVAL;
}
- GP_FilterGaussianBlur_Raw(*c, *c, sigma_x, sigma_y, progress_callback);
+ GP_FilterGaussianBlur(*c, *c, sigma_x, sigma_y, progress_callback);
return GP_ESUCCESS;
}
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 176fa56..aad96a9 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -314,9 +314,9 @@ GP_Context *load_resized_image(struct loader_params *params, GP_Size w, GP_Size
cpu_timer_start(&timer, "Blur");
callback.priv = "Blurring Image";
- res = GP_FilterGaussianBlur(img, NULL,
- 0.3/params->rat, 0.3/params->rat,
- &callback);
+ res = GP_FilterGaussianBlurAlloc(img, 0.3/params->rat,
+ 0.3/params->rat, &callback);
+
if (res == NULL)
return NULL;
@@ -335,6 +335,8 @@ GP_Context *load_resized_image(struct loader_params *params, GP_Size w, GP_Size
// img = GP_FilterDifferenceAlloc(i2, i1, NULL);
// img = GP_FilterInvert(img, NULL, NULL);
img = i1;
+// if (params->resampling_method == GP_INTERP_CUBIC_INT)
+// GP_FilterEdgeSharpening(img, img, 0.2, NULL);
cpu_timer_stop(&timer);
/* Free low passed context if needed */
diff --git a/include/filters/GP_Blur.h b/include/filters/GP_Blur.h
index 22694bc..fb0ac26 100644
--- a/include/filters/GP_Blur.h
+++ b/include/filters/GP_Blur.h
@@ -32,33 +32,40 @@
#include "GP_Filter.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, ...);
+ * Gaussian blur implemented using linear separable convolution.
+ *
+ * The x_sigma defines the blur size in horizontal direction and y_sigma
+ * defines blur on vertical direction.
*/
-int GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst,
- float sigma_x, float sigma_y,
- GP_ProgressCallback *callback);
-/*
- * 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);
+int GP_FilterGaussianBlurEx(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ float x_sigma, float y_sigma,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterGaussianBlurExAlloc(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ float x_sigma, float y_sigma,
+ GP_ProgressCallback *callback);
+
+static inline int GP_FilterGaussianBlur(const GP_Context *src, GP_Context *dst,
+ float x_sigma, float y_sigma,
+ GP_ProgressCallback *callback)
+{
+ return GP_FilterGaussianBlurEx(src, 0, 0, src->w, src->h, dst, 0, 0,
+ x_sigma, y_sigma, callback);
+}
+
+static inline GP_Context *GP_FilterGaussianBlurAlloc(const GP_Context *src,
+ float x_sigma, float y_sigma,
+ GP_ProgressCallback *callback)
+{
+ return GP_FilterGaussianBlurExAlloc(src, 0, 0, src->w, src->h,
+ x_sigma, y_sigma, callback);
+}
#endif /* FILTERS_GP_BLUR_H */
diff --git a/libs/filters/GP_Blur.c b/libs/filters/GP_Blur.c
index 21aa315..420073e 100644
--- a/libs/filters/GP_Blur.c
+++ b/libs/filters/GP_Blur.c
@@ -69,7 +69,11 @@ static int gaussian_callback_vert(GP_ProgressCallback *self)
return callback->callback(callback);
}
-int GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst,
+int GP_FilterGaussianBlur_Raw(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
float sigma_x, float sigma_y,
GP_ProgressCallback *callback)
{
@@ -77,7 +81,7 @@ int GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst,
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);
+ sigma_x, sigma_y, size_x, size_y, w_src, h_src);
GP_ProgressCallback *new_callback = NULL;
@@ -96,13 +100,13 @@ int GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst,
GP_ConvolutionParams params = {
.src = src,
- .x_src = 0,
- .y_src = 0,
- .w_src = src->w,
- .h_src = src->h,
+ .x_src = x_src,
+ .y_src = y_src,
+ .w_src = w_src,
+ .h_src = h_src,
.dst = dst,
- .x_dst = 0,
- .y_dst = 0,
+ .x_dst = x_dst,
+ .y_dst = y_dst,
.kernel = kernel_x,
.kw = size_x,
.kh = 1,
@@ -124,13 +128,13 @@ int GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst,
GP_ConvolutionParams params = {
.src = src,
- .x_src = 0,
- .y_src = 0,
- .w_src = src->w,
- .h_src = src->h,
+ .x_src = x_src,
+ .y_src = y_src,
+ .w_src = w_src,
+ .h_src = h_src,
.dst = dst,
- .x_dst = 0,
- .y_dst = 0,
+ .x_dst = x_dst,
+ .y_dst = y_dst,
.kernel = kernel_y,
.kw = 1,
.kh = size_y,
@@ -146,27 +150,41 @@ int GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst,
return 0;
}
-GP_Context *GP_FilterGaussianBlur(const GP_Context *src, GP_Context *dst,
- float sigma_x, float sigma_y,
- GP_ProgressCallback *callback)
+int GP_FilterGaussianBlurEx(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ GP_Context *dst,
+ GP_Coord x_dst, GP_Coord y_dst,
+ float sigma_x, float sigma_y,
+ GP_ProgressCallback *callback)
{
- /* TODO: templatetize */
- if (src->pixel_type != GP_PIXEL_RGB888)
- return NULL;
+ GP_CHECK(src->pixel_type == dst->pixel_type);
- 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");
- }
+ /* Check that destination is large enough */
+ GP_CHECK(x_dst + (GP_Coord)w_src <= (GP_Coord)dst->w);
+ GP_CHECK(y_dst + (GP_Coord)h_src <= (GP_Coord)dst->h);
+
+ return GP_FilterGaussianBlur_Raw(src, x_src, y_src, w_src, h_src,
+ dst, x_dst, y_dst,
+ sigma_x, sigma_y, callback);
+}
+
+GP_Context *GP_FilterGaussianBlurExAlloc(const GP_Context *src,
+ GP_Coord x_src, GP_Coord y_src,
+ GP_Size w_src, GP_Size h_src,
+ float sigma_x, float sigma_y,
+ GP_ProgressCallback *callback)
+{
+ GP_Context *dst = GP_ContextAlloc(w_src, h_src, src->pixel_type);
+
+ if (dst == NULL)
+ return NULL;
- GP_FilterGaussianBlur_Raw(src, dst, sigma_x, sigma_y, callback);
+ if (GP_FilterGaussianBlur_Raw(src, x_src, y_src, w_src, h_src, dst,
+ 0, 0, sigma_x, sigma_y, callback)) {
+ GP_ContextFree(dst);
+ return NULL;
+ }
return dst;
}
http://repo.or.cz/w/gfxprim.git/commit/ccaf2748930ef9e255019c50b94961f93ff2…
commit ccaf2748930ef9e255019c50b94961f93ff29f69
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Jul 9 13:00:57 2012 +0200
filters: Fix convolution return value.
diff --git a/libs/filters/GP_Convolution.c b/libs/filters/GP_Convolution.c
index b628cba..7ee3b62 100644
--- a/libs/filters/GP_Convolution.c
+++ b/libs/filters/GP_Convolution.c
@@ -71,5 +71,5 @@ GP_Context *GP_FilterConvolutionExAlloc(const GP_Context *src,
return NULL;
}
- return 0;
+ return ret;
}
http://repo.or.cz/w/gfxprim.git/commit/dc222028aaf265293940f1df9dfd2d652152…
commit dc222028aaf265293940f1df9dfd2d65215289a0
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Jul 9 11:19:39 2012 +0200
doc: A few typo corrections.
diff --git a/doc/context.txt b/doc/context.txt
index 7c812cc..0d1d18b 100644
--- a/doc/context.txt
+++ b/doc/context.txt
@@ -1,8 +1,8 @@
Drawing Context
---------------
-The 'GP_Context' structure describes an 'in memory' memory. It contains all
-metadata needed for drawing into a bitmap.
+The 'GP_Context' structure describes an 'in memory' pixmap. It contains all
+metadata needed for drawing and filters.
Data Structure
~~~~~~~~~~~~~~
-----------------------------------------------------------------------
Summary of changes:
demos/c_simple/convolution.c | 4 +-
demos/grinder/grinder.c | 2 +-
demos/py_simple/blur.py | 2 +-
demos/spiv/spiv.c | 8 ++-
doc/context.txt | 4 +-
doc/filters.txt | 49 +++++++++++++++++------
include/core/GP_Core.h | 3 +
include/filters/GP_Blur.h | 59 ++++++++++++++++------------
libs/filters/GP_Blur.c | 82 +++++++++++++++++++++++---------------
libs/filters/GP_Convolution.c | 2 +-
pylib/gfxprim/filters/filters.i | 9 ++++-
11 files changed, 142 insertions(+), 82 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 99e04dcfb4af842f3a3be19e62fb52b9ce2ff725
by metan 08 Jul '12
by metan 08 Jul '12
08 Jul '12
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
discards 274f579cdeaeeb021e9650e6022c01bb874f7fed (commit)
via 99e04dcfb4af842f3a3be19e62fb52b9ce2ff725 (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (274f579cdeaeeb021e9650e6022c01bb874f7fed)
N -- N -- N (99e04dcfb4af842f3a3be19e62fb52b9ce2ff725)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
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/99e04dcfb4af842f3a3be19e62fb52b9ce2f…
commit 99e04dcfb4af842f3a3be19e62fb52b9ce2ff725
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jul 8 23:24:44 2012 +0200
filters,core: Update in the threads interface.
diff --git a/include/core/GP_ProgressCallback.h b/include/core/GP_ProgressCallback.h
index 818bafa..e944154 100644
--- a/include/core/GP_ProgressCallback.h
+++ b/include/core/GP_ProgressCallback.h
@@ -24,10 +24,11 @@
Progress callback implementation.
- Progress callbacks serves two purposes
+ Progress callbacks serves following purposes:
- ability to visibly show algorithm progress
- ability to correctly abort operation in the middle of processing
+ - ability to override default number of threads to use for the operation
*/
@@ -42,8 +43,20 @@
*/
typedef struct GP_ProgressCallback {
float percentage;
+
int (*callback)(struct GP_ProgressCallback *self);
void *priv;
+
+ /*
+ * Number of threads to use (if supported). This setting could be used
+ * to override the default number of threads as returned by
+ * GP_NrThreads().
+ *
+ * 0 == use number returned from GP_NrThreads().
+ *
+ * >= 1 use exactly n threads
+ */
+ unsigned int threads;
} GP_ProgressCallback;
static inline int GP_ProgressCallbackReport(GP_ProgressCallback *callback,
diff --git a/include/core/GP_Threads.h b/include/core/GP_Threads.h
index 948f278..6cc4be6 100644
--- a/include/core/GP_Threads.h
+++ b/include/core/GP_Threads.h
@@ -26,8 +26,8 @@
*/
-#ifndef GP_THREADS_H
-#define GP_THREADS_H
+#ifndef CORE_GP_THREADS_H
+#define CORE_GP_THREADS_H
#include <pthread.h>
@@ -35,12 +35,31 @@
#include "GP_Types.h"
/*
- * Returns an optimal number of threads for a given image size on a particular
- * machine. Most of the time, if the image is not too small, this function
- * returns number of processors as seen by the operating system.
+ * Sets default number of threads the library uses
+ * (changes the behavior of GP_NrThreads()).
+ *
+ * 0 == auto
+ * Most of the time, if the image is not too small, this makes
+ * the filter run number of processors (as seen by the operating system)
+ * threads.
+ *
+ * 1 == one thread
+ * Everything runs in exactly one thread. This is default value.
+ *
+ * >= 2
+ * Runs exactly n threads unless the image is too small.
+ *
+ * This value may also be overriden by the GP_THREADS enviroment variable.
+ *
+ * Moreover the value may be changed for a single call by settings in progres
+ * callback structure.
*/
-unsigned int GP_NrThreads(GP_Size w, GP_Size h);
+void GP_NrThreadsSet(unsigned int nr);
+/*
+ * Returns a number of threads to use.
+ */
+unsigned int GP_NrThreads(GP_Size w, GP_Size h, GP_ProgressCallback *callback);
/*
* Multithreaded progress callback priv data guarded by a mutex.
@@ -78,4 +97,4 @@ struct GP_ProgressCallbackMPPriv {
*/
int GP_ProgressCallbackMP(GP_ProgressCallback *self);
-#endif /* GP_THREADS_H */
+#endif /* CORE_GP_THREADS_H */
diff --git a/libs/core/GP_Threads.c b/libs/core/GP_Threads.c
index 638f27b..ff59d75 100644
--- a/libs/core/GP_Threads.c
+++ b/libs/core/GP_Threads.c
@@ -21,26 +21,63 @@
*****************************************************************************/
#include <unistd.h>
+#include <stdlib.h>
#include "GP_Common.h"
#include "GP_Debug.h"
#include "GP_Threads.h"
-unsigned int GP_NrThreads(GP_Size w, GP_Size h)
+static unsigned int nr_threads = 1;
+
+unsigned int GP_NrThreads(GP_Size w, GP_Size h, GP_ProgressCallback *callback)
{
- int count = sysconf(_SC_NPROCESSORS_ONLN);
- int threads = GP_MIN(count, (int)(w * h / 1024) + 1);
+ int count, threads;
+ char *env;
+
+ /* Try to override nr_threads from the callback first */
+ if (callback != NULL && callback->threads) {
+ GP_DEBUG(1, "Overriding nr_threads from callback to %i",
+ callback->threads);
+ nr_threads = callback->threads;
+ } else {
+ /* Then try to override it from the enviroment variable */
+ env = getenv("GP_THREADS");
+
+ if (env) {
+ nr_threads = atoi(env);
+ GP_DEBUG(1, "Using GP_THREADS=%u from enviroment "
+ "variable", nr_threads);
+ }
+ }
- if (count < -1)
+ if (nr_threads == 0) {
+ count = sysconf(_SC_NPROCESSORS_ONLN);
+ GP_DEBUG(1, "Found %i CPUs", count);
+ } else {
+ count = nr_threads;
+ GP_DEBUG(1, "Using nr_threads=%i", count);
+ }
+
+ threads = GP_MIN(count, (int)(w * h / 1024) + 1);
+
+ /* Call to the sysconf may return -1 if unsupported */
+ if (threads < -1)
threads = 1;
- GP_DEBUG(1, "Found %u CPUs size %ux%u runnig %u threads",
+ GP_DEBUG(1, "Max threads %i image size %ux%u runnig %u threads",
count, w, h, threads);
return threads;
}
+void GP_NrThreadsSet(unsigned int nr)
+{
+ nr_threads = nr;
+
+ GP_DEBUG(1, "Setting default number of threads to %u", nr);
+}
+
int GP_ProgressCallbackMP(GP_ProgressCallback *self)
{
struct GP_ProgressCallbackMPPriv *priv = self->priv;
diff --git a/libs/filters/GP_LinearThreads.c b/libs/filters/GP_LinearThreads.c
index 9a2aa43..2ab625e 100644
--- a/libs/filters/GP_LinearThreads.c
+++ b/libs/filters/GP_LinearThreads.c
@@ -60,11 +60,14 @@ static void *linear_convolution(void *arg)
int GP_FilterHConvolutionMP_Raw(const GP_ConvolutionParams *params)
{
- int i, t = GP_NrThreads(params->w_src, params->h_src);
+ int i, t = GP_NrThreads(params->w_src, params->h_src, params->callback);
if (t == 1)
return GP_FilterHConvolution_Raw(params);
+ GP_ASSERT(params->src != params->dst,
+ "Multithreaded convolution can't work in-place");
+
GP_PROGRESS_CALLBACK_MP(callback_mp, params->callback);
/* Run t threads */
@@ -105,11 +108,14 @@ int GP_FilterHConvolutionMP_Raw(const GP_ConvolutionParams *params)
int GP_FilterVConvolutionMP_Raw(const GP_ConvolutionParams *params)
{
- int i, t = GP_NrThreads(params->w_src, params->h_src);
+ int i, t = GP_NrThreads(params->w_src, params->h_src, params->callback);
if (t == 1)
return GP_FilterVConvolution_Raw(params);
+ GP_ASSERT(params->src != params->dst,
+ "Multithreaded convolution can't work in-place");
+
GP_PROGRESS_CALLBACK_MP(callback_mp, params->callback);
/* Run t threads */
@@ -149,10 +155,13 @@ int GP_FilterVConvolutionMP_Raw(const GP_ConvolutionParams *params)
int GP_FilterConvolutionMP_Raw(const GP_ConvolutionParams *params)
{
- int i, t = GP_NrThreads(params->w_src, params->h_src);
+ int i, t = GP_NrThreads(params->w_src, params->h_src, params->callback);
if (t == 1)
return GP_FilterConvolution_Raw(params);
+
+ GP_ASSERT(params->src != params->dst,
+ "Multithreaded convolution can't work in-place");
GP_PROGRESS_CALLBACK_MP(callback_mp, params->callback);
-----------------------------------------------------------------------
Summary of changes:
include/core/GP_Threads.h | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 274f579cdeaeeb021e9650e6022c01bb874f7fed
by metan 08 Jul '12
by metan 08 Jul '12
08 Jul '12
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 274f579cdeaeeb021e9650e6022c01bb874f7fed (commit)
via 5355f8de46d21c12f260b08c4774a13993db9701 (commit)
from 00460e85d190a282d97009977cecdc5a6b9c101a (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/274f579cdeaeeb021e9650e6022c01bb874f…
commit 274f579cdeaeeb021e9650e6022c01bb874f7fed
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jul 8 23:24:44 2012 +0200
filters,core: Update in the threads interface.
diff --git a/include/core/GP_ProgressCallback.h b/include/core/GP_ProgressCallback.h
index 818bafa..e944154 100644
--- a/include/core/GP_ProgressCallback.h
+++ b/include/core/GP_ProgressCallback.h
@@ -24,10 +24,11 @@
Progress callback implementation.
- Progress callbacks serves two purposes
+ Progress callbacks serves following purposes:
- ability to visibly show algorithm progress
- ability to correctly abort operation in the middle of processing
+ - ability to override default number of threads to use for the operation
*/
@@ -42,8 +43,20 @@
*/
typedef struct GP_ProgressCallback {
float percentage;
+
int (*callback)(struct GP_ProgressCallback *self);
void *priv;
+
+ /*
+ * Number of threads to use (if supported). This setting could be used
+ * to override the default number of threads as returned by
+ * GP_NrThreads().
+ *
+ * 0 == use number returned from GP_NrThreads().
+ *
+ * >= 1 use exactly n threads
+ */
+ unsigned int threads;
} GP_ProgressCallback;
static inline int GP_ProgressCallbackReport(GP_ProgressCallback *callback,
diff --git a/include/core/GP_Threads.h b/include/core/GP_Threads.h
index 948f278..185ce06 100644
--- a/include/core/GP_Threads.h
+++ b/include/core/GP_Threads.h
@@ -35,12 +35,31 @@
#include "GP_Types.h"
/*
- * Returns an optimal number of threads for a given image size on a particular
- * machine. Most of the time, if the image is not too small, this function
- * returns number of processors as seen by the operating system.
+ * Sets default number of threads the library uses
+ * (changes the behavior of GP_NrThreads()).
+ *
+ * 0 == auto
+ * Most of the time, if the image is not too small, this makes
+ * the filter run number of processors (as seen by the operating system)
+ * threads.
+ *
+ * 1 == one thread
+ * Everything runs in exactly one thread. This is default value.
+ *
+ * >= 2
+ * Runs exactly n threads unless the image is too small.
+ *
+ * This value may also be overriden by GP_THREADS enviroment variable.
+ *
+ * Moreover the value may changed for a single call by settings in progres
+ * callback structure.
*/
-unsigned int GP_NrThreads(GP_Size w, GP_Size h);
+void GP_NrThreadsSet(unsigned int nr);
+/*
+ * Returns a number of threads to use.
+ */
+unsigned int GP_NrThreads(GP_Size w, GP_Size h, GP_ProgressCallback *callback);
/*
* Multithreaded progress callback priv data guarded by a mutex.
diff --git a/libs/core/GP_Threads.c b/libs/core/GP_Threads.c
index 638f27b..ff59d75 100644
--- a/libs/core/GP_Threads.c
+++ b/libs/core/GP_Threads.c
@@ -21,26 +21,63 @@
*****************************************************************************/
#include <unistd.h>
+#include <stdlib.h>
#include "GP_Common.h"
#include "GP_Debug.h"
#include "GP_Threads.h"
-unsigned int GP_NrThreads(GP_Size w, GP_Size h)
+static unsigned int nr_threads = 1;
+
+unsigned int GP_NrThreads(GP_Size w, GP_Size h, GP_ProgressCallback *callback)
{
- int count = sysconf(_SC_NPROCESSORS_ONLN);
- int threads = GP_MIN(count, (int)(w * h / 1024) + 1);
+ int count, threads;
+ char *env;
+
+ /* Try to override nr_threads from the callback first */
+ if (callback != NULL && callback->threads) {
+ GP_DEBUG(1, "Overriding nr_threads from callback to %i",
+ callback->threads);
+ nr_threads = callback->threads;
+ } else {
+ /* Then try to override it from the enviroment variable */
+ env = getenv("GP_THREADS");
+
+ if (env) {
+ nr_threads = atoi(env);
+ GP_DEBUG(1, "Using GP_THREADS=%u from enviroment "
+ "variable", nr_threads);
+ }
+ }
- if (count < -1)
+ if (nr_threads == 0) {
+ count = sysconf(_SC_NPROCESSORS_ONLN);
+ GP_DEBUG(1, "Found %i CPUs", count);
+ } else {
+ count = nr_threads;
+ GP_DEBUG(1, "Using nr_threads=%i", count);
+ }
+
+ threads = GP_MIN(count, (int)(w * h / 1024) + 1);
+
+ /* Call to the sysconf may return -1 if unsupported */
+ if (threads < -1)
threads = 1;
- GP_DEBUG(1, "Found %u CPUs size %ux%u runnig %u threads",
+ GP_DEBUG(1, "Max threads %i image size %ux%u runnig %u threads",
count, w, h, threads);
return threads;
}
+void GP_NrThreadsSet(unsigned int nr)
+{
+ nr_threads = nr;
+
+ GP_DEBUG(1, "Setting default number of threads to %u", nr);
+}
+
int GP_ProgressCallbackMP(GP_ProgressCallback *self)
{
struct GP_ProgressCallbackMPPriv *priv = self->priv;
diff --git a/libs/filters/GP_LinearThreads.c b/libs/filters/GP_LinearThreads.c
index 9a2aa43..2ab625e 100644
--- a/libs/filters/GP_LinearThreads.c
+++ b/libs/filters/GP_LinearThreads.c
@@ -60,11 +60,14 @@ static void *linear_convolution(void *arg)
int GP_FilterHConvolutionMP_Raw(const GP_ConvolutionParams *params)
{
- int i, t = GP_NrThreads(params->w_src, params->h_src);
+ int i, t = GP_NrThreads(params->w_src, params->h_src, params->callback);
if (t == 1)
return GP_FilterHConvolution_Raw(params);
+ GP_ASSERT(params->src != params->dst,
+ "Multithreaded convolution can't work in-place");
+
GP_PROGRESS_CALLBACK_MP(callback_mp, params->callback);
/* Run t threads */
@@ -105,11 +108,14 @@ int GP_FilterHConvolutionMP_Raw(const GP_ConvolutionParams *params)
int GP_FilterVConvolutionMP_Raw(const GP_ConvolutionParams *params)
{
- int i, t = GP_NrThreads(params->w_src, params->h_src);
+ int i, t = GP_NrThreads(params->w_src, params->h_src, params->callback);
if (t == 1)
return GP_FilterVConvolution_Raw(params);
+ GP_ASSERT(params->src != params->dst,
+ "Multithreaded convolution can't work in-place");
+
GP_PROGRESS_CALLBACK_MP(callback_mp, params->callback);
/* Run t threads */
@@ -149,10 +155,13 @@ int GP_FilterVConvolutionMP_Raw(const GP_ConvolutionParams *params)
int GP_FilterConvolutionMP_Raw(const GP_ConvolutionParams *params)
{
- int i, t = GP_NrThreads(params->w_src, params->h_src);
+ int i, t = GP_NrThreads(params->w_src, params->h_src, params->callback);
if (t == 1)
return GP_FilterConvolution_Raw(params);
+
+ GP_ASSERT(params->src != params->dst,
+ "Multithreaded convolution can't work in-place");
GP_PROGRESS_CALLBACK_MP(callback_mp, params->callback);
http://repo.or.cz/w/gfxprim.git/commit/5355f8de46d21c12f260b08c4774a13993db…
commit 5355f8de46d21c12f260b08c4774a13993db9701
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jul 8 13:12:52 2012 +0200
filters: Simplify multithreaded filters.
* Move the common code to the core
* Pack the linear convolution paraters into the
structure by default.
diff --git a/include/core/GP_ProgressCallback.h b/include/core/GP_ProgressCallback.h
index 72857ce..818bafa 100644
--- a/include/core/GP_ProgressCallback.h
+++ b/include/core/GP_ProgressCallback.h
@@ -69,4 +69,10 @@ static inline void GP_ProgressCallbackDone(GP_ProgressCallback *callback)
callback->callback(callback);
}
+#define GP_PROGRESS_CALLBACK(name, pcallback, ppriv) + GP_ProgressCallback name = { + .callback = pcallback, + .priv = ppriv, + };
+
#endif /* CORE_GP_PROGRESSCALBACK_H */
diff --git a/include/filters/GP_LinearThreads.h b/include/core/GP_Threads.h
similarity index 51%
copy from include/filters/GP_LinearThreads.h
copy to include/core/GP_Threads.h
index 76c46db..948f278 100644
--- a/include/filters/GP_LinearThreads.h
+++ b/include/core/GP_Threads.h
@@ -20,33 +20,62 @@
* *
*****************************************************************************/
-#ifndef FILTERS_GP_LINEAR_THREADS_H
-#define FILTERS_GP_LINEAR_THREADS_H
-
-#include "GP_Filter.h"
-
-int GP_FilterLinearConvolutionMP_Raw(const GP_Context *src,
- GP_Coord x_src, GP_Coord y_src,
- GP_Size w_src, GP_Size h_src,
- GP_Context *dst,
- GP_Coord x_dst, GP_Coord y_dst,
- float kernel[], uint32_t kw, uint32_t kh,
- float kern_div, GP_ProgressCallback *callback);
-
-int GP_FilterHLinearConvolutionMP_Raw(const GP_Context *src,
- GP_Coord x_src, GP_Coord y_src,
- GP_Size w_src, GP_Size h_src,
- GP_Context *dst,
- GP_Coord x_dst, GP_Coord y_dst,
- float kernel[], uint32_t kw, float kern_div,
- GP_ProgressCallback *callback);
-
-int GP_FilterVLinearConvolutionMP_Raw(const GP_Context *src,
- GP_Coord x_src, GP_Coord y_src,
- GP_Size w_src, GP_Size h_src,
- GP_Context *dst,
- GP_Coord x_dst, GP_Coord y_dst,
- float kernel[], uint32_t kh, float kern_div,
- GP_ProgressCallback *callback);
-
-#endif /* FILTERS_GP_LINEAR_THREADS_H */
+ /*
+
+ A code to ease multithreaded filters and more.
+
+ */
+
+#ifndef GP_THREADS_H
+#define GP_THREADS_H
+
+#include <pthread.h>
+
+#include "GP_ProgressCallback.h"
+#include "GP_Types.h"
+
+/*
+ * Returns an optimal number of threads for a given image size on a particular
+ * machine. Most of the time, if the image is not too small, this function
+ * returns number of processors as seen by the operating system.
+ */
+unsigned int GP_NrThreads(GP_Size w, GP_Size h);
+
+
+/*
+ * Multithreaded progress callback priv data guarded by a mutex.
+ */
+struct GP_ProgressCallbackMPPriv {
+ float max;
+ int abort;
+ pthread_mutex_t mutex;
+ GP_ProgressCallback *orig_callback;
+};
+
+/*
+ * Creates and initalizes a on-the-stack progress callback
+ *
+ * The intended usage is:
+ *
+ * GP_PROGRESS_CALLBACK(callback_mp, orig_callback);
+ *
+ * ...
+ *
+ * for n threads:
+ * run_filter(..., callback ? &callback_mp : NULL);
+ */
+#define GP_PROGRESS_CALLBACK_MP(name, callback) + struct GP_ProgressCallbackMPPriv name_priv = { + .max = 0, + .abort = 0, + .mutex = PTHREAD_MUTEX_INITIALIZER, + .orig_callback = callback, + }; + GP_PROGRESS_CALLBACK(name, GP_ProgressCallbackMP, &name_priv);
+
+/*
+ * Multithreaded callback function itself.
+ */
+int GP_ProgressCallbackMP(GP_ProgressCallback *self);
+
+#endif /* GP_THREADS_H */
diff --git a/include/filters/GP_Linear.h b/include/filters/GP_Linear.h
index ae96e34..fe938f5 100644
--- a/include/filters/GP_Linear.h
+++ b/include/filters/GP_Linear.h
@@ -53,8 +53,6 @@
* kw = kh = 3
*
* kern_div = 9
- *
- * This function works also in-place.
*/
int GP_FilterLinearConvolution_Raw(const GP_Context *src,
GP_Coord x_src, GP_Coord y_src,
@@ -109,4 +107,59 @@ int GP_FilterVHLinearConvolution_Raw(const GP_Context *src,
*/
void GP_FilterKernelPrint_Raw(float kernel[], int kw, int kh, float kern_div);
+
+
+typedef struct GP_ConvolutionParams {
+ const GP_Context *src;
+ GP_Coord x_src;
+ GP_Coord y_src;
+ GP_Size w_src;
+ GP_Size h_src;
+
+ GP_Context *dst;
+ GP_Coord x_dst;
+ GP_Coord y_dst;
+
+ float *kernel;
+ unsigned int kw;
+ unsigned int kh;
+ float kern_div;
+
+ GP_ProgressCallback *callback;
+} GP_ConvolutionParams;
+
+static inline int GP_FilterConvolution_Raw(const struct GP_ConvolutionParams *params)
+{
+ return GP_FilterLinearConvolution_Raw(params->src, params->x_src,
+ params->y_src, params->w_src,
+ params->h_src, params->dst,
+ params->x_dst, params->y_dst,
+ params->kernel, params->kw,
+ params->kh, params->kern_div,
+ params->callback);
+}
+
+static inline int GP_FilterVConvolution_Raw(const struct GP_ConvolutionParams *params)
+{
+
+ return GP_FilterVLinearConvolution_Raw(params->src, params->x_src,
+ params->y_src, params->w_src,
+ params->h_src, params->dst,
+ params->x_dst, params->y_dst,
+ params->kernel, params->kh,
+ params->kern_div,
+ params->callback);
+}
+
+static inline int GP_FilterHConvolution_Raw(const struct GP_ConvolutionParams *params)
+{
+ return GP_FilterHLinearConvolution_Raw(params->src, params->x_src,
+ params->y_src, params->w_src,
+ params->h_src, params->dst,
+ params->x_dst, params->y_dst,
+ params->kernel, params->kw,
+ params->kern_div,
+ params->callback);
+}
+
#endif /* FILTERS_GP_LINEAR_H */
diff --git a/include/filters/GP_LinearThreads.h b/include/filters/GP_LinearThreads.h
index 76c46db..ee4d0fc 100644
--- a/include/filters/GP_LinearThreads.h
+++ b/include/filters/GP_LinearThreads.h
@@ -24,29 +24,13 @@
#define FILTERS_GP_LINEAR_THREADS_H
#include "GP_Filter.h"
+#include "GP_Linear.h"
-int GP_FilterLinearConvolutionMP_Raw(const GP_Context *src,
- GP_Coord x_src, GP_Coord y_src,
- GP_Size w_src, GP_Size h_src,
- GP_Context *dst,
- GP_Coord x_dst, GP_Coord y_dst,
- float kernel[], uint32_t kw, uint32_t kh,
- float kern_div, GP_ProgressCallback *callback);
+int GP_FilterConvolutionMP_Raw(const GP_ConvolutionParams *params);
-int GP_FilterHLinearConvolutionMP_Raw(const GP_Context *src,
- GP_Coord x_src, GP_Coord y_src,
- GP_Size w_src, GP_Size h_src,
- GP_Context *dst,
- GP_Coord x_dst, GP_Coord y_dst,
- float kernel[], uint32_t kw, float kern_div,
- GP_ProgressCallback *callback);
+int GP_FilterVConvolutionMP_Raw(const GP_ConvolutionParams *params);
+
+int GP_FilterHConvolutionMP_Raw(const GP_ConvolutionParams *params);
-int GP_FilterVLinearConvolutionMP_Raw(const GP_Context *src,
- GP_Coord x_src, GP_Coord y_src,
- GP_Size w_src, GP_Size h_src,
- GP_Context *dst,
- GP_Coord x_dst, GP_Coord y_dst,
- float kernel[], uint32_t kh, float kern_div,
- GP_ProgressCallback *callback);
#endif /* FILTERS_GP_LINEAR_THREADS_H */
diff --git a/include/core/GP_ProgressCallback.h b/libs/core/GP_Threads.c
similarity index 58%
copy from include/core/GP_ProgressCallback.h
copy to libs/core/GP_Threads.c
index 72857ce..638f27b 100644
--- a/include/core/GP_ProgressCallback.h
+++ b/libs/core/GP_Threads.c
@@ -16,57 +16,58 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
-/*
+#include <unistd.h>
- Progress callback implementation.
+#include "GP_Common.h"
+#include "GP_Debug.h"
- Progress callbacks serves two purposes
+#include "GP_Threads.h"
- - ability to visibly show algorithm progress
- - ability to correctly abort operation in the middle of processing
+unsigned int GP_NrThreads(GP_Size w, GP_Size h)
+{
+ int count = sysconf(_SC_NPROCESSORS_ONLN);
+ int threads = GP_MIN(count, (int)(w * h / 1024) + 1);
- */
+ if (count < -1)
+ threads = 1;
-#ifndef CORE_GP_PROGRESSCALLBACK_H
-#define CORE_GP_PROGRESSCALLBACK_H
+ GP_DEBUG(1, "Found %u CPUs size %ux%u runnig %u threads",
+ count, w, h, threads);
-/*
- * Progress callback
- *
- * Non zero return value from callback will abort current operation
- * free memory and return NULL from filter/loader...
- */
-typedef struct GP_ProgressCallback {
- float percentage;
- int (*callback)(struct GP_ProgressCallback *self);
- void *priv;
-} GP_ProgressCallback;
+ return threads;
+}
-static inline int GP_ProgressCallbackReport(GP_ProgressCallback *callback,
- unsigned int val, unsigned int max,
- unsigned int mul __attribute__((unused)))
+int GP_ProgressCallbackMP(GP_ProgressCallback *self)
{
- if (callback == NULL)
- return 0;
+ struct GP_ProgressCallbackMPPriv *priv = self->priv;
- if (val % 100)
+ /*
+ * If any thread got non-zero return value from a callback abort all.
+ */
+ if (priv->abort)
+ return 1;
+
+ if (pthread_mutex_trylock(&priv->mutex)) {
+ GP_DEBUG(1, "Mutex locked, skipping calllback.");
return 0;
+ }
- callback->percentage = 100.00 * val / max;
- return callback->callback(callback);
-}
+ /* Compute max value for the percentage */
+ priv->orig_callback->percentage = GP_MAX(self->percentage, priv->max);
+ priv->max = priv->orig_callback->percentage;
-static inline void GP_ProgressCallbackDone(GP_ProgressCallback *callback)
-{
- if (callback == NULL)
- return;
+ /* Call the original callback */
+ int ret = priv->orig_callback->callback(priv->orig_callback);
- callback->percentage = 100;
- callback->callback(callback);
-}
+ /* Turn on abort flag if callback returned nonzero */
+ if (ret)
+ priv->abort = 1;
-#endif /* CORE_GP_PROGRESSCALBACK_H */
+ pthread_mutex_unlock(&priv->mutex);
+
+ return ret;
+}
diff --git a/libs/filters/GP_Blur.c b/libs/filters/GP_Blur.c
index 22b99fd..21aa315 100644
--- a/libs/filters/GP_Blur.c
+++ b/libs/filters/GP_Blur.c
@@ -25,6 +25,7 @@
#include "core/GP_Debug.h"
#include "GP_Linear.h"
+#include "GP_LinearThreads.h"
#include "GP_Blur.h"
@@ -92,10 +93,24 @@ int GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst,
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))
+
+ GP_ConvolutionParams params = {
+ .src = src,
+ .x_src = 0,
+ .y_src = 0,
+ .w_src = src->w,
+ .h_src = src->h,
+ .dst = dst,
+ .x_dst = 0,
+ .y_dst = 0,
+ .kernel = kernel_x,
+ .kw = size_x,
+ .kh = 1,
+ .kern_div = sum,
+ .callback = new_callback,
+ };
+
+ if (GP_FilterHConvolutionMP_Raw(¶ms))
return 1;
}
@@ -107,9 +122,23 @@ int GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst,
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))
+ GP_ConvolutionParams params = {
+ .src = src,
+ .x_src = 0,
+ .y_src = 0,
+ .w_src = src->w,
+ .h_src = src->h,
+ .dst = dst,
+ .x_dst = 0,
+ .y_dst = 0,
+ .kernel = kernel_y,
+ .kw = 1,
+ .kh = size_y,
+ .kern_div = sum,
+ .callback = new_callback,
+ };
+
+ if (GP_FilterVConvolutionMP_Raw(¶ms))
return 1;
}
diff --git a/libs/filters/GP_Edge.c b/libs/filters/GP_Edge.c
index a9a42a6..349c36b 100644
--- a/libs/filters/GP_Edge.c
+++ b/libs/filters/GP_Edge.c
@@ -57,24 +57,54 @@ static int prewitt(const GP_Context *src, GP_Context *dx, GP_Context *dy,
static int sobel(const GP_Context *src, GP_Context *dx, GP_Context *dy,
GP_ProgressCallback *callback)
{
- float x_kern[] = {
+ float dx_kern[] = {
-1, 0, 1,
-2, 0, 2,
-1, 0, 1,
};
- if (GP_FilterLinearConvolution_Raw(src, 0, 0, src->w, src->h,
- dx, 0, 0, x_kern, 3, 3, 32, callback))
+ GP_ConvolutionParams dx_conv = {
+ .src = src,
+ .x_src = 0,
+ .y_src = 0,
+ .w_src = src->w,
+ .h_src = src->h,
+ .dst = dx,
+ .x_dst = 0,
+ .y_dst = 0,
+ .kernel = dx_kern,
+ .kw = 3,
+ .kh = 3,
+ .kern_div = 1,
+ .callback = callback,
+ };
+
+ if (GP_FilterConvolution_Raw(&dx_conv))
return 1;
- float y_kern[] = {
+ float dy_kern[] = {
-1, -2, -1,
0, 0, 0,
1, 2, 1,
};
+
+ GP_ConvolutionParams dy_conv = {
+ .src = src,
+ .x_src = 0,
+ .y_src = 0,
+ .w_src = src->w,
+ .h_src = src->h,
+ .dst = dy,
+ .x_dst = 0,
+ .y_dst = 0,
+ .kernel = dy_kern,
+ .kw = 3,
+ .kh = 3,
+ .kern_div = 1,
+ .callback = callback,
+ };
- if (GP_FilterLinearConvolution_Raw(src, 0, 0, src->w, src->h,
- dy, 0, 0, y_kern, 3, 3, 32, callback))
+ if (GP_FilterConvolution_Raw(&dy_conv))
return 1;
return 0;
@@ -133,7 +163,7 @@ static int edge_detect(const GP_Context *src,
GP_PutPixel_Raw_24BPP(dx, i, j,
GP_Pixel_CREATE_RGB888(RE, GE, BE));
-
+
if (Rx != 0 && Ry != 0)
RPhi = ((atan2(Rx, Ry) + M_PI) * 255)/(2*M_PI);
else
diff --git a/libs/filters/GP_LinearThreads.c b/libs/filters/GP_LinearThreads.c
index 5ccdebc..9a2aa43 100644
--- a/libs/filters/GP_LinearThreads.c
+++ b/libs/filters/GP_LinearThreads.c
@@ -26,189 +26,65 @@
#include "core/GP_Common.h"
#include "core/GP_Debug.h"
+#include "core/GP_Threads.h"
#include "GP_Linear.h"
#include "GP_LinearThreads.h"
-static int nr_threads(GP_Size w, GP_Size h)
-{
- int count = sysconf(_SC_NPROCESSORS_ONLN);
- int threads = GP_MIN(count, (int)(w * h / 1024) + 1);
-
- if (count < -1)
- threads = 1;
-
- GP_DEBUG(1, "Found %u CPUs size %ux%u runnig %u threads",
- count, w, h, threads);
-
- return threads;
-}
-
-/*
- * Multithreaded callback wrapper.
- */
-struct callback_priv {
- float max;
- int abort;
- unsigned int nr_threads;
- pthread_mutex_t mutex;
- GP_ProgressCallback *orig_callback;
-};
-
-static int progress_callback_mp(GP_ProgressCallback *self)
+static void *h_linear_convolution(void *arg)
{
- struct callback_priv *priv = self->priv;
+ struct GP_ConvolutionParams *params = arg;
- /* If any thread got non-zero return value from a callback, abort all */
- if (priv->abort)
- return 1;
-
- if (pthread_mutex_trylock(&priv->mutex)) {
- GP_DEBUG(1, "Mutex locked, skipping calllback.");
- return 0;
- }
-
- /* Compute max value for the percentage */
- priv->orig_callback->percentage = GP_MAX(self->percentage, priv->max);
- priv->max = priv->orig_callback->percentage;
-
- /* Call the original callback */
- int ret = priv->orig_callback->callback(priv->orig_callback);
+ long ret = GP_FilterHConvolution_Raw(params);
- /* Turn on abort flag if callback returned nonzero */
- if (ret)
- priv->abort = 1;
-
- pthread_mutex_unlock(&priv->mutex);
-
- return ret;
-}
-
-static void callback_priv_init(struct callback_priv *priv, int nr_threads,
- GP_ProgressCallback *orig_callback)
-{
- priv->nr_threads = nr_threads;
- priv->orig_callback = orig_callback;
- priv->max = 0;
- priv->abort = 0;
- pthread_mutex_init(&priv->mutex, NULL);
+ return (void*)ret;
}
-static void callback_priv_exit(struct callback_priv *priv)
+static void *v_linear_convolution(void *arg)
{
- pthread_mutex_destroy(&priv->mutex);
-}
-
-/*
- * This code just packs and unpacks convolution parameters.
- */
-struct convolution {
- const GP_Context *src;
- GP_Coord x_src;
- GP_Coord y_src;
- GP_Size w_src;
- GP_Size h_src;
+ struct GP_ConvolutionParams *params = arg;
- GP_Context *dst;
- GP_Coord x_dst;
- GP_Coord y_dst;
-
- float *kernel;
- unsigned int ks;
- float kern_div;
-
- GP_ProgressCallback *callback;
-};
-
-static void convolution_init(struct convolution *conv, const GP_Context *src,
- GP_Coord x_src, GP_Coord y_src,
- GP_Size w_src, GP_Size h_src,
- GP_Context *dst, GP_Coord x_dst, GP_Coord y_dst,
- float kernel[], unsigned int ks, float kern_div,
- GP_ProgressCallback *callback)
-{
- conv->src = src;
- conv->x_src = x_src;
- conv->y_src = y_src;
- conv->w_src = w_src;
- conv->h_src = h_src;
- conv->dst = dst;
- conv->x_dst = x_dst;
- conv->y_dst = y_dst;
- conv->kernel = kernel;
- conv->ks = ks;
- conv->kern_div = kern_div;
- conv->callback = callback;
-}
-
-static void *h_linear_convolution(void *arg)
-{
- struct convolution *conv = arg;
-
- long ret;
+ long ret = GP_FilterVConvolution_Raw(params);
- ret = GP_FilterHLinearConvolution_Raw(conv->src, conv->x_src, conv->y_src,
- conv->w_src, conv->h_src, conv->dst,
- conv->x_dst, conv->y_dst, conv->kernel,
- conv->ks, conv->kern_div, conv->callback);
return (void*)ret;
}
-static void *v_linear_convolution(void *arg)
+static void *linear_convolution(void *arg)
{
- struct convolution *conv = arg;
-
- long ret;
+ struct GP_ConvolutionParams *params = arg;
+
+ long ret = GP_FilterConvolution_Raw(params);
- ret = GP_FilterVLinearConvolution_Raw(conv->src, conv->x_src, conv->y_src,
- conv->w_src, conv->h_src, conv->dst,
- conv->x_dst, conv->y_dst, conv->kernel,
- conv->ks, conv->kern_div, conv->callback);
return (void*)ret;
}
-
-int GP_FilterHLinearConvolutionMP_Raw(const GP_Context *src,
- GP_Coord x_src, GP_Coord y_src,
- GP_Size w_src, GP_Size h_src,
- GP_Context *dst,
- GP_Coord x_dst, GP_Coord y_dst,
- float kernel[], uint32_t kw, float kern_div,
- GP_ProgressCallback *callback)
+int GP_FilterHConvolutionMP_Raw(const GP_ConvolutionParams *params)
{
- int t = nr_threads(w_src, h_src);
-
- if (t == 1) {
- return GP_FilterHLinearConvolution_Raw(src, x_src, y_src,
- w_src, h_src,
- dst, x_dst, y_dst,
- kernel, kw, kern_div,
- callback);
- }
+ int i, t = GP_NrThreads(params->w_src, params->h_src);
+
+ if (t == 1)
+ return GP_FilterHConvolution_Raw(params);
- /* Create multithreaded safe callback on the stack */
- struct callback_priv priv;
- callback_priv_init(&priv, t, callback);
- GP_ProgressCallback callback_mp = {0, progress_callback_mp, &priv};
+ GP_PROGRESS_CALLBACK_MP(callback_mp, params->callback);
/* Run t threads */
- int i;
pthread_t threads[t];
- struct convolution convs[t];
- GP_Size h = h_src/t;
+ struct GP_ConvolutionParams convs[t];
+ GP_Size h = params->h_src/t;
for (i = 0; i < t; i++) {
- GP_Coord y_src_2 = y_src + i * h;
- GP_Coord y_dst_2 = y_dst + i * h;
+ GP_Coord y_src_2 = params->y_src + i * h;
+ GP_Coord y_dst_2 = params->y_dst + i * h;
GP_Size h_src_2 = h;
if (i == t - 1)
- h_src_2 = h_src - i * h;
+ h_src_2 = params->h_src - i * h;
- /* Pack convolution parameters into the structure */
- convolution_init(&convs[i], src, x_src, y_src_2, w_src, h_src_2,
- dst, x_dst, y_dst_2, kernel, kw, kern_div,
- callback ? &callback_mp : NULL);
+ convs[i] = *params;
+ convs[i].y_src = y_src_2;
+ convs[i].h_src = h_src_2;
+ convs[i].y_dst = y_dst_2;
+ convs[i].callback = params->callback ? &callback_mp : NULL;
pthread_create(&threads[i], NULL, h_linear_convolution, &convs[i]);
}
@@ -223,52 +99,37 @@ int GP_FilterHLinearConvolutionMP_Raw(const GP_Context *src,
ret |= (int)r;
}
- callback_priv_exit(&priv);
-
return ret;
}
-int GP_FilterVLinearConvolutionMP_Raw(const GP_Context *src,
- GP_Coord x_src, GP_Coord y_src,
- GP_Size w_src, GP_Size h_src,
- GP_Context *dst,
- GP_Coord x_dst, GP_Coord y_dst,
- float kernel[], uint32_t kh, float kern_div,
- GP_ProgressCallback *callback)
+int GP_FilterVConvolutionMP_Raw(const GP_ConvolutionParams *params)
{
- int t = nr_threads(w_src, h_src);
-
- if (t == 1) {
- return GP_FilterVLinearConvolution_Raw(src, x_src, y_src,
- w_src, h_src,
- dst, x_dst, y_dst,
- kernel, kh, kern_div,
- callback);
- }
+ int i, t = GP_NrThreads(params->w_src, params->h_src);
+
+ if (t == 1)
+ return GP_FilterVConvolution_Raw(params);
- /* Create multithreaded safe callback on the stack */
- struct callback_priv priv;
- callback_priv_init(&priv, t, callback);
- GP_ProgressCallback callback_mp = {0, progress_callback_mp, &priv};
+ GP_PROGRESS_CALLBACK_MP(callback_mp, params->callback);
- int i;
+ /* Run t threads */
pthread_t threads[t];
- struct convolution convs[t];
- GP_Size h = h_src/t;
+ struct GP_ConvolutionParams convs[t];
+ GP_Size h = params->h_src/t;
for (i = 0; i < t; i++) {
- GP_Coord y_src_2 = y_src + i * h;
- GP_Coord y_dst_2 = y_dst + i * h;
+ GP_Coord y_src_2 = params->y_src + i * h;
+ GP_Coord y_dst_2 = params->y_dst + i * h;
GP_Size h_src_2 = h;
if (i == t - 1)
- h_src_2 = h_src - i * h;
-
- /* Pack convolution parameters into the structure */
- convolution_init(&convs[i], src, x_src, y_src_2, w_src, h_src_2,
- dst, x_dst, y_dst_2, kernel, kh, kern_div,
- callback ? &callback_mp : NULL);
+ h_src_2 = params->h_src - i * h;
+
+ convs[i] = *params;
+ convs[i].y_src = y_src_2;
+ convs[i].h_src = h_src_2;
+ convs[i].y_dst = y_dst_2;
+ convs[i].callback = params->callback ? &callback_mp : NULL;
pthread_create(&threads[i], NULL, v_linear_convolution, &convs[i]);
}
@@ -282,19 +143,49 @@ int GP_FilterVLinearConvolutionMP_Raw(const GP_Context *src,
ret |= (int)r;
}
- callback_priv_exit(&priv);
-
return ret;
}
-/*
-int GP_FilterLinearConvolutionMP_Raw(const GP_Context *src,
- GP_Coord x_src, GP_Coord y_src,
- GP_Size w_src, GP_Size h_src,
- GP_Context *dst,
- GP_Coord x_dst, GP_Coord y_dst,
- float kernel[], uint32_t kw, uint32_t kh,
- float kern_div, GP_ProgressCallback *callback)
+
+int GP_FilterConvolutionMP_Raw(const GP_ConvolutionParams *params)
{
+ int i, t = GP_NrThreads(params->w_src, params->h_src);
+
+ if (t == 1)
+ return GP_FilterConvolution_Raw(params);
+
+ GP_PROGRESS_CALLBACK_MP(callback_mp, params->callback);
+
+ /* Run t threads */
+ pthread_t threads[t];
+ struct GP_ConvolutionParams convs[t];
+ GP_Size h = params->h_src/t;
+
+ for (i = 0; i < t; i++) {
+ GP_Coord y_src_2 = params->y_src + i * h;
+ GP_Coord y_dst_2 = params->y_dst + i * h;
+ GP_Size h_src_2 = h;
+
+ if (i == t - 1)
+ h_src_2 = params->h_src - i * h;
+
+ convs[i] = *params;
+ convs[i].y_src = y_src_2;
+ convs[i].h_src = h_src_2;
+ convs[i].y_dst = y_dst_2;
+ convs[i].callback = params->callback ? &callback_mp : NULL;
+
+ pthread_create(&threads[i], NULL, linear_convolution, &convs[i]);
+ }
+
+ int ret = 0;
+
+ for (i = 0; i < t; i++) {
+ long r;
+ pthread_join(threads[i], (void*)&r);
+
+ ret |= (int)r;
+ }
+
+ return ret;
}
-*/
-----------------------------------------------------------------------
Summary of changes:
include/core/GP_ProgressCallback.h | 21 +++-
include/core/GP_Threads.h | 100 ++++++++++++
include/filters/GP_Linear.h | 57 +++++++-
include/filters/GP_LinearThreads.h | 26 +---
libs/core/GP_Threads.c | 110 ++++++++++++++
libs/filters/GP_Blur.c | 43 +++++-
libs/filters/GP_Edge.c | 44 +++++-
libs/filters/GP_LinearThreads.c | 290 ++++++++++++------------------------
8 files changed, 458 insertions(+), 233 deletions(-)
create mode 100644 include/core/GP_Threads.h
create mode 100644 libs/core/GP_Threads.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 00460e85d190a282d97009977cecdc5a6b9c101a
by metan 06 Jul '12
by metan 06 Jul '12
06 Jul '12
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 00460e85d190a282d97009977cecdc5a6b9c101a (commit)
via 14fa043cbe2545c0970092ffaef9ead7ef29fe02 (commit)
from b7b1aa5e558261c0787fad6e924969625cd465ce (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/00460e85d190a282d97009977cecdc5a6b9c…
commit 00460e85d190a282d97009977cecdc5a6b9c101a
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jul 6 15:51:15 2012 +0200
doc: Generate page per topic docs too.
diff --git a/doc/Makefile b/doc/Makefile
index 7eb952d..9bc6c52 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,10 +1,26 @@
-all: api.html examples.html
+SOURCES=general.txt context.txt loaders.txt filters.txt basic_types.txt + drawing_api.txt backends.txt gamma.txt grabbers.txt
-api.html: general.txt api.txt context.txt loaders.txt filters.txt - basic_types.txt drawing_api.txt backends.txt gamma.txt - grabbers.txt
+PAGES=$(subst .txt,.html,$(SOURCES))
+
+
+all: api.html examples.html $(PAGES) api_links.html
+
+#
+# Create all in one API page
+#
+api.html: $(SOURCES)
asciidoc -a toc api.txt
+#
+# Create page for each part of API description
+#
+$(PAGES): %.html: %.txt
+ asciidoc $<
+
+api_links.html: api_links.txt
+ asciidoc $<
+
examples.html: examples.txt ../demos/c_simple/*.c ../demos/py_simple/*.py
asciidoc -a toc examples.txt
diff --git a/doc/api_links.txt b/doc/api_links.txt
new file mode 100644
index 0000000..b4ef4d2
--- /dev/null
+++ b/doc/api_links.txt
@@ -0,0 +1,48 @@
+GFXprim API
+===========
+Cyril Hrubis <metan(a)ucw.cz>
+
+Also available in link:api.html[all in one page form].
+
+
+. link:basic_types.html[Basic library types]
+ +
+ Describes how colors and pixels are handled also describes progress callback
+ in great detail.
+ +
+. link:context.html[Context]
+ +
+ The Context is description of in-memory bitmap including some meta-data
+ (size, pixel format, etc...).
+ +
+. link:gamma.html[Gamma correction]
+ +
+ The gama correction description and hanlding in GFXprim.
+ +
+. link:drawing_api.html[Drawing primitives]
+ +
+ Drawing API for primitives such as lines, polygons and circles as well as
+ text drawing.
+ +
+. link:filters.html[Context filters]
+ +
+ Context filters, basically all algorithms that takes an Context as an input
+ and returns Context as output.
+ +
+ Includes resampling, convolutions, low pass (blur) filters, dithering and
+ more.
+ +
+. link:loaders.html[Context loaders]
+ +
+ Handles loading and saving images in standard formats.
+ +
+. link:backends.html[Backends]
+ +
+ Backends API for drawing on the screen or into a window.
+ +
+. link:grabbers.html[Grabbers]
+ +
+ Video grabbers interface such as V4L2.
+ +
+
+There is also a nice page with code link:examples.html[examples].
diff --git a/doc/filters.txt b/doc/filters.txt
index 074e7d4..d9ac4fe 100644
--- a/doc/filters.txt
+++ b/doc/filters.txt
@@ -492,8 +492,8 @@ O(x,y)=sum_{i=-infty}^{infty}sum_{j=-infty}^{infty}I(x+i,y+j) cdot K(i,j)
-------------------------------------------------------------------------------
The K denotes convolution kernel and in practice, due to computational
-complexity, the i and j are bounded in relatively small intervals. For example
-i and j are in (-1,1) and the kernel size is 3x3.
+complexity i and j are bounded in relatively small intervals. For example i
+and j are in (-1,1) and the kernel size is 3x3.
Note that pixel values outside the image are undefined. The linear convolution
in GFXprim simply uses the closest border pixel values for all pixels outside
http://repo.or.cz/w/gfxprim.git/commit/14fa043cbe2545c0970092ffaef9ead7ef29…
commit 14fa043cbe2545c0970092ffaef9ead7ef29fe02
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jul 6 15:09:22 2012 +0200
doc: More spellchecks + v4l2 examples.
diff --git a/doc/examples.txt b/doc/examples.txt
index cbd4cf5..683b9f5 100644
--- a/doc/examples.txt
+++ b/doc/examples.txt
@@ -99,6 +99,24 @@ include::../demos/c_simple/backend_example.c[]
include::../demos/c_simple/showimage.c[]
------------------------------------------------------------------
+Grabbers
+--------
+
+Simple C source that saves JPEG images from V4L2 device (web camera).
+
+[source,c]
+------------------------------------------------------------------
+include::../demos/c_simple/v4l2_grab.c[]
+------------------------------------------------------------------
+
+Simple C source that shows filters interactively on image stream from a
+camera.
+
+[source,c]
+------------------------------------------------------------------
+include::../demos/c_simple/v4l2_show.c[]
+------------------------------------------------------------------
+
GFXprim + PyGTK
---------------
diff --git a/doc/grabbers.txt b/doc/grabbers.txt
index 571cc06..e7112cc 100644
--- a/doc/grabbers.txt
+++ b/doc/grabbers.txt
@@ -22,7 +22,7 @@ The grabber API consist GP_Grabber structure and of several functions:
-------------------------------------------------------------------------------
typdef struct GP_Grabber {
/*
- * Currently loaded frame frame.
+ * Currently loaded frame.
*/
GP_Context *frame;
@@ -38,7 +38,8 @@ typdef struct GP_Grabber {
-------------------------------------------------------------------------------
The frame is a pointer to currently loaded frame. Its content is undefined
-until you start the grabber with 'GP_GrabberStart()'.
+until you start the grabber with 'GP_GrabberStart()' and receive frame with
+'GP_GrabberPoll()'.
The 'fd' is a file descriptor suitable for select() or poll(). It's set to -1
if there is none.
@@ -56,8 +57,6 @@ void GP_GrabberExit(GP_Grabber *backend);
Exits the grabber, frees memory, unmaps memory mappings, closes file
descriptors etc...
-Returns zero on success and non-zero on failure.
-
[source,c]
-------------------------------------------------------------------------------
#include <grabbers/GP_Grabber.h>
@@ -67,8 +66,8 @@ Returns zero on success and non-zero on failure.
int GP_GrabberStart(struct GP_Grabber *self);
-------------------------------------------------------------------------------
-Starts a grabber. After calling this calling you can start retrieving frames
-with 'GP_GrabberPoll()'.
+Starts a grabber. After calling this you can start retrieving frames with
+'GP_GrabberPoll()'.
Returns zero on success and non-zero on failure.
@@ -84,6 +83,7 @@ int GP_GrabberStop(struct GP_Grabber *self);
Stops a grabber. Call this when you doesn't need to receive frames but still
plan to use the grabber later.
+Returns zero on success and non-zero on failure.
[source,c]
-------------------------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
doc/Makefile | 24 ++++++++++++++++++++----
doc/api_links.txt | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
doc/examples.txt | 18 ++++++++++++++++++
doc/filters.txt | 4 ++--
doc/grabbers.txt | 12 ++++++------
5 files changed, 94 insertions(+), 12 deletions(-)
create mode 100644 doc/api_links.txt
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0