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/* This is highpass for Lab space. We only do invert/blur/mix on L and desaturate a and b */
23
24kernel void
25highpass_invert(read_only image2d_t in, write_only image2d_t out, const int width, const int height)
26{
27  const int x = get_global_id(0);
28  const int y = get_global_id(1);
29
30  if(x >= width || y >= height) return;
31
32  float4 pixel = read_imagef(in, sampleri, (int2)(x, y));
33  pixel.x = clamp(100.0f - pixel.x, 0.0f, 100.0f);
34  write_imagef (out, (int2)(x, y), pixel);
35}
36
37
38kernel void
39highpass_hblur(read_only image2d_t in, write_only image2d_t out, global float *m, const int rad,
40      const int width, const int height, const int blocksize, local float *buffer)
41{
42  const int lid = get_local_id(0);
43  const int lsz = get_local_size(0);
44  const int x = get_global_id(0);
45  const int y = get_global_id(1);
46  float4 pixel = (float4)0.0f;
47
48  /* read pixel and fill center part of buffer */
49  pixel = read_imagef(in, sampleri, (int2)(x, y));
50  buffer[rad + lid] = pixel.x;
51
52  /* left wing of buffer */
53  for(int n=0; n <= rad/lsz; n++)
54  {
55    const int l = mad24(n, lsz, lid + 1);
56    if(l > rad) continue;
57    const int xx = mad24((int)get_group_id(0), lsz, -l);
58    buffer[rad - l] = read_imagef(in, sampleri, (int2)(xx, y)).x;
59  }
60
61  /* right wing of buffer */
62  for(int n=0; n <= rad/lsz; n++)
63  {
64    const int r = mad24(n, lsz, lsz - lid);
65    if(r > rad) continue;
66    const int xx = mad24((int)get_group_id(0), lsz, lsz - 1 + r);
67    buffer[rad + lsz - 1 + r] = read_imagef(in, sampleri, (int2)(xx, y)).x;
68  }
69
70  barrier(CLK_LOCAL_MEM_FENCE);
71
72  if(x >= width || y >= height) return;
73
74  buffer += lid + rad;
75  m += rad;
76
77  float sum = 0.0f;
78
79  for (int i=-rad; i<=rad; i++)
80  {
81    sum += buffer[i] * m[i];
82  }
83
84  pixel.x = sum;
85  write_imagef (out, (int2)(x, y), pixel);
86}
87
88
89
90kernel void
91highpass_vblur(read_only image2d_t in, write_only image2d_t out, global float *m, const int rad,
92      const int width, const int height, const int blocksize, local float *buffer)
93{
94  const int lid = get_local_id(1);
95  const int lsz = get_local_size(1);
96  const int x = get_global_id(0);
97  const int y = get_global_id(1);
98  float4 pixel = (float4)0.0f;
99
100  /* read pixel and fill center part of buffer */
101  pixel = read_imagef(in, sampleri, (int2)(x, y));
102  buffer[rad + lid] = pixel.x;
103
104  /* left wing of buffer */
105  for(int n=0; n <= rad/lsz; n++)
106  {
107    const int l = mad24(n, lsz, lid + 1);
108    if(l > rad) continue;
109    const int yy = mad24((int)get_group_id(1), lsz, -l);
110    buffer[rad - l] = read_imagef(in, sampleri, (int2)(x, yy)).x;
111  }
112
113  /* right wing of buffer */
114  for(int n=0; n <= rad/lsz; n++)
115  {
116    const int r = mad24(n, lsz, lsz - lid);
117    if(r > rad) continue;
118    const int yy = mad24((int)get_group_id(1), lsz, lsz - 1 + r);
119    buffer[rad + lsz - 1 + r] = read_imagef(in, sampleri, (int2)(x, yy)).x;
120  }
121
122  barrier(CLK_LOCAL_MEM_FENCE);
123
124  if(x >= width || y >= height) return;
125
126  buffer += lid + rad;
127  m += rad;
128
129  float sum = 0.0f;
130
131  for (int i=-rad; i<=rad; i++)
132  {
133    sum += buffer[i] * m[i];
134  }
135
136  pixel.x = sum;
137  write_imagef (out, (int2)(x, y), pixel);
138}
139
140
141
142kernel void
143highpass_mix(read_only image2d_t in_a, read_only image2d_t in_b, write_only image2d_t out,
144             const int width, const int height, const float contrast_scale)
145{
146  const int x = get_global_id(0);
147  const int y = get_global_id(1);
148
149  if(x >= width || y >= height) return;
150
151  float4 o = 0.0f;
152  float4 a = read_imagef(in_a, sampleri, (int2)(x, y));
153  float4 b = read_imagef(in_b, sampleri, (int2)(x, y));
154  float4 min = (float4)(0.0f, -128.0f, -128.0f, -INFINITY);
155  float4 max = (float4)(100.0f, 128.0f, 128.0f, INFINITY);
156
157  o.x = 50.0f+((0.5f * a.x + 0.5f * b.x) - 50.0f)*contrast_scale;
158  o.y = 0.0f;
159  o.z = 0.0f;
160  o.w = a.w;
161
162  write_imagef (out, (int2)(x, y), clamp(o, min, max));
163}
164
165