App

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

TLUTGenerator.cpp
Go to the documentation of this file.
1 /*
2 * TLUTGenerator.cpp
3 *
4 * Created on: Mar 24, 2013
5 * Author: xxx
6 */
7
8 #include "TLUTGenerator.hpp"
9
10 namespace app {
11
12 template class TLUTGenerator<px_4x8bit, px_1x8bit> ;
13
14 template<typename TPIXEL, typename TCHANNEL> TLUTGenerator<TPIXEL, TCHANNEL>::~TLUTGenerator() {
15
16 }
17
18 template<typename TPIXEL, typename TCHANNEL>
19 TLUT<TPIXEL, TCHANNEL> * TLUTGenerator<TPIXEL, TCHANNEL>::createCurvesLUT_4ch(
20 double* xM, double* yM, unsigned cM,
21 double* xR, double* yR, unsigned cR,
22 double* xG, double* yG, unsigned cG,
23 double* xB, double* yB, unsigned cB,
24 double* xA, double* yA, unsigned cA) {
25 TLUT<TPIXEL, TCHANNEL> * retVal = new TLUT<TPIXEL, TCHANNEL>();
26 if (retVal == NULL) {
27 return NULL;
28 }
29 if (!retVal->isInitOk()) {
30 delete retVal;
31 return NULL;
32 }
33 if (fillCurvesLUT_4ch(*retVal, xM, yM, cM, xR, yR, cR, xG, yG, cG, xB, yB, cB, xA, yA, cA)) {
34 delete retVal;
35 return NULL;
36 }
37 return retVal;
38 }
39
40
41 template<typename TPIXEL, typename TCHANNEL>
42 int TLUTGenerator<TPIXEL, TCHANNEL>::fillCurvesLUT_4ch(TLUT<TPIXEL, TCHANNEL> & dst,
43 double* xM, double* yM, unsigned cM,
44 double* xR, double* yR, unsigned cR,
45 double* xG, double* yG, unsigned cG,
46 double* xB, double* yB, unsigned cB,
47 double* xA, double* yA, unsigned cA) {
48
49 if (!dst.isInitOk()) {
50 return 1;
51 }
52
53 CubicSpline * splines[] = {NULL, NULL, NULL, NULL, NULL};
54 int initiOk = 1;
55
56 if (xM != NULL && yM != NULL && initiOk) {
57 splines[0] = new CubicSpline(xM, yM, cM);
58 if (splines[0] == NULL) {
59 initiOk = 0;
60 }
61 }
62 if (xR != NULL && yR != NULL && initiOk) {
63 splines[1] = new CubicSpline(xR, yR, cR);
64 if (splines[1] == NULL) {
65 initiOk = 0;
66 }
67 }
68 if (xG != NULL && yG != NULL && initiOk) {
69 splines[2] = new CubicSpline(xG, yG, cG);
70 if (splines[2] == NULL) {
71 initiOk = 0;
72 }
73 }
74 if (xB != NULL && yB != NULL && initiOk) {
75 splines[3] = new CubicSpline(xB, yB, cB);
76 if (splines[3] == NULL) {
77 initiOk = 0;
78 }
79 }
80 if (xA != NULL && yA != NULL && initiOk) {
81 splines[4] = new CubicSpline(xA, yA, cA);
82 if (splines[3] == NULL) {
83 initiOk = 0;
84 }
85 }
86
87 if (initiOk) {
88 for (int i = 0; i < 3; i++) {
89 prepareChannelLUT(dst.getValues()[i], splines[0], splines[i + 1]);
90 }
91 prepareChannelLUT(dst.getValues()[3], splines[4]);
92 }
93
94 for (int i = 0; i < 5; i++) {
95 if (splines[i] != NULL) {
96 delete splines[i];
97 }
98 }
99 return 0;
100 }
101
102 template <typename TPIXEL, typename TCHANNEL>
103 int TLUTGenerator<TPIXEL, TCHANNEL>::prepareChannelLUT(TCHANNEL * ch, CubicSpline *sp) {
104 if (ch == NULL) { return 1; }
105 TCHANNEL * chEnd = ch + maxVal + 1;
106 if (sp == NULL) {
107 int i = 0;
108 while (ch < chEnd) {
109 *ch = i++;
110 ch++;
111 }
112 return 0;
113 }
114 long tmp;
115 double x = 0;
116 double dx = 1 / (double) maxVal;
117 while (ch < chEnd) {
118 tmp = sp->getValueAt(x) * maxVal + 0.5;
119 *ch = (tmp >= maxVal) ? maxVal : (tmp <= 0) ? 0 : tmp; // !!! Vždy by mělo být v této podobě ve správném rozsahu, takže pro optimalizaci by šla vynechat kontrola mezí...
120 ch++; x += dx;
121 }
122 return 0;
123 }
124
125 template <typename TPIXEL, typename TCHANNEL>
126 int TLUTGenerator<TPIXEL, TCHANNEL>::prepareChannelLUT(TCHANNEL * ch, CubicSpline *sp1, CubicSpline *sp2) {
127 if (ch == NULL) { return 1; }
128 if (sp1 == NULL) { return prepareChannelLUT(ch, sp2); }
129 if (sp2 == NULL) { return prepareChannelLUT(ch, sp1); }
130 TCHANNEL * chEnd = ch + maxVal + 1;
131 long tmp;
132 double x = 0;
133 double dx = 1 / (double) maxVal;
134 while (ch < chEnd) {
135 tmp = sp1->getValueAt(sp2->getValueAt(x)) * maxVal + 0.5; // V tomhle pořadí aplikuje operace GIMP
136 *ch = (tmp >= maxVal) ? maxVal : (tmp <= 0) ? 0 : tmp; // !!! Vždy by mělo být v této podobě ve správném rozsahu, takže pro optimalizaci by šla vynechat kontrola mezí...
137 ch++; x += dx;
138 }
139 return 0;
140 }
141
142
143 template<typename TPIXEL, typename TCHANNEL>
144 int TLUTGenerator<TPIXEL, TCHANNEL>::fillBrightnessLUT_4ch(TLUT<TPIXEL, TCHANNEL> & dst, double bias) {
145
146 double factor = (bias < 0) ? 1 + bias : 1 - bias;
147 TCHANNEL offset = (bias < 0) ? 0 : bias * maxVal + 0.5;
148 if (!dst.isInitOk()) {
149 return 1;
150 }
151
152 TCHANNEL * lut = dst.getValues()[0];
153 TCHANNEL * lutEnd = lut + maxVal + 1;
154 long tmp;
155 int i = 0;
156 while (lut < lutEnd) {
157 *lut = factor * i + offset + 0.5;
158 i++;
159 // *lut = (tmp >= maxVal) ? maxVal : (tmp <= 0) ? 0 : tmp; // !!! Vždy by mělo být v této podobě ve správném rozsahu, takže pro optimalizaci by šla vynechat kontrola mezí...
160 lut++;
161 }
162 memcpy(dst.getValues()[1], dst.getValues()[0], (maxVal + 1) * sizeof(TCHANNEL));
163 memcpy(dst.getValues()[2], dst.getValues()[0], (maxVal + 1) * sizeof(TCHANNEL));
164 lut = dst.getValues()[3];
165 lutEnd = lut + maxVal + 1;
166 i = 0;
167 while (lut < lutEnd) {
168 *lut = i++;
169 lut++;
170 }
171 return 0;
172 }
173
174 template<typename TPIXEL, typename TCHANNEL>
175 TLUT<TPIXEL, TCHANNEL> * TLUTGenerator<TPIXEL, TCHANNEL>::createBrightnessLUT_4ch(double bias) {
176
177 TLUT<TPIXEL, TCHANNEL> * retVal = new TLUT<TPIXEL, TCHANNEL>();
178 if (retVal == NULL) {
179 return NULL;
180 }
181 if (!retVal->isInitOk()) {
182 delete retVal;
183 return NULL;
184 }
185 if (fillBrightnessLUT_4ch(*retVal, bias)) {
186 delete retVal;
187 return NULL;
188 }
189 return retVal;
190 }
191
192 template<typename TPIXEL, typename TCHANNEL>
193 int TLUTGenerator<TPIXEL, TCHANNEL>::fillContrastLUT_4ch(TLUT<TPIXEL, TCHANNEL> & dst, double bias) {
194 double factor = (bias + 1) / (1.0001 - bias);
195 if (!dst.isInitOk()) {
196 return 1;
197 }
198
199 TCHANNEL * lut = dst.getValues()[0];
200 TCHANNEL * lutEnd = lut + maxVal + 1;
201 long tmp;
202 int i = 0;
203 while (lut < lutEnd) {
204 tmp = factor * (i - halfVal) + halfVal + 0.5;
205 i++;
206 *lut = (tmp >= maxVal) ? maxVal : (tmp <= 0) ? 0 : tmp;
207 lut++;
208 }
209 memcpy(dst.getValues()[1], dst.getValues()[0], (maxVal + 1) * sizeof(TCHANNEL));
210 memcpy(dst.getValues()[2], dst.getValues()[0], (maxVal + 1) * sizeof(TCHANNEL));
211 lut = dst.getValues()[3];
212 lutEnd = lut + maxVal + 1;
213 i = 0;
214 while (lut < lutEnd) {
215 *lut = i++;
216 lut++;
217 }
218 return 0;
219 }
220
221 template<typename TPIXEL, typename TCHANNEL>
222 TLUT<TPIXEL, TCHANNEL> * TLUTGenerator<TPIXEL, TCHANNEL>::createContrastLUT_4ch(double bias) {
223 TLUT<TPIXEL, TCHANNEL> * retVal = new TLUT<TPIXEL, TCHANNEL>();
224 if (retVal == NULL) {
225 return NULL;
226 }
227 if (!retVal->isInitOk()) {
228 delete retVal;
229 return NULL;
230 }
231 if (fillContrastLUT_4ch(*retVal, bias)) {
232 delete retVal;
233 return NULL;
234 }
235 return retVal;
236 }
237
238 template<typename TPIXEL, typename TCHANNEL>
239 int TLUTGenerator<TPIXEL, TCHANNEL>::fillGammaLUT_4ch(TLUT<TPIXEL, TCHANNEL> & dst, double gamma) {
240 if (gamma < 0.00001) {
241 gamma = 0.00001;
242 } else if (gamma > 100) {
243 gamma = 100;
244 }
245 if (!dst.isInitOk()) {
246 return 1;
247 }
248
249 TCHANNEL * lut = dst.getValues()[0];
250 TCHANNEL * lutEnd = lut + maxVal + 1;
251 long tmp;
252 double val = 0;
253 double delta = 1.0 / maxVal;
254 while (lut < lutEnd) {
255 *lut = maxVal * (pow(val, gamma)) + 0.5;
256 val += delta;
257 // *lut = (tmp >= maxVal) ? maxVal : (tmp <= 0) ? 0 : tmp; // Clamping pravdepodobne neni nutny...
258 lut++;
259 }
260 memcpy(dst.getValues()[1], dst.getValues()[0], (maxVal + 1) * sizeof(TCHANNEL));
261 memcpy(dst.getValues()[2], dst.getValues()[0], (maxVal + 1) * sizeof(TCHANNEL));
262 lut = dst.getValues()[3];
263 lutEnd = lut + maxVal + 1;
264 int i = 0;
265 while (lut < lutEnd) {
266 *lut = i++;
267 lut++;
268 }
269 return 0;
270 }
271
272 template<typename TPIXEL, typename TCHANNEL>
273 TLUT<TPIXEL, TCHANNEL> * TLUTGenerator<TPIXEL, TCHANNEL>::createGammaLUT_4ch(double gamma) {
274 TLUT<TPIXEL, TCHANNEL> * retVal = new TLUT<TPIXEL, TCHANNEL>();
275 if (retVal == NULL) {
276 return NULL;
277 }
278 if (!retVal->isInitOk()) {
279 delete retVal;
280 return NULL;
281 }
282 if (fillGammaLUT_4ch(*retVal, gamma)) {
283 delete retVal;
284 return NULL;
285 }
286 return retVal;
287 }
288
289 } /* namespace app */