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.")
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.")
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.")
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.")