filters/gp_filter_resize_alloc: Check w and h
[gfxprim.git] / libs / filters / GP_GaussianNoise.gen.c.t
blobae69c17a4f56385490228ac658817ca139a4b87f
1 @ include source.t
2 /*
3  * Gaussian Noise
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_Clamp.h>
14 #include <core/GP_Debug.h>
16 #include <filters/GP_Rand.h>
17 #include <filters/GP_GaussianNoise.h>
19 @ for pt in pixeltypes:
20 @     if not pt.is_unknown() and not pt.is_palette():
21 static int gaussian_noise_add_{{ pt.name }}(const gp_pixmap *src,
22                                 gp_coord x_src, gp_coord y_src,
23                                 gp_size w_src, gp_size h_src,
24                                 gp_pixmap *dst,
25                                 gp_coord x_dst, gp_coord y_dst,
26                                 float sigma, float mu,
27                                 gp_progress_cb *callback)
29         GP_DEBUG(1, "Additive Gaussian noise filter %ux%u sigma=%f mu=%f",
30                  w_src, h_src, sigma, mu);
32 @         for c in pt.chanslist:
33         int sigma_{{ c.name }} = {{ c.max }} * sigma;
34         int mu_{{ c.name }} = {{ c.max }} * mu;
35 @         end
37         unsigned int size = w_src + w_src%2;
39         /* Create temporary buffers */
40         gp_temp_alloc_create(temp, sizeof(int) * size * {{ len(pt.chanslist) }});
42 @         for c in pt.chanslist:
43         int *{{ c.name }} = gp_temp_alloc_get(temp, size * sizeof(int));
44 @         end
46         /* Apply the additive noise filter */
47         unsigned int x, y;
49         for (y = 0; y < h_src; y++) {
50 @         for c in pt.chanslist:
51                 gp_norm_int({{ c.name }}, size, sigma_{{ c.name }}, mu_{{ c.name }});
52 @         end
54                 for (x = 0; x < w_src; x++) {
55                         gp_pixel pix = gp_getpixel_raw_{{ pt.pixelsize.suffix }}(src, x + x_src, y + y_src);
57 @         for c in pt.chanslist:
58                         {{ c.name }}[x] += GP_PIXEL_GET_{{ c.name }}_{{ pt.name }}(pix);
59                         {{ c.name }}[x] = GP_CLAMP({{ c.name }}[x], 0, {{ c.max }});
60 @         end
62                         pix = GP_PIXEL_CREATE_{{ pt.name }}({{ arr_to_params(pt.chan_names, '', '[x]') }});
63                         gp_putpixel_raw_{{ pt.pixelsize.suffix }}(dst, x + x_dst, y + y_dst, pix);
64                 }
66                 if (gp_progress_cb_report(callback, y, h_src, w_src)) {
67                         gp_temp_alloc_free(temp);
68                         errno = ECANCELED;
69                         return 1;
70                 }
71         }
73         gp_temp_alloc_free(temp);
74         gp_progress_cb_done(callback);
76         return 0;
79 @ end
81 int gp_filter_gaussian_noise_add_raw(const gp_pixmap *src,
82                                      gp_coord x_src, gp_coord y_src,
83                                      gp_size w_src, gp_size h_src,
84                                      gp_pixmap *dst,
85                                      gp_coord x_dst, gp_coord y_dst,
86                                      float sigma, float mu,
87                                      gp_progress_cb *callback)
89         switch (src->pixel_type) {
90 @ for pt in pixeltypes:
91 @     if not pt.is_unknown() and not pt.is_palette():
92         case GP_PIXEL_{{ pt.name }}:
93                 return gaussian_noise_add_{{ pt.name }}(src, x_src,
94                                 y_src, w_src, h_src, dst, x_dst, y_dst,
95                                 sigma, mu, callback);
96         break;
97 @ end
98         default:
99                 errno = EINVAL;
100                 return -1;
101         }
104 int gp_filter_gaussian_noise_add_ex(const gp_pixmap *src,
105                                     gp_coord x_src, gp_coord y_src,
106                                     gp_size w_src, gp_size h_src,
107                                     gp_pixmap *dst,
108                                     gp_coord x_dst, gp_coord y_dst,
109                                     float sigma, float mu,
110                                     gp_progress_cb *callback)
112         GP_CHECK(src->pixel_type == dst->pixel_type);
114         /* Check that destination is large enough */
115         GP_CHECK(x_dst + (gp_coord)w_src <= (gp_coord)dst->w);
116         GP_CHECK(y_dst + (gp_coord)h_src <= (gp_coord)dst->h);
118         /* Source is large enough */
119         GP_CHECK(x_src + w_src <= src->w);
120         GP_CHECK(y_src + h_src <= src->h);
122         return gp_filter_gaussian_noise_add_raw(src, x_src, y_src, w_src, h_src,
123                                                 dst, x_dst, y_dst,
124                                                 sigma, mu, callback);
127 gp_pixmap *gp_filter_gaussian_noise_add_ex_alloc(const gp_pixmap *src,
128                                                  gp_coord x_src, gp_coord y_src,
129                                                  gp_size w_src, gp_size h_src,
130                                                  float sigma, float mu,
131                                                  gp_progress_cb *callback)
133         int ret, err;
135         gp_pixmap *dst = gp_pixmap_alloc(w_src, h_src, src->pixel_type);
137         if (dst == NULL)
138                 return NULL;
140         ret = gp_filter_gaussian_noise_add_raw(src, x_src, y_src, w_src, h_src,
141                                               dst, 0, 0, sigma, mu, callback);
143         if (ret) {
144                 err = errno;
145                 gp_pixmap_free(dst);
146                 errno = err;
147                 return NULL;
148         }
150         return dst;