Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
equalizer_eaw.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2009-2021 darktable developers.
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#pragma once
20
21// edge-avoiding wavelet:
22#define gweight(i, j, ii, jj) \
23 1.0 / (fabsf(weight_a[l][(size_t)wd * ((j) >> (l - 1)) + ((i) >> (l - 1))] \
24 - weight_a[l][(size_t)wd * ((jj) >> (l - 1)) + ((ii) >> (l - 1))]) + 1.e-5)
25// #define gweight(i, j, ii, jj) 1.0/(powf(fabsf(weight_a[l][wd*((j)>>(l-1)) + ((i)>>(l-1))] -
26// weight_a[l][wd*((jj)>>(l-1)) + ((ii)>>(l-1))]),0.8)+1.e-5)
27// std cdf(2,2) wavelet:
28// #define gweight(i, j, ii, jj) (wd ? 1.0 : 1.0) //1.0
29#define gbuf(BUF, A, B) ((BUF)[4 * ((size_t)width * ((B)) + ((A))) + ch])
30
31
32static void dt_iop_equalizer_wtf(float *const buf, float **weight_a, const int l, const int width, const int height)
33{
34 const int wd = (int)(1 + (width >> (l - 1))), ht = (int)(1 + (height >> (l - 1)));
35 int ch = 0;
36 // store weights for luma channel only, chroma uses same basis.
37 for(int j = 0; j < ht - 1; j++)
38 {
39 for(int i = 0; i < wd - 1; i++) weight_a[l][(size_t)j * wd + i] = gbuf(buf, i << (l - 1), j << (l - 1));
40 weight_a[l][j * wd + (wd - 1)] = 0.0f; // zero out right-most column
41 }
42 for(int i = 0; i < wd; i++) // zero out the bottom row
43 weight_a[l][(ht-1) * wd + i] = 0.0f;
44
45 const int step = 1 << l;
46 const int st = step / 2;
47
48 size_t scratch_size;
49 float *const restrict tmp_width_buf = dt_alloc_perthread_float(width, &scratch_size);
50 if(tmp_width_buf == NULL) return;
51
52#ifdef _OPENMP
53#pragma omp parallel for default(none) \
54 dt_omp_firstprivate(height, l, st, step, tmp_width_buf, scratch_size, wd, width) \
55 dt_omp_sharedconst(buf) \
56 shared(weight_a) \
57 private(ch) \
58 schedule(static)
59#endif
60 for(int j = 0; j < height; j++)
61 {
62 // rows
63 // precompute weights:
64 float *tmp = dt_get_perthread(tmp_width_buf, scratch_size);
65 for(int i = 0; i < width - st; i += st) tmp[i] = gweight(i, j, i + st, j);
66 // predict, get detail
67 int i = st;
68 for(; i < width - st; i += step)
69 for(ch = 0; ch < 3; ch++)
70 gbuf(buf, i, j) -= (tmp[i - st] * gbuf(buf, i - st, j) + tmp[i] * gbuf(buf, i + st, j))
71 / (tmp[i - st] + tmp[i]);
72 if(i < width)
73 for(ch = 0; ch < 3; ch++) gbuf(buf, i, j) -= gbuf(buf, i - st, j);
74 // update coarse
75 for(ch = 0; ch < 3; ch++) gbuf(buf, 0, j) += gbuf(buf, st, j) * 0.5f;
76 for(i = step; i < width - st; i += step)
77 for(ch = 0; ch < 3; ch++)
78 gbuf(buf, i, j) += (tmp[i - st] * gbuf(buf, i - st, j) + tmp[i] * gbuf(buf, i + st, j))
79 / (2.0 * (tmp[i - st] + tmp[i]));
80 if(i < width)
81 for(ch = 0; ch < 3; ch++) gbuf(buf, i, j) += gbuf(buf, i - st, j) * .5f;
82 }
83
84 dt_free_align(tmp_width_buf);
85
86 float *const restrict tmp_height_buf = dt_alloc_perthread_float(height, &scratch_size);
87 if(tmp_height_buf == NULL) return;
88
89#ifdef _OPENMP
90#pragma omp parallel for default(none) \
91 dt_omp_firstprivate(height, l, st, step, tmp_height_buf, scratch_size, wd, width) \
92 dt_omp_sharedconst(buf) \
93 shared(weight_a) \
94 private(ch) \
95 schedule(static)
96#endif
97 for(int i = 0; i < width; i++)
98 {
99 // cols
100 // precompute weights:
101 float *const tmp = dt_get_perthread(tmp_height_buf, scratch_size);
102 for(int j = 0; j < height - st; j += st) tmp[j] = gweight(i, j, i, j + st);
103 int j = st;
104 // predict, get detail
105 for(; j < height - st; j += step)
106 for(ch = 0; ch < 3; ch++)
107 gbuf(buf, i, j) -= (tmp[j - st] * gbuf(buf, i, j - st) + tmp[j] * gbuf(buf, i, j + st))
108 / (tmp[j - st] + tmp[j]);
109 if(j < height)
110 for(ch = 0; ch < 3; ch++) gbuf(buf, i, j) -= gbuf(buf, i, j - st);
111 // update
112 for(ch = 0; ch < 3; ch++) gbuf(buf, i, 0) += gbuf(buf, i, st) * 0.5;
113 for(j = step; j < height - st; j += step)
114 for(ch = 0; ch < 3; ch++)
115 gbuf(buf, i, j) += (tmp[j - st] * gbuf(buf, i, j - st) + tmp[j] * gbuf(buf, i, j + st))
116 / (2.0 * (tmp[j - st] + tmp[j]));
117 if(j < height)
118 for(ch = 0; ch < 3; ch++) gbuf(buf, i, j) += gbuf(buf, i, j - st) * .5f;
119 }
120
121 dt_free_align(tmp_height_buf);
122}
123
124static void dt_iop_equalizer_iwtf(float *buf, float **weight_a, const int l, const int width, const int height)
125{
126 const int step = 1 << l;
127 const int st = step / 2;
128 const int wd = (int)(1 + (width >> (l - 1)));
129
130 size_t scratch_size;
131 float *const restrict tmp_height_buf = dt_alloc_perthread_float(height, &scratch_size);
132 if(tmp_height_buf == NULL) return;
133
134#ifdef _OPENMP
135#pragma omp parallel for default(none) \
136 dt_omp_firstprivate(height, l, st, step, tmp_height_buf, scratch_size, wd, width) \
137 shared(weight_a, buf) \
138 schedule(static)
139#endif
140 for(int i = 0; i < width; i++)
141 {
142 // cols
143 float *const restrict tmp = dt_get_perthread(tmp_height_buf, scratch_size);
144 int j;
145 for(j = 0; j < height - st; j += st) tmp[j] = gweight(i, j, i, j + st);
146 // update coarse
147 for(int ch = 0; ch < 3; ch++) gbuf(buf, i, 0) -= gbuf(buf, i, st) * 0.5f;
148 for(j = step; j < height - st; j += step)
149 for(int ch = 0; ch < 3; ch++)
150 gbuf(buf, i, j) -= (tmp[j - st] * gbuf(buf, i, j - st) + tmp[j] * gbuf(buf, i, j + st))
151 / (2.0 * (tmp[j - st] + tmp[j]));
152 if(j < height)
153 for(int ch = 0; ch < 3; ch++) gbuf(buf, i, j) -= gbuf(buf, i, j - st) * .5f;
154 // predict
155 for(j = st; j < height - st; j += step)
156 for(int ch = 0; ch < 3; ch++)
157 gbuf(buf, i, j) += (tmp[j - st] * gbuf(buf, i, j - st) + tmp[j] * gbuf(buf, i, j + st))
158 / (tmp[j - st] + tmp[j]);
159 if(j < height)
160 for(int ch = 0; ch < 3; ch++) gbuf(buf, i, j) += gbuf(buf, i, j - st);
161 }
162
163 dt_free_align(tmp_height_buf);
164
165 float *const restrict tmp_width_buf = dt_alloc_perthread_float(width, &scratch_size);
166 if(tmp_width_buf == NULL) return;
167
168#ifdef _OPENMP
169#pragma omp parallel for default(none) \
170 dt_omp_firstprivate(height, l, st, step, tmp_width_buf, scratch_size, wd, width) \
171 shared(weight_a, buf) \
172 schedule(static)
173#endif
174 for(int j = 0; j < height; j++)
175 {
176 // rows
177 float *const restrict tmp = dt_get_perthread(tmp_width_buf, scratch_size);
178 for(int i = 0; i < width - st; i += st) tmp[i] = gweight(i, j, i + st, j);
179 // update
180 for(int ch = 0; ch < 3; ch++) gbuf(buf, 0, j) -= gbuf(buf, st, j) * 0.5f;
181 int i;
182 for(i = step; i < width - st; i += step)
183 for(int ch = 0; ch < 3; ch++)
184 gbuf(buf, i, j) -= (tmp[i - st] * gbuf(buf, i - st, j) + tmp[i] * gbuf(buf, i + st, j))
185 / (2.0 * (tmp[i - st] + tmp[i]));
186 if(i < width)
187 for(int ch = 0; ch < 3; ch++) gbuf(buf, i, j) -= gbuf(buf, i - st, j) * 0.5f;
188 // predict
189 for(i = st; i < width - st; i += step)
190 for(int ch = 0; ch < 3; ch++)
191 gbuf(buf, i, j) += (tmp[i - st] * gbuf(buf, i - st, j) + tmp[i] * gbuf(buf, i + st, j))
192 / (tmp[i - st] + tmp[i]);
193 if(i < width)
194 for(int ch = 0; ch < 3; ch++) gbuf(buf, i, j) += gbuf(buf, i - st, j);
195 }
196
197 dt_free_align(tmp_width_buf);
198}
199
200#undef gbuf
201#undef gweight
202// clang-format off
203// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
204// vim: shiftwidth=2 expandtab tabstop=2 cindent
205// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
206// clang-format on
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
#define dt_get_perthread(buf, padsize)
Definition darktable.h:797
#define dt_free_align(A)
Definition darktable.h:334
static float * dt_alloc_perthread_float(const size_t n, size_t *padded_size)
Definition darktable.h:780
#define gweight(i, j, ii, jj)
Definition equalizer_eaw.h:22
#define gbuf(BUF, A, B)
Definition equalizer_eaw.h:29
static void dt_iop_equalizer_iwtf(float *buf, float **weight_a, const int l, const int width, const int height)
Definition equalizer_eaw.h:124
static void dt_iop_equalizer_wtf(float *const buf, float **weight_a, const int l, const int width, const int height)
Definition equalizer_eaw.h:32