Krita Source Code Documentation
Loading...
Searching...
No Matches
lut.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2010 Cyrille Berger <cberger@cberger.net>
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _LUT_H_
8#define _LUT_H_
9
10template<typename _InputT_>
11class LutKey;
12
13template<typename _InputT_>
15
31template<typename _FunctionT_, typename _OutputT_, typename _InputT_, typename _LutKeyT_ >
32class BaseLut {
33 private:
37 inline void init()
38 {
39 int size = m_key.size();
40 m_table = new _OutputT_[size];
41 for(int i = 0; i < size; ++i)
42 {
43 m_table[i] = m_function(m_key.keyToInput(i));
44 }
45 }
46 public:
50 inline BaseLut(_LutKeyT_ key, _FunctionT_ function = _FunctionT_()) : m_key(key), m_function(function)
51 {
52 init();
53 }
54 inline ~BaseLut() {
55 // just leak on exit -- we get into trouble for explicitly
56 // deleting stuff from static objects, like registries
57 //delete[] m_table;
58 }
59 public:
63 inline _OutputT_ operator()(_InputT_ i) const
64 {
65 if(m_key.inrange(i))
66 {
67 return m_table[m_key.inputToKey(i)];
68 }
69 return m_function(i);
70 }
71 private:
72 _OutputT_* m_table;
73 _LutKeyT_ m_key;
74 _FunctionT_ m_function;
75};
76
80template<typename _FunctionT_, typename _OutputT_, typename _InputT_>
81class Lut : public BaseLut<_FunctionT_, _OutputT_, _InputT_, LutKey<_InputT_> > {
82 public:
86 inline Lut(_InputT_ _min, _InputT_ _max, _FunctionT_ function = _FunctionT_()) :
87 BaseLut<_FunctionT_, _OutputT_, _InputT_, LutKey<_InputT_> >( LutKey<_InputT_>(_min, _max), function)
88 {
89 }
90 inline Lut(LutKey<_InputT_> key, _FunctionT_ function = _FunctionT_()) :
91 BaseLut<_FunctionT_, _OutputT_, _InputT_, LutKey<_InputT_> >( key, function)
92 {
93 }
94};
95
99template<typename _FunctionT_, typename _OutputT_, typename _InputT_>
100class FullLut : public BaseLut<_FunctionT_, _OutputT_, _InputT_, FullLutKey<_InputT_> > {
101 public:
102 inline FullLut( _FunctionT_ function = _FunctionT_()) :
103 BaseLut<_FunctionT_, _OutputT_, _InputT_, FullLutKey<_InputT_> >( FullLutKey<_InputT_>(), function)
104 {
105 }
106};
107
108#ifdef _USE_QT_TYPES_
109typedef quint8 lut_uint8;
110typedef quint16 lut_uint16;
111typedef quint32 lut_uint32;
112#else
113#include <stdint.h>
114typedef uint8_t lut_uint8;
115typedef uint16_t lut_uint16;
116typedef uint32_t lut_uint32;
117#endif
118
119// integer specialization
120
121#define PARTIAL_LUT_INT_SPECIALIZATION(_INT_TYPE_) \
122 template<> \
123 class LutKey<_INT_TYPE_> { \
124 public: \
125 LutKey(_INT_TYPE_ min, _INT_TYPE_ max) : m_min(min), m_max(max) \
126 { \
127 } \
128 public: \
129 inline int inputToKey(_INT_TYPE_ i) const \
130 { \
131 return i - m_min; \
132 } \
133 inline _INT_TYPE_ keyToInput(int k) const \
134 { \
135 return k + m_min; \
136 } \
137 inline bool inrange(_INT_TYPE_ i) const \
138 { \
139 return i >= m_min && i <= m_max; \
140 } \
141 inline _INT_TYPE_ minimum() const \
142 { \
143 return m_min; \
144 } \
145 inline _INT_TYPE_ maximum() const \
146 { \
147 return m_max; \
148 } \
149 inline int size() const \
150 { \
151 return m_max - m_min + 1; \
152 } \
153 private: \
154 _INT_TYPE_ m_min, m_max; \
155 };
156
160
161#define FULL_LUT_INT_SPECIALIZATION(_INT_TYPE_, _MIN_, _MAX_) \
162 template<> \
163 class FullLutKey<_INT_TYPE_> { \
164 public: \
165 FullLutKey() \
166 { \
167 } \
168 public: \
169 inline int inputToKey(_INT_TYPE_ i) const \
170 { \
171 return i - _MIN_; \
172 } \
173 inline _INT_TYPE_ keyToInput(int k) const \
174 { \
175 return k + _MIN_; \
176 } \
177 inline bool inrange(_INT_TYPE_ ) const \
178 { \
179 return true; \
180 } \
181 inline _INT_TYPE_ minimum() const \
182 { \
183 return _MIN_; \
184 } \
185 inline _INT_TYPE_ maximum() const \
186 { \
187 return _MAX_; \
188 } \
189 inline int size() const \
190 { \
191 return _MAX_ - _MIN_ + 1; \
192 } \
193 private: \
194 };
195
198
199// float specialization
200
207template<>
208class LutKey<float> {
209 public:
210 union IFNumber {
212 float f;
213 };
214 public:
215 LutKey(float min, float max, float precision) : m_min(min), m_max(max), m_precision(precision)
216 {
217 // Those values where computed using the test_linear and setting the shift and then using
218 // the standard deviation.
219 if (precision <= 0.000011809f) {
220 m_min = 1;
221 m_max = -1;
222 }
223 else if (precision <= 0.0000237291f) m_shift = 8;
224 else if (precision <= 0.0000475024f) m_shift = 9;
225 else if (precision <= 0.0000948575f) m_shift = 10;
226 else if (precision <= 0.00019013f) m_shift = 11;
227 else if (precision <= 0.000379523f) m_shift = 12;
228 else if (precision <= 0.000758431f) m_shift = 13;
229 else if (precision <= 0.00151891f) m_shift = 14;
230 else if (precision <= 0.00303725f) m_shift = 15;
231 else m_shift = 16;
232
233 if ( 0.0 <= m_min && m_min <= precision)
234 m_min = precision;
235 if ( -precision <= m_max && m_max <= 0.0)
236 m_max = -precision;
237
238 IFNumber uf;
239
240 if(m_min > 0 && m_max > 0)
241 {
242 uf.f = m_min;
243 m_tMin_p = uf.i >> m_shift;
244 uf.f = m_max;
245 m_tMax_p = uf.i >> m_shift;
246 m_tMin_n = m_tMax_p;
247 m_tMax_n = m_tMax_p;
248 } else if( m_max < 0)
249 {
250 uf.f = m_min;
251 m_tMax_n = uf.i >> m_shift;
252 uf.f = m_max;
253 m_tMin_n = uf.i >> m_shift;
254 m_tMin_p = m_tMax_n;
255 m_tMax_p = m_tMax_n;
256 } else { // m_min <0 && m_max > 0
257 uf.f = precision;
258 m_tMin_p = uf.i >> m_shift;
259 uf.f = m_max;
260 m_tMax_p = uf.i >> m_shift;
261 uf.f = -precision;
262 m_tMin_n = uf.i >> m_shift;
263 uf.f = m_min;
264 m_tMax_n = uf.i >> m_shift;
265 }
266 m_diff_p = m_tMax_p - m_tMin_p;
267 }
268 public:
269 inline int inputToKey(float i) const
270 {
271 IFNumber uf;
272 uf.f = i;
273 int k = (uf.i >> m_shift);
274 if(k <= m_tMax_p)
275 {
276 return k - m_tMin_p;
277 } else {
278 return k - m_tMin_n + m_diff_p;
279 }
280 }
281 inline float keyToInput(int k) const
282 {
283 IFNumber uf;
284 if( k <= m_diff_p ) {
285 uf.i = ((k + m_tMin_p) << m_shift);
286 } else {
287 uf.i = ((k + m_tMin_n - m_diff_p ) << m_shift);
288 }
289 return uf.f;
290 }
291 inline bool inrange(float i) const
292 {
293 return i >= m_min && i <= m_max && (i < -m_precision || i > m_precision);
294 }
295 inline float minimum() const
296 {
297 return m_min;
298 }
299 inline float maximum() const
300 {
301 return m_max;
302 }
303 inline int size() const
304 {
305 return m_diff_p + m_tMax_n - m_tMin_p + 1;
306 }
307 private:
308 float m_min, m_max, m_precision;
309 int m_tMin_p, m_tMax_p, m_tMin_n, m_tMax_n, m_diff_p;
311};
312
313#endif
Definition lut.h:32
BaseLut(_LutKeyT_ key, _FunctionT_ function=_FunctionT_())
Definition lut.h:50
_FunctionT_ m_function
Definition lut.h:74
_LutKeyT_ m_key
Definition lut.h:73
_OutputT_ * m_table
Definition lut.h:72
void init()
Definition lut.h:37
_OutputT_ operator()(_InputT_ i) const
Definition lut.h:63
~BaseLut()
Definition lut.h:54
Definition lut.h:100
FullLut(_FunctionT_ function=_FunctionT_())
Definition lut.h:102
int inputToKey(float i) const
Definition lut.h:269
bool inrange(float i) const
Definition lut.h:291
float keyToInput(int k) const
Definition lut.h:281
int m_shift
Definition lut.h:310
LutKey(float min, float max, float precision)
Definition lut.h:215
float minimum() const
Definition lut.h:295
int size() const
Definition lut.h:303
float maximum() const
Definition lut.h:299
int m_diff_p
Definition lut.h:309
float m_max
Definition lut.h:308
Definition lut.h:11
Definition lut.h:81
Lut(LutKey< _InputT_ > key, _FunctionT_ function=_FunctionT_())
Definition lut.h:90
Lut(_InputT_ _min, _InputT_ _max, _FunctionT_ function=_FunctionT_())
Definition lut.h:86
#define PARTIAL_LUT_INT_SPECIALIZATION(_INT_TYPE_)
Definition lut.h:121
uint8_t lut_uint8
Definition lut.h:114
#define FULL_LUT_INT_SPECIALIZATION(_INT_TYPE_, _MIN_, _MAX_)
Definition lut.h:161
uint16_t lut_uint16
Definition lut.h:115
uint32_t lut_uint32
Definition lut.h:116