Rename GP_Context -> GP_Pixmap
[gfxprim.git] / libs / filters / GP_MultiTone.gen.c.t
blobc20b4bc7ed95de10cb79bb1aa9c02993edded121
1 @ include source.t
2 /*
3  * Generic Point filer
4  *
5  * Copyright (C) 2009-2014 Cyril Hrubis <metan@ucw.cz>
6  */
8 #include <errno.h>
10 #include "core/GP_Pixmap.h"
11 #include "core/GP_GetPutPixel.h"
12 #include "core/GP_TempAlloc.h"
13 #include "core/GP_MixPixels.h"
14 #include "core/GP_Debug.h"
16 #include "filters/GP_MultiTone.h"
18 @ for pt in pixeltypes:
19 @     if not pt.is_unknown() and not pt.is_palette():
20 static void init_table_{{ pt.name }}(GP_Pixel table[],
21                                      GP_Size table_size,
22                                      GP_Pixel pixels[],
23                                      GP_Size pixels_size)
25         unsigned int i;
26         unsigned int p = 0;
27         float perc;
28         float step = 1.00 * table_size / (pixels_size - 1);
30         GP_DEBUG(2, "Preparing pixel table %u steps %u pixels, step %.2f",
31                  table_size, pixels_size, step);
33         for (i = 0; i < table_size; i++) {
34                 p = 1.00 * i / step;
35                 perc = i+1;
37                 while (perc > step)
38                         perc -= step;
40                 perc = perc / step;
42                 table[i] = GP_MIX_PIXELS_{{ pt.name }}(pixels[p+1], pixels[p], 255 * perc);
43 //              printf("p = %u i = %u PERC %.2f\n", p, i, perc);
44 //              GP_PixelPrint(table[i], GP_PIXEL_{{ pt.name }});
45         }
48 @ end
50 static void init_table(GP_PixelType type,
51                        GP_Pixel table[], GP_Size table_size,
52                        GP_Pixel pixels[], GP_Size pixels_size)
54         switch (type) {
55 @ for pt in pixeltypes:
56 @     if not pt.is_unknown() and not pt.is_palette():
57         case GP_PIXEL_{{ pt.name }}:
58                 init_table_{{ pt.name }}(table, table_size,
59                                          pixels, pixels_size);
60         break;
61 @ end
62         default:
63                 GP_BUG("Should not be reached");
64         break;
65         }
68 #include <assert.h>
70 @ for pt in pixeltypes:
71 @     if pt.is_gray():
72 static int multitone_{{ pt.name }}(const GP_Pixmap *const src,
73                                    GP_Coord x_src, GP_Coord y_src,
74                                    GP_Size w_src, GP_Size h_src,
75                                    GP_Pixmap *dst,
76                                    GP_Coord x_dst, GP_Coord y_dst,
77                                    GP_Pixel pixels[], GP_Size pixels_size,
78                                    GP_ProgressCallback *callback)
80 @         size = pt.chanslist[0].max + 1
81         GP_TempAllocCreate(tmp, {{ size }} * sizeof(GP_Pixel));
82         GP_Pixel *table = GP_TempAllocGet(tmp, {{ size }} * sizeof(GP_Pixel));
84         GP_DEBUG(1, "Duotone filter %ux%u {{ pt.name }} -> %s",
85                  w_src, h_src, GP_PixelTypeName(dst->pixel_type));
87         init_table(dst->pixel_type, table, {{ size }}, pixels, pixels_size);
89         unsigned int x, y;
91         for (y = 0; y < h_src; y++) {
92                 for (x = 0; x < w_src; x++) {
93                         unsigned int src_x = x_src + x;
94                         unsigned int src_y = y_src + y;
95                         unsigned int dst_x = x_dst + x;
96                         unsigned int dst_y = y_dst + y;
98                         GP_Pixel pix = GP_GetPixel_Raw_{{ pt.pixelsize.suffix }}(src, src_x, src_y);
100                         pix = table[pix];
102                         GP_PutPixel_Raw(dst, dst_x, dst_y, pix);
103                 }
105                 if (GP_ProgressCallbackReport(callback, y, h_src, w_src)) {
106                         GP_TempAllocFree(tmp);
107                         errno = ECANCELED;
108                         return 1;
109                 }
110         }
112         GP_TempAllocFree(tmp);
113         GP_ProgressCallbackDone(callback);
115         return 0;
118 @ end
120 int GP_FilterMultiToneEx(const GP_Pixmap *const src,
121                          GP_Coord x_src, GP_Coord y_src,
122                          GP_Size w_src, GP_Size h_src,
123                          GP_Pixmap *dst,
124                          GP_Coord x_dst, GP_Coord y_dst,
125                          GP_Pixel pixels[], GP_Size pixels_size,
126                          GP_ProgressCallback *callback)
128         //CHECK DST IS NOT PALETTE PixelHasFlags
130         switch (src->pixel_type) {
131 @ for pt in pixeltypes:
132 @     if pt.is_gray():
133         case GP_PIXEL_{{ pt.name }}:
134                 return multitone_{{ pt.name }}(src, x_src, y_src,
135                                                w_src, h_src, dst,
136                                                x_dst, y_dst,
137                                                pixels, pixels_size,
138                                                callback);
139         break;
140 @ end
141         default:
142                 errno = EINVAL;
143                 return -1;
144         }
147 GP_Pixmap *GP_FilterMultiToneExAlloc(const GP_Pixmap *const src,
148                                       GP_Coord x_src, GP_Coord y_src,
149                                       GP_Size w_src, GP_Size h_src,
150                                       GP_PixelType dst_pixel_type,
151                                       GP_Pixel pixels[], GP_Size pixels_size,
152                                       GP_ProgressCallback *callback)
154         GP_Pixmap *res;
155         int err;
157         res = GP_PixmapAlloc(w_src, h_src, dst_pixel_type);
159         if (!res) {
160                 GP_DEBUG(1, "Malloc failed :(");
161                 return NULL;
162         }
164         if (GP_FilterMultiToneEx(src, x_src, y_src, w_src, h_src, res, 0, 0,
165                                  pixels, pixels_size, callback)) {
166                 err = errno;
167                 GP_PixmapFree(res);
168                 errno = err;
169                 return NULL;
170         }
172         return res;