loaders: PNG: Handle gamma on 16bpp conversion
[gfxprim.git] / libs / filters / GP_Rotate.gen.c.t
blob3e8608e41f0970bf55d42e867483db82dec5ae92
1 @ include source.t
2 /*
3  * Vertical Mirror alogorithm
4  *
5  * Copyright (C) 2009-2014 Cyril Hrubis <metan@ucw.cz>
6  */
8 #include "core/GP_Debug.h"
9 #include "core/GP_GetPutPixel.h"
10 #include "GP_Rotate.h"
12 @ for ps in pixelsizes:
13 static int GP_FilterRotate90_Raw_{{ ps.suffix }}(const GP_Pixmap *src, GP_Pixmap *dst,
14                                           GP_ProgressCallback *callback)
16         uint32_t x, y;
18         GP_DEBUG(1, "Rotating image by 90 %ux%u", src->w, src->h);
20         for (x = 0; x < src->w; x++) {
21                 for (y = 0; y < src->h; y++) {
22                         uint32_t yr = src->h - y - 1;
23                         GP_PutPixel_Raw_{{ ps.suffix }}(dst, yr, x, GP_GetPixel_Raw_{{ ps.suffix }}(src, x, y));
24                 }
26                 if (GP_ProgressCallbackReport(callback, x, src->w, src->h))
27                         return 1;
28         }
30         GP_ProgressCallbackDone(callback);
31         return 0;
34 @ end
36 static int GP_FilterRotate90_Raw(const GP_Pixmap *src, GP_Pixmap *dst,
37                                  GP_ProgressCallback *callback)
39         GP_FN_RET_PER_BPP_PIXMAP(GP_FilterRotate90_Raw, src, src, dst, callback);
40         return 1;
43 int GP_FilterRotate90(const GP_Pixmap *src, GP_Pixmap *dst,
44                       GP_ProgressCallback *callback)
46         GP_ASSERT(src->pixel_type == dst->pixel_type,
47                   "The src and dst pixel types must match");
48         GP_ASSERT(src->w <= dst->h && src->h <= dst->w,
49                   "Destination is not large enough");
51         if (GP_FilterRotate90_Raw(src, dst, callback)) {
52                 GP_DEBUG(1, "Operation aborted");
53                 return 1;
54         }
56         return 0;
59 GP_Pixmap *GP_FilterRotate90Alloc(const GP_Pixmap *src,
60                                     GP_ProgressCallback *callback)
62         GP_Pixmap *res;
64         res = GP_PixmapAlloc(src->h, src->w, src->pixel_type);
66         if (res == NULL)
67                 return NULL;
69         if (GP_FilterRotate90_Raw(src, res, callback)) {
70                 GP_DEBUG(1, "Operation aborted");
71                 GP_PixmapFree(res);
72                 return NULL;
73         }
75         return res;
78 @ def swap_pixels(ps, src, dst, x0, y0, x1, y1):
79 GP_Pixel pix0 = GP_GetPixel_Raw_{{ ps.suffix }}({{ src }}, {{ x0 }}, {{ y0 }});
80 GP_Pixel pix1 = GP_GetPixel_Raw_{{ ps.suffix }}({{ src }}, {{ x1 }}, {{ y1 }});
81 GP_PutPixel_Raw_{{ ps.suffix }}({{ dst }}, {{ x0 }}, {{ y0 }}, pix1);
82 GP_PutPixel_Raw_{{ ps.suffix }}({{ dst }}, {{ x1 }}, {{ y1 }}, pix0);
83 @ end
85 @ for ps in pixelsizes:
86 static int GP_FilterRotate180_Raw_{{ ps.suffix }}(const GP_Pixmap *src, GP_Pixmap *dst,
87                                           GP_ProgressCallback *callback)
89         uint32_t x, y;
91         GP_DEBUG(1, "Rotating image by 180 %ux%u", src->w, src->h);
93         for (x = 0; x < src->w; x++) {
94                 for (y = 0; y < src->h; y++) {
95                         uint32_t xr = src->w - x - 1;
96                         uint32_t yr = src->h - y - 1;
98                         {@ swap_pixels(ps, 'src', 'dst', 'x', 'y', 'xr', 'yr') @}
99                 }
101                 if (GP_ProgressCallbackReport(callback, x, src->w, src->h))
102                         return 1;
103         }
105         GP_ProgressCallbackDone(callback);
106         return 0;
109 @ end
111 static int GP_FilterRotate180_Raw(const GP_Pixmap *src, GP_Pixmap *dst,
112                                   GP_ProgressCallback *callback)
114         GP_FN_RET_PER_BPP_PIXMAP(GP_FilterRotate180_Raw, src, src, dst, callback);
115         return 1;
118 int GP_FilterRotate180(const GP_Pixmap *src, GP_Pixmap *dst,
119                        GP_ProgressCallback *callback)
121         GP_ASSERT(src->pixel_type == dst->pixel_type,
122                   "The src and dst pixel types must match");
123         GP_ASSERT(src->w <= dst->w && src->h <= dst->h,
124                   "Destination is not large enough");
126         if (GP_FilterRotate180_Raw(src, dst, callback)) {
127                 GP_DEBUG(1, "Operation aborted");
128                 return 1;
129         }
131         return 0;
134 GP_Pixmap *GP_FilterRotate180Alloc(const GP_Pixmap *src,
135                                     GP_ProgressCallback *callback)
137         GP_Pixmap *res;
139         res = GP_PixmapCopy(src, 0);
141         if (res == NULL)
142                 return NULL;
144         if (GP_FilterRotate180_Raw(src, res, callback)) {
145                 GP_DEBUG(1, "Operation aborted");
146                 GP_PixmapFree(res);
147                 return NULL;
148         }
150         return res;
153 @ for ps in pixelsizes:
154 static int GP_FilterRotate270_Raw_{{ ps.suffix }}(const GP_Pixmap *src, GP_Pixmap *dst,
155                                            GP_ProgressCallback *callback)
157         uint32_t x, y;
159         GP_DEBUG(1, "Rotating image by 270 %ux%u", src->w, src->h);
161         for (x = 0; x < src->w; x++) {
162                 for (y = 0; y < src->h; y++) {
163                                 uint32_t xr = src->w - x - 1;
164                                 GP_PutPixel_Raw_{{ ps.suffix }}(dst, y, xr, GP_GetPixel_Raw_{{ ps.suffix }}(src, x, y));
165                 }
167                 if (GP_ProgressCallbackReport(callback, x, src->w, src->h))
168                         return 1;
169         }
171         GP_ProgressCallbackDone(callback);
172         return 0;
175 @ end
177 static int GP_FilterRotate270_Raw(const GP_Pixmap *src, GP_Pixmap *dst,
178                                   GP_ProgressCallback *callback)
180         GP_FN_RET_PER_BPP_PIXMAP(GP_FilterRotate270_Raw, src, src, dst, callback);
181         return 1;
184 int GP_FilterRotate270(const GP_Pixmap *src, GP_Pixmap *dst,
185                       GP_ProgressCallback *callback)
187         GP_ASSERT(src->pixel_type == dst->pixel_type,
188                   "The src and dst pixel types must match");
189         GP_ASSERT(src->w <= dst->h && src->h <= dst->w,
190                   "Destination is not large enough");
192         if (GP_FilterRotate270_Raw(src, dst, callback)) {
193                 GP_DEBUG(1, "Operation aborted");
194                 return 1;
195         }
197         return 0;
200 GP_Pixmap *GP_FilterRotate270Alloc(const GP_Pixmap *src,
201                                      GP_ProgressCallback *callback)
203         GP_Pixmap *res;
205         res = GP_PixmapAlloc(src->h, src->w, src->pixel_type);
207         if (res == NULL)
208                 return NULL;
210         if (GP_FilterRotate270_Raw(src, res, callback)) {
211                 GP_DEBUG(1, "Operation aborted");
212                 GP_PixmapFree(res);
213                 return NULL;
214         }
216         return res;