static const char* bilateral_filter_cl_source =
"#define POW2(a) ((a) * (a))                                                   \n"
"kernel void bilateral_filter(global float4 *in,                               \n"
"                             global float4 *out,                              \n"
"                             const  float radius,                             \n"
"                             const  float preserve)                           \n"
"{                                                                             \n"
"    int gidx       = get_global_id(0);                                        \n"
"    int gidy       = get_global_id(1);                                        \n"
"    int n_radius   = ceil(radius);                                            \n"
"    int dst_width  = get_global_size(0);                                      \n"
"    int src_width  = dst_width + n_radius * 2;                                \n"
"                                                                              \n"
"    int u, v, i, j;                                                           \n"
"    float4 center_pix =                                                       \n"
"        in[(gidy + n_radius) * src_width + gidx + n_radius];                  \n"
"    float4 accumulated = 0.0f;                                                \n"
"    float4 tempf       = 0.0f;                                                \n"
"    float  count       = 0.0f;                                                \n"
"    float  diff_map, gaussian_weight, weight;                                 \n"
"                                                                              \n"
"    for (v = -n_radius;v <= n_radius; ++v)                                    \n"
"    {                                                                         \n"
"        for (u = -n_radius;u <= n_radius; ++u)                                \n"
"        {                                                                     \n"
"            i = gidx + n_radius + u;                                          \n"
"            j = gidy + n_radius + v;                                          \n"
"                                                                              \n"
"            int gid1d = i + j * src_width;                                    \n"
"            tempf = in[gid1d];                                                \n"
"                                                                              \n"
"            diff_map = exp (                                                  \n"
"                - (   POW2(center_pix.x - tempf.x)                            \n"
"                    + POW2(center_pix.y - tempf.y)                            \n"
"                    + POW2(center_pix.z - tempf.z))                           \n"
"                * preserve);                                                  \n"
"                                                                              \n"
"            gaussian_weight =                                                 \n"
"                exp( - 0.5f * (POW2(u) + POW2(v)) / radius);                  \n"
"                                                                              \n"
"            weight = diff_map * gaussian_weight;                              \n"
"                                                                              \n"
"            accumulated += tempf * weight;                                    \n"
"            count += weight;                                                  \n"
"        }                                                                     \n"
"    }                                                                         \n"
"    out[gidx + gidy * dst_width] = accumulated / count;                       \n"
"}                                                                             \n"
;
