filters: Make the linear covolutions general.
[gfxprim.git] / libs / filters / GP_HilbertPeano.gen.c.t
blob2157580ac92b235d2d4dc56416c39f2adf5dc44f
1 %% extends "base.c.t"
3 {% block descr %}Hilbert Peano dithering RGB888 -> any pixel{% endblock %}
5 %% block body
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.
14  */
15 static unsigned int count_bits(unsigned int n)
17         unsigned int i = 0, s = n;
19         do {
20                 n>>=1;
21                 i++;
22         } while (n);
24         i--;
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 }}
33  */
34 int GP_FilterHilbertPeano_RGB888_to_{{ pt.name }}_Raw(const GP_Context *src,
35                                                  GP_Context *dst,
36                                                  GP_ProgressCallback *callback)
38         struct GP_CurveState state;
39         unsigned int n;
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);
46         
47         /* processed pixels counter */
48         unsigned int cnt = 0;
50         /* error counters */
51 %% for c in pt.chanslist
52         int err_{{ c[0] }} = 0;
53 %% endfor
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
60 %% if pt.is_gray()
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);
64 %% else
65                         int pix_{{ c[0] }} = GP_Pixel_GET_{{ c[0] }}_RGB888(pix);
66 %% endif                        
68                         pix_{{ c[0] }} += err_{{ c[0] }};
70 %% if pt.is_gray()
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 }};
73 %% else
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 }};
76 %% endif
77 %% endfor
79 %% if pt.is_gray()
80                         GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, state.x, state.y, res_V);
81 %% else
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);
85 %% endif
86                         cnt++;
88                         if (GP_ProgressCallbackReport(callback, cnt/src->h, src->w, src->h))
89                                 return 1;
91                         /* We are done, exit */
92                         if (cnt == src->w * src->h - 1) {
93                                 GP_ProgressCallbackDone(callback);
94                                 return 0;
95                         }
96                 } else {
97 %% for c in pt.chanslist
98                         err_{{ c[0] }} = 0;
99 %% endfor
100                 }
102                 GP_HilbertCurveNext(&state);
103         }
105         GP_ProgressCallbackDone(callback);
106         return 0;
109 %% endif
110 %% endfor
112 int GP_FilterHilbertPeano_RGB888_Raw(const GP_Context *src,
113                                      GP_Context *dst,
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);
121 %% endif
122 %% endfor
123         default:
124                 return 1;
125         }
128 %% endblock body