3 {% block descr %}Hilbert Peano dithering RGB888 -> any pixel{% endblock %}
7 #include "core/GP_Core.h"
8 #include "core/GP_GetPutPixel.h"
9 #include "GP_HilbertCurve.h"
10 #include "GP_Filter.h"
13 * Returns closest greater square of two, used to determine the curve size.
15 static unsigned int count_bits(unsigned int n)
17 unsigned int i = 0, s = n;
26 return (i + (s != (1U<<i)));
29 %% for pt in pixeltypes
30 %% if not pt.is_unknown() and not pt.is_alpha() and not pt.is_palette()
32 * Hilbert Peano RGB888 to {{ pt.name }}
34 int GP_FilterHilbertPeano_RGB888_to_{{ pt.name }}_Raw(const GP_Context *src,
36 GP_ProgressCallback *callback)
38 struct GP_CurveState state;
41 n = GP_MAX(count_bits(src->w), count_bits(src->h));
43 GP_DEBUG(1, "Hilbert Peano dithering %ux%u -> n = %u", src->w, src->h, n);
45 GP_HilbertCurveInit(&state, n);
47 /* processed pixels counter */
51 %% for c in pt.chanslist
52 int err_{{ c[0] }} = 0;
55 while (GP_HilbertCurveContinues(&state)) {
56 if (state.x < src->w && state.y < src->h) {
57 GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, state.x, state.y);
59 %% for c in pt.chanslist
61 int pix_{{ c[0] }} = GP_Pixel_GET_R_RGB888(pix) +
62 GP_Pixel_GET_G_RGB888(pix) +
63 GP_Pixel_GET_B_RGB888(pix);
65 int pix_{{ c[0] }} = GP_Pixel_GET_{{ c[0] }}_RGB888(pix);
68 pix_{{ c[0] }} += err_{{ c[0] }};
71 int res_{{ c[0] }} = ({{ 2 ** c[2] - 1}} * pix_{{ c[0] }} + 382) / {{ 3 * 255 }};
72 err_{{ c[0] }} = pix_{{ c[0] }} - {{ 3 * 255 }} * res_{{ c[0] }} / {{ 2 ** c[2] - 1 }};
74 int res_{{ c[0] }} = ({{ 2 ** c[2] - 1}} * pix_{{ c[0] }} + 127) / 255;
75 err_{{ c[0] }} = pix_{{ c[0] }} - 255 * res_{{ c[0] }} / {{ 2 ** c[2] - 1 }};
80 GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, state.x, state.y, res_V);
82 GP_Pixel res = GP_Pixel_CREATE_{{ pt.name }}(res_{{ pt.chanslist[0][0] }}{% for c in pt.chanslist[1:] %}, res_{{ c[0] }}{% endfor %});
84 GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, state.x, state.y, res);
88 if (GP_ProgressCallbackReport(callback, cnt/src->h, src->w, src->h))
91 /* We are done, exit */
92 if (cnt == src->w * src->h - 1) {
93 GP_ProgressCallbackDone(callback);
97 %% for c in pt.chanslist
102 GP_HilbertCurveNext(&state);
105 GP_ProgressCallbackDone(callback);
112 int GP_FilterHilbertPeano_RGB888_Raw(const GP_Context *src,
114 GP_ProgressCallback *callback)
116 switch (dst->pixel_type) {
117 %% for pt in pixeltypes
118 %% if not pt.is_unknown() and not pt.is_alpha() and not pt.is_palette()
119 case GP_PIXEL_{{ pt.name }}:
120 return GP_FilterHilbertPeano_RGB888_to_{{ pt.name }}_Raw(src, dst, callback);