1/*
2    This file is part of darktable,
3    copyright (c) 2011 ulrich pegelow.
4
5    darktable is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    darktable is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with darktable.  If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#include "common.h"
20
21
22
23kernel void
24sharpen_hblur(read_only image2d_t in, write_only image2d_t out, global const float *m, const int rad,
25      const int width, const int height, const int blocksize, local float *buffer)
26{
27  const int lid = get_local_id(0);
28  const int lsz = get_local_size(0);
29  const int x = get_global_id(0);
30  const int y = get_global_id(1);
31  float4 pixel = (float4)0.0f;
32
33  /* read pixel and fill center part of buffer */
34  pixel = read_imagef(in, sampleri, (int2)(x, y));
35  buffer[rad + lid] = pixel.x;
36
37  /* left wing of buffer */
38  for(int n=0; n <= rad/lsz; n++)
39  {
40    const int l = mad24(n, lsz, lid + 1);
41    if(l > rad) continue;
42    const int xx = mad24((int)get_group_id(0), lsz, -l);
43    buffer[rad - l] = read_imagef(in, sampleri, (int2)(xx, y)).x;
44  }
45
46  /* right wing of buffer */
47  for(int n=0; n <= rad/lsz; n++)
48  {
49    const int r = mad24(n, lsz, lsz - lid);
50    if(r > rad) continue;
51    const int xx = mad24((int)get_group_id(0), lsz, lsz - 1 + r);
52    buffer[rad + lsz - 1 + r] = read_imagef(in, sampleri, (int2)(xx, y)).x;
53  }
54
55  barrier(CLK_LOCAL_MEM_FENCE);
56
57  if(x >= width || y >= height) return;
58
59  buffer += lid + rad;
60  m += rad;
61
62  float sum = 0.0f;
63
64  for (int i=-rad; i<=rad; i++)
65  {
66    sum += buffer[i] * m[i];
67  }
68
69  pixel.x = sum;
70  write_imagef (out, (int2)(x, y), pixel);
71}
72
73
74kernel void
75sharpen_vblur(read_only image2d_t in, write_only image2d_t out, global const float *m, const int rad,
76      const int width, const int height, const int blocksize, local float *buffer)
77{
78  const int lid = get_local_id(1);
79  const int lsz = get_local_size(1);
80  const int x = get_global_id(0);
81  const int y = get_global_id(1);
82  float4 pixel = (float4)0.0f;
83
84  /* read pixel and fill center part of buffer */
85  pixel = read_imagef(in, sampleri, (int2)(x, y));
86  buffer[rad + lid] = pixel.x;
87
88  /* left wing of buffer */
89  for(int n=0; n <= rad/lsz; n++)
90  {
91    const int l = mad24(n, lsz, lid + 1);
92    if(l > rad) continue;
93    const int yy = mad24((int)get_group_id(1), lsz, -l);
94    buffer[rad - l] = read_imagef(in, sampleri, (int2)(x, yy)).x;
95  }
96
97  /* right wing of buffer */
98  for(int n=0; n <= rad/lsz; n++)
99  {
100    const int r = mad24(n, lsz, lsz - lid);
101    if(r > rad) continue;
102    const int yy = mad24((int)get_group_id(1), lsz, lsz - 1 + r);
103    buffer[rad + lsz - 1 + r] = read_imagef(in, sampleri, (int2)(x, yy)).x;
104  }
105
106  barrier(CLK_LOCAL_MEM_FENCE);
107
108  if(x >= width || y >= height) return;
109
110  buffer += lid + rad;
111  m += rad;
112
113  float sum = 0.0f;
114
115  for (int i=-rad; i<=rad; i++)
116  {
117    sum += buffer[i] * m[i];
118  }
119
120  pixel.x = sum;
121  write_imagef (out, (int2)(x, y), pixel);
122}
123
124
125
126/* final mixing step for sharpen plugin.
127 * in_a = original image
128 * in_b = blurred image
129 * out  = sharpened image
130 * sharpen = level of sharpening
131 * thrs = sharpening threshold
132 */
133kernel void
134sharpen_mix(read_only image2d_t in_a, read_only image2d_t in_b, write_only image2d_t out,
135            const int width, const int height, const float sharpen, const float thrs)
136{
137  const int x = get_global_id(0);
138  const int y = get_global_id(1);
139
140  if(x >= width || y >= height) return;
141
142  float4 pixel = read_imagef(in_a, sampleri, (int2)(x, y));
143  float blurredx  = read_imagef(in_b, sampleri, (int2)(x, y)).x;
144  float4 Labmin = (float4)(0.0f, -128.0f, -128.0f, 0.0f);
145  float4 Labmax = (float4)(100.0f, 128.0f, 128.0f, 1.0f);
146
147  float delta = pixel.x - blurredx;
148  float amount = sharpen * copysign(fmax(0.0f, fabs(delta) - thrs), delta);
149  pixel.x = pixel.x + amount;
150  write_imagef (out, (int2)(x, y), pixel);
151}
152
153