5 * Copyright (C) 2009-2014 Cyril Hrubis <metan@ucw.cz>
10 #include "core/GP_Pixmap.h"
11 #include "core/GP_GetPutPixel.h"
12 #include "core/GP_TempAlloc.h"
13 //#include "core/GP_Gamma.h"
14 #include "core/GP_Clamp.h"
15 #include "core/GP_Debug.h"
18 #include "GP_GaussianNoise.h"
20 @ for pt in pixeltypes:
21 @ if not pt.is_unknown() and not pt.is_palette():
22 static int GP_FilterGaussianNoiseAdd_{{ pt.name }}_Raw(const GP_Pixmap *src,
23 GP_Coord x_src, GP_Coord y_src,
24 GP_Size w_src, GP_Size h_src,
26 GP_Coord x_dst, GP_Coord y_dst,
27 float sigma, float mu,
28 GP_ProgressCallback *callback)
30 GP_DEBUG(1, "Additive Gaussian noise filter %ux%u sigma=%f mu=%f",
31 w_src, h_src, sigma, mu);
33 @ for c in pt.chanslist:
34 int sigma_{{ c.name }} = {{ c.max }} * sigma;
35 int mu_{{ c.name }} = {{ c.max }} * mu;
38 unsigned int size = w_src + w_src%2;
40 /* Create temporary buffers */
41 GP_TempAllocCreate(temp, sizeof(int) * size * {{ len(pt.chanslist) }});
43 @ for c in pt.chanslist:
44 int *{{ c.name }} = GP_TempAllocGet(temp, size * sizeof(int));
47 /* Apply the additive noise filter */
50 for (y = 0; y < h_src; y++) {
51 @ for c in pt.chanslist:
52 GP_NormInt({{ c.name }}, size, sigma_{{ c.name }}, mu_{{ c.name }});
55 for (x = 0; x < w_src; x++) {
56 GP_Pixel pix = GP_GetPixel_Raw_{{ pt.pixelsize.suffix }}(src, x + x_src, y + y_src);
58 @ for c in pt.chanslist:
59 {{ c.name }}[x] += GP_Pixel_GET_{{ c.name }}_{{ pt.name }}(pix);
60 {{ c.name }}[x] = GP_CLAMP({{ c.name }}[x], 0, {{ c.max }});
63 pix = GP_Pixel_CREATE_{{ pt.name }}({{ arr_to_params(pt.chan_names, '', '[x]') }});
64 GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, x + x_dst, y + y_dst, pix);
67 if (GP_ProgressCallbackReport(callback, y, h_src, w_src)) {
68 GP_TempAllocFree(temp);
74 GP_TempAllocFree(temp);
75 GP_ProgressCallbackDone(callback);
82 int GP_FilterGaussianNoiseAdd_Raw(const GP_Pixmap *src,
83 GP_Coord x_src, GP_Coord y_src,
84 GP_Size w_src, GP_Size h_src,
86 GP_Coord x_dst, GP_Coord y_dst,
87 float sigma, float mu,
88 GP_ProgressCallback *callback)
90 switch (src->pixel_type) {
91 @ for pt in pixeltypes:
92 @ if not pt.is_unknown() and not pt.is_palette():
93 case GP_PIXEL_{{ pt.name }}:
94 return GP_FilterGaussianNoiseAdd_{{ pt.name }}_Raw(src, x_src,
95 y_src, w_src, h_src, dst, x_dst, y_dst,
105 int GP_FilterGaussianNoiseAddEx(const GP_Pixmap *src,
106 GP_Coord x_src, GP_Coord y_src,
107 GP_Size w_src, GP_Size h_src,
109 GP_Coord x_dst, GP_Coord y_dst,
110 float sigma, float mu,
111 GP_ProgressCallback *callback)
113 GP_CHECK(src->pixel_type == dst->pixel_type);
115 /* Check that destination is large enough */
116 GP_CHECK(x_dst + (GP_Coord)w_src <= (GP_Coord)dst->w);
117 GP_CHECK(y_dst + (GP_Coord)h_src <= (GP_Coord)dst->h);
119 /* Source is large enough */
120 GP_CHECK(x_src + w_src <= src->w);
121 GP_CHECK(y_src + h_src <= src->h);
123 return GP_FilterGaussianNoiseAdd_Raw(src, x_src, y_src, w_src, h_src,
125 sigma, mu, callback);
128 GP_Pixmap *GP_FilterGaussianNoiseAddExAlloc(const GP_Pixmap *src,
129 GP_Coord x_src, GP_Coord y_src,
130 GP_Size w_src, GP_Size h_src,
131 float sigma, float mu,
132 GP_ProgressCallback *callback)
136 GP_Pixmap *dst = GP_PixmapAlloc(w_src, h_src, src->pixel_type);
141 ret = GP_FilterGaussianNoiseAdd_Raw(src, x_src, y_src, w_src, h_src,
142 dst, 0, 0, sigma, mu, callback);