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 2bea36d5281f8683a1215177d6a162581de40521 (commit) via 28e1f1872424ff83ed2eceafcbdd6b9b293b8866 (commit) from c2f10f3f488c6f32fb2c516153689a1fcc317ff0 (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/2bea36d5281f8683a1215177d6a162581de40...
commit 2bea36d5281f8683a1215177d6a162581de40521 Author: Cyril Hrubis metan@ucw.cz Date: Mon May 21 00:10:36 2012 +0200
filters: Templatized Hilbert Peano Dithering.
diff --git a/libs/filters/GP_Dither.c b/libs/filters/GP_Dither.c index e0c6be1..d258ef4 100644 --- a/libs/filters/GP_Dither.c +++ b/libs/filters/GP_Dither.c @@ -133,3 +133,14 @@ GP_Context *GP_FilterFloydSteinberg_from_RGB888(const GP_Context *src,
return ret; } + +int GP_FilterHilbertPeano_RGB888_to_XXX_Raw(const GP_Context *src, + GP_Context *dst, + GP_ProgressCallback *callback); + +int GP_FilterHilbertPeano_from_RGB888(const GP_Context *src, + GP_Context *dst, + GP_ProgressCallback *callback) +{ + return GP_FilterHilbertPeano_RGB888_to_XXX_Raw(src, dst, callback); +} diff --git a/libs/filters/GP_Dither.gen.c.t b/libs/filters/GP_Dither.gen.c.t index 8b9e237..c1ec2bf 100644 --- a/libs/filters/GP_Dither.gen.c.t +++ b/libs/filters/GP_Dither.gen.c.t @@ -1,9 +1,7 @@
%% extends "base.c.t"
-%% block descr -Floyd Steinberg dithering RGB888 -> any pixel -%% endblock +{% block descr %}Floyd Steinberg dithering RGB888 -> any pixel{% endblock %}
%% block body
@@ -52,7 +50,7 @@ int GP_FilterFloydSteinberg_RGB888_to_{{ pt.name }}_Raw(const GP_Context *src, G
for (y = 0; y < (GP_Coord)src->h; y++) { for (x = 0; x < (GP_Coord)src->w; x++) { - GP_Pixel pix = GP_GetPixel(src, x, y); + GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, x, y); %% for c in pt.chanslist %% if pt.is_gray() diff --git a/libs/filters/GP_HilbertPeanoDithering.c b/libs/filters/GP_HilbertPeanoDithering.c deleted file mode 100644 index decaebf..0000000 --- a/libs/filters/GP_HilbertPeanoDithering.c +++ /dev/null @@ -1,97 +0,0 @@ -/***************************************************************************** - * This file is part of gfxprim library. * - * * - * Gfxprim is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - * * - * Gfxprim is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with gfxprim; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin Street, Fifth Floor, * - * Boston, MA 02110-1301 USA * - * * - * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * - * * - *****************************************************************************/ - -#include "core/GP_Debug.h" -#include "core/GP_GetPutPixel.h" -#include "core/GP_Core.h" - -#include "GP_HilbertCurve.h" -#include "GP_Dither.h" - -/* - * Returns closest greater square of two, used to determine the curve size. - */ -static unsigned int count_bits(unsigned int n) -{ - unsigned int i = 0, s = n; - - do { - n>>=1; - i++; - } while (n); - - return (i + (s != (1<<i))); -} - -int GP_FilterHilbertPeano_from_RGB888(const GP_Context *src, - GP_Context *dst, - GP_ProgressCallback *callback) -{ - struct GP_CurveState state; - - unsigned int n = GP_MAX(count_bits(src->w), count_bits(src->h)); - - GP_DEBUG(1, "Hilbert Peano dithering %ux%u -> n = %u", src->w, src->h, n); - - GP_HilbertCurveInit(&state, n); - - int err = 0, cnt = 0; - - while (GP_HilbertCurveContinues(&state)) { - - if (state.x < src->w && state.y < src->h) { - int pix = GP_GetPixel_Raw(src, state.x, state.y); - - pix = GP_ConvertPixel(pix, src->pixel_type, GP_PIXEL_G8); - - pix += err; - - if (pix > 127) { - err = pix - 255; - pix = 1; - } else { - err = pix; - pix = 0; - } - - GP_PutPixel_Raw_1BPP_LE(dst, state.x, state.y, pix); - - cnt++; - - if (GP_ProgressCallbackReport(callback, cnt/src->h, src->w, src->h)) - return 1; - - /* We are done, exit */ - if (cnt == src->w * src->h - 1) { - GP_ProgressCallbackDone(callback); - return 0; - } - } else { - err = 0; - } - - GP_HilbertCurveNext(&state); - } - - GP_ProgressCallbackDone(callback); - return 0; -} diff --git a/libs/filters/GP_HilbertPeanoDithering.gen.c.t b/libs/filters/GP_HilbertPeanoDithering.gen.c.t new file mode 100644 index 0000000..a925c9c --- /dev/null +++ b/libs/filters/GP_HilbertPeanoDithering.gen.c.t @@ -0,0 +1,126 @@ +%% extends "base.c.t" + +{% block descr %}Hilbert Peano dithering RGB888 -> any pixel{% endblock %} + +%% block body + +#include "core/GP_Core.h" +#include "core/GP_GetPutPixel.h" +#include "GP_HilbertCurve.h" +#include "GP_Filter.h" + +/* + * Returns closest greater square of two, used to determine the curve size. + */ +static unsigned int count_bits(unsigned int n) +{ + unsigned int i = 0, s = n; + + do { + n>>=1; + i++; + } while (n); + + return (i + (s != (1U<<i))); +} + +%% for pt in pixeltypes +%% if not pt.is_unknown() and not pt.is_alpha() and not pt.is_palette() +/* + * Hilbert Peano RGB888 to {{ pt.name }} + */ +int GP_FilterHilbertPeano_RGB888_to_{{ pt.name }}_Raw(const GP_Context *src, + GP_Context *dst, + GP_ProgressCallback *callback) +{ + struct GP_CurveState state; + unsigned int n; + + n = GP_MAX(count_bits(src->w), count_bits(src->h)); + + GP_DEBUG(1, "Hilbert Peano dithering %ux%u -> n = %u", src->w, src->h, n); + + GP_HilbertCurveInit(&state, n); + + /* processed pixels counter */ + unsigned int cnt = 0; + + /* error counters */ +%% for c in pt.chanslist + int err_{{ c[0] }} = 0; +%% endfor + + while (GP_HilbertCurveContinues(&state)) { + if (state.x < src->w && state.y < src->h) { + GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, state.x, state.y); + +%% for c in pt.chanslist +%% if pt.is_gray() + int pix_{{ c[0] }} = GP_Pixel_GET_R_RGB888(pix) + + GP_Pixel_GET_G_RGB888(pix) + + GP_Pixel_GET_B_RGB888(pix); +%% else + int pix_{{ c[0] }} = GP_Pixel_GET_{{ c[0] }}_RGB888(pix); +%% endif + + pix_{{ c[0] }} += err_{{ c[0] }}; + +%% if pt.is_gray() + int res_{{ c[0] }} = ({{ 2 ** c[2] - 1}} * pix_{{ c[0] }} + 382) / {{ 3 * 255 }}; + err_{{ c[0] }} = pix_{{ c[0] }} - {{ 3 * 255 }} * res_{{ c[0] }} / {{ 2 ** c[2] - 1 }}; +%% else + int res_{{ c[0] }} = ({{ 2 ** c[2] - 1}} * pix_{{ c[0] }} + 127) / 255; + err_{{ c[0] }} = pix_{{ c[0] }} - 255 * res_{{ c[0] }} / {{ 2 ** c[2] - 1 }}; +%% endif +%% endfor + +%% if pt.is_gray() + GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, state.x, state.y, res_V); +%% else + GP_Pixel res = GP_Pixel_CREATE_{{ pt.name }}(res_{{ pt.chanslist[0][0] }}{% for c in pt.chanslist[1:] %}, res_{{ c[0] }}{% endfor %}); + + GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, state.x, state.y, res); +%% endif + cnt++; + + if (GP_ProgressCallbackReport(callback, cnt/src->h, src->w, src->h)) + return 1; + + /* We are done, exit */ + if (cnt == src->w * src->h - 1) { + GP_ProgressCallbackDone(callback); + return 0; + } + } else { +%% for c in pt.chanslist + err_{{ c[0] }} = 0; +%% endfor + } + + GP_HilbertCurveNext(&state); + } + + GP_ProgressCallbackDone(callback); + return 0; +} + +%% endif +%% endfor + +int GP_FilterHilbertPeano_RGB888_to_XXX_Raw(const GP_Context *src, + GP_Context *dst, + GP_ProgressCallback *callback) +{ + switch (dst->pixel_type) { +%% for pt in pixeltypes +%% if not pt.is_unknown() and not pt.is_alpha() and not pt.is_palette() + case GP_PIXEL_{{ pt.name }}: + return GP_FilterHilbertPeano_RGB888_to_{{ pt.name }}_Raw(src, dst, callback); +%% endif +%% endfor + default: + return 1; + } +} + +%% endblock body diff --git a/libs/filters/Makefile b/libs/filters/Makefile index 216d06d..7a9a670 100644 --- a/libs/filters/Makefile +++ b/libs/filters/Makefile @@ -8,7 +8,7 @@ POINT_FILTERS=GP_Contrast.gen.c GP_Brightness.gen.c GP_Invert.gen.c ARITHMETIC_FILTERS=GP_Difference.gen.c GP_Addition.gen.c GP_Min.gen.c GP_Max.gen.c GP_Multiply.gen.c
-GENSOURCES=GP_MirrorV.gen.c GP_Rotate.gen.c GP_Dither.gen.c+GENSOURCES=GP_MirrorV.gen.c GP_Rotate.gen.c GP_Dither.gen.c GP_HilbertPeanoDithering.gen.c $(POINT_FILTERS) $(ARITHMETIC_FILTERS) $(STATS_FILTERS)
CSOURCES=$(filter-out $(wildcard *.gen.c),$(wildcard *.c))
http://repo.or.cz/w/gfxprim.git/commit/28e1f1872424ff83ed2eceafcbdd6b9b293b8...
commit 28e1f1872424ff83ed2eceafcbdd6b9b293b8866 Author: Cyril Hrubis metan@ucw.cz Date: Sun May 20 22:00:46 2012 +0200
filters: Initial version of Hilbert Peano Dithering.
* For G1 only now.
diff --git a/include/filters/GP_Dither.h b/include/filters/GP_Dither.h index b0b5157..07a8da2 100644 --- a/include/filters/GP_Dither.h +++ b/include/filters/GP_Dither.h @@ -61,4 +61,12 @@ int GP_FilterFloydSteinberg_XXX_to_G1_Raw(const GP_Context *src, GP_ProgressCallback *callback);
+/* + * Hilbert-peano space filling curve based dithering. + */ +int GP_FilterHilbertPeano_from_RGB888(const GP_Context *src, + GP_Context *dst, + GP_ProgressCallback *callback); + + #endif /* FILTERS_GP_DITHER_H */ diff --git a/include/filters/GP_Dither.h b/include/filters/GP_HilbertCurve.h similarity index 53% copy from include/filters/GP_Dither.h copy to include/filters/GP_HilbertCurve.h index b0b5157..fecac22 100644 --- a/include/filters/GP_Dither.h +++ b/include/filters/GP_HilbertCurve.h @@ -16,49 +16,84 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
/*
- Dithering algorithms. + Hilbert curve implementation.
*/
-#ifndef FILTERS_GP_DITHER_H -#define FILTERS_GP_DITHER_H +#ifndef FILTERS_GP_HILBERT_CURVE_H +#define FILTERS_GP_HILBERT_CURVE_H
-#include "GP_Filter.h" +struct GP_CurveState { + /* half of the number of bits of curve size */ + unsigned int n; + /* coordinates */ + unsigned int x, y; + /* current curve lenght */ + unsigned int s; +};
/* - * Floyd Steinberg + * Resets curve to initial state i.e. x = 0, y = 0, (length) s = 0. */ -GP_Context *GP_FilterFloydSteinberg_to_G1(const GP_Context *src, - GP_Context *dst, - GP_ProgressCallback *callback); +static inline void GP_HilbertCurveInit(struct GP_CurveState *state, int n) +{ + state->n = n; + state->s = 0; + state->x = 0; + state->y = 0; +}
/* - * Floyd Steinberg + * Variant of Lam and Shapiro */ -GP_Context *GP_FilterFloydSteinberg_from_RGB888(const GP_Context *src, - GP_Context *dst, - GP_PixelType dst_pixel_type, - GP_ProgressCallback *callback); +static inline void GP_HilbertCurveGetXY(struct GP_CurveState *state) +{ + int sa, sb; + unsigned int i, temp, x, y; + + for (i = 0; i < 2 * state->n; i += 2) { + sa = (state->s >> (i+1)) & 0x01; + sb = (state->s >> i) & 0x01; + + if ((sa ^ sb) == 0) { + temp = x; + x = y ^ (-sa); + y = temp ^ (-sa); + } + + x = (x >> 1) | (sa << 31); + y = (y >> 1) | ((sa ^ sb) << 31); + } + + state->x = x >> (32 - state->n); + state->y = y >> (32 - state->n); +} +
/* - * Converts RGB888 to RGB or Grayscale bitmap. + * Finds next X and Y */ -int GP_FilterFloydSteinberg_RGB888_to_XXX_Raw(const GP_Context *src, - GP_Context *dst, - GP_ProgressCallback *callback); +static inline void GP_HilbertCurveNext(struct GP_CurveState *state) +{ + + /* increment length */ + state->s++; + /* get X and Y */ + GP_HilbertCurveGetXY(state); +}
/* - * Converts any bitmap to 1-bit Grayscale. + * Returns true if we are not at curve endpoint */ -int GP_FilterFloydSteinberg_XXX_to_G1_Raw(const GP_Context *src, - GP_Context *dst, - GP_ProgressCallback *callback); - +static inline int GP_HilbertCurveContinues(struct GP_CurveState *state) +{ + return state->s < (1U<<(2*state->n)); +}
-#endif /* FILTERS_GP_DITHER_H */ +#endif /* FILTERS_GP_HILBERT_CURVE_H */ diff --git a/include/filters/GP_Dither.h b/libs/filters/GP_HilbertPeanoDithering.c similarity index 51% copy from include/filters/GP_Dither.h copy to libs/filters/GP_HilbertPeanoDithering.c index b0b5157..decaebf 100644 --- a/include/filters/GP_Dither.h +++ b/libs/filters/GP_HilbertPeanoDithering.c @@ -16,49 +16,82 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
-/* +#include "core/GP_Debug.h" +#include "core/GP_GetPutPixel.h" +#include "core/GP_Core.h"
- Dithering algorithms. +#include "GP_HilbertCurve.h" +#include "GP_Dither.h"
+/* + * Returns closest greater square of two, used to determine the curve size. */ +static unsigned int count_bits(unsigned int n) +{ + unsigned int i = 0, s = n;
-#ifndef FILTERS_GP_DITHER_H -#define FILTERS_GP_DITHER_H + do { + n>>=1; + i++; + } while (n);
-#include "GP_Filter.h" + return (i + (s != (1<<i))); +}
-/* - * Floyd Steinberg - */ -GP_Context *GP_FilterFloydSteinberg_to_G1(const GP_Context *src, - GP_Context *dst, - GP_ProgressCallback *callback); +int GP_FilterHilbertPeano_from_RGB888(const GP_Context *src, + GP_Context *dst, + GP_ProgressCallback *callback) +{ + struct GP_CurveState state;
-/* - * Floyd Steinberg - */ -GP_Context *GP_FilterFloydSteinberg_from_RGB888(const GP_Context *src, - GP_Context *dst, - GP_PixelType dst_pixel_type, - GP_ProgressCallback *callback); + unsigned int n = GP_MAX(count_bits(src->w), count_bits(src->h));
-/* - * Converts RGB888 to RGB or Grayscale bitmap. - */ -int GP_FilterFloydSteinberg_RGB888_to_XXX_Raw(const GP_Context *src, - GP_Context *dst, - GP_ProgressCallback *callback); + GP_DEBUG(1, "Hilbert Peano dithering %ux%u -> n = %u", src->w, src->h, n);
-/* - * Converts any bitmap to 1-bit Grayscale. - */ -int GP_FilterFloydSteinberg_XXX_to_G1_Raw(const GP_Context *src, - GP_Context *dst, - GP_ProgressCallback *callback); + GP_HilbertCurveInit(&state, n); + + int err = 0, cnt = 0; + + while (GP_HilbertCurveContinues(&state)) { + + if (state.x < src->w && state.y < src->h) { + int pix = GP_GetPixel_Raw(src, state.x, state.y); + + pix = GP_ConvertPixel(pix, src->pixel_type, GP_PIXEL_G8); + + pix += err; + + if (pix > 127) { + err = pix - 255; + pix = 1; + } else { + err = pix; + pix = 0; + } + + GP_PutPixel_Raw_1BPP_LE(dst, state.x, state.y, pix); + + cnt++; + + if (GP_ProgressCallbackReport(callback, cnt/src->h, src->w, src->h)) + return 1; + + /* We are done, exit */ + if (cnt == src->w * src->h - 1) { + GP_ProgressCallbackDone(callback); + return 0; + } + } else { + err = 0; + }
+ GP_HilbertCurveNext(&state); + }
-#endif /* FILTERS_GP_DITHER_H */ + GP_ProgressCallbackDone(callback); + return 0; +}
-----------------------------------------------------------------------
Summary of changes: include/filters/GP_Dither.h | 8 ++ .../GP_GIF.h => filters/GP_HilbertCurve.h} | 84 ++++++++++---- libs/filters/GP_Dither.c | 11 ++ libs/filters/GP_Dither.gen.c.t | 6 +- libs/filters/GP_HilbertPeanoDithering.gen.c.t | 126 ++++++++++++++++++++ libs/filters/Makefile | 2 +- 6 files changed, 209 insertions(+), 28 deletions(-) copy include/{loaders/GP_GIF.h => filters/GP_HilbertCurve.h} (55%) create mode 100644 libs/filters/GP_HilbertPeanoDithering.gen.c.t
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos@gmail.com if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.