Changeset View
Changeset View
Standalone View
Standalone View
imagelib/effects/kpEffectToneEnhance.cpp
Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Line(s) | |||||
47 | #define TONE_MAP_SIZE ((MAX_TONE_VALUE >> TONE_DROP_BITS) + 1) | 47 | #define TONE_MAP_SIZE ((MAX_TONE_VALUE >> TONE_DROP_BITS) + 1) | ||
48 | #define MAX_GRANULARITY 25 | 48 | #define MAX_GRANULARITY 25 | ||
49 | #define MIN_IMAGE_DIM 3 | 49 | #define MIN_IMAGE_DIM 3 | ||
50 | 50 | | |||
51 | //--------------------------------------------------------------------- | 51 | //--------------------------------------------------------------------- | ||
52 | 52 | | |||
53 | inline unsigned int ComputeTone(unsigned int color) | 53 | inline unsigned int ComputeTone(unsigned int color) | ||
54 | { | 54 | { | ||
55 | return RED_WEIGHT * qRed(color) + GREEN_WEIGHT * qGreen(color) + BLUE_WEIGHT * qBlue(color); | 55 | return RED_WEIGHT * static_cast<unsigned int> (qRed(color)) + | ||
56 | GREEN_WEIGHT * static_cast<unsigned int> (qGreen(color)) + | ||||
57 | BLUE_WEIGHT * static_cast<unsigned int> (qBlue(color)); | ||||
56 | } | 58 | } | ||
57 | 59 | | |||
58 | //--------------------------------------------------------------------- | 60 | //--------------------------------------------------------------------- | ||
59 | 61 | | |||
60 | inline unsigned int AdjustTone(unsigned int color, unsigned int oldTone, unsigned int newTone, double amount) | 62 | inline unsigned int AdjustTone(unsigned int color, unsigned int oldTone, unsigned int newTone, double amount) | ||
61 | { | 63 | { | ||
62 | return qRgba( | 64 | return qRgba( | ||
63 | qMax(0, qMin(255, (int) (amount * qRed(color) * newTone / oldTone + (1.0 - amount) * qRed(color)))), | 65 | qMax(0, qMin(255, static_cast<int> (amount * qRed(color) * newTone / oldTone + (1.0 - amount) * qRed(color)))), | ||
64 | qMax(0, qMin(255, (int) (amount * qGreen(color) * newTone / oldTone + (1.0 - amount) * qGreen(color)))), | 66 | qMax(0, qMin(255, static_cast<int> (amount * qGreen(color) * newTone / oldTone + (1.0 - amount) * qGreen(color)))), | ||
65 | qMax(0, qMin(255, (int) (amount * qBlue(color) * newTone / oldTone + (1.0 - amount) * qBlue(color)))), | 67 | qMax(0, qMin(255, static_cast<int> (amount * qBlue(color) * newTone / oldTone + (1.0 - amount) * qBlue(color)))), | ||
66 | qAlpha(color) | 68 | qAlpha(color) | ||
67 | ); | 69 | ); | ||
68 | } | 70 | } | ||
69 | 71 | | |||
70 | //--------------------------------------------------------------------- | 72 | //--------------------------------------------------------------------- | ||
71 | 73 | | |||
72 | class kpEffectToneEnhanceApplier | 74 | class kpEffectToneEnhanceApplier | ||
73 | { | 75 | { | ||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Line(s) | 133 | { | |||
167 | int i; | 169 | int i; | ||
168 | for(i = 1; i < TONE_MAP_SIZE; i++) | 170 | for(i = 1; i < TONE_MAP_SIZE; i++) | ||
169 | m_pHistogram[i] += m_pHistogram[i - 1]; | 171 | m_pHistogram[i] += m_pHistogram[i - 1]; | ||
170 | 172 | | |||
171 | // Compute the forward contribution to the tone map | 173 | // Compute the forward contribution to the tone map | ||
172 | unsigned int total = m_pHistogram[i - 1]; | 174 | unsigned int total = m_pHistogram[i - 1]; | ||
173 | unsigned int* pToneMap = new unsigned int[TONE_MAP_SIZE]; | 175 | unsigned int* pToneMap = new unsigned int[TONE_MAP_SIZE]; | ||
174 | for(i = 0; i < TONE_MAP_SIZE; i++) | 176 | for(i = 0; i < TONE_MAP_SIZE; i++) | ||
175 | pToneMap[i] = (uint)((unsigned long long int)m_pHistogram[i] * MAX_TONE_VALUE / total); | 177 | pToneMap[i] = static_cast<uint> (static_cast<unsigned long long int> (m_pHistogram[i] * MAX_TONE_VALUE / total)); | ||
176 | /* | 178 | /* | ||
177 | // Undo the forward sum and reverse sum the tone histogram | 179 | // Undo the forward sum and reverse sum the tone histogram | ||
178 | m_pHistogram[TONE_MAP_SIZE - 1] -= m_pHistogram[TONE_MAP_SIZE - 2]; | 180 | m_pHistogram[TONE_MAP_SIZE - 1] -= m_pHistogram[TONE_MAP_SIZE - 2]; | ||
179 | for(i = TONE_MAP_SIZE - 2; i > 0; i--) | 181 | for(i = TONE_MAP_SIZE - 2; i > 0; i--) | ||
180 | { | 182 | { | ||
181 | m_pHistogram[i] -= m_pHistogram[i - 1]; | 183 | m_pHistogram[i] -= m_pHistogram[i - 1]; | ||
182 | m_pHistogram[i] += m_pHistogram[i + 1]; | 184 | m_pHistogram[i] += m_pHistogram[i + 1]; | ||
183 | } | 185 | } | ||
184 | m_pHistogram[0] += m_pHistogram[1]; | 186 | m_pHistogram[0] += m_pHistogram[1]; | ||
185 | */ | 187 | */ | ||
186 | return pToneMap; | 188 | return pToneMap; | ||
187 | } | 189 | } | ||
188 | 190 | | |||
189 | //--------------------------------------------------------------------- | 191 | //--------------------------------------------------------------------- | ||
190 | 192 | | |||
191 | // protected | 193 | // protected | ||
192 | void kpEffectToneEnhanceApplier::ComputeToneMaps(QImage* pImage, int nGranularity) | 194 | void kpEffectToneEnhanceApplier::ComputeToneMaps(QImage* pImage, int nGranularity) | ||
193 | { | 195 | { | ||
194 | if(nGranularity == m_nToneMapGranularity && pImage->width() == (int) m_nComputedWid && pImage->height() == (int) m_nComputedHgt) | 196 | if(nGranularity == m_nToneMapGranularity && pImage->width() == | ||
197 | static_cast<int> (m_nComputedWid) && pImage->height() == static_cast<int> (m_nComputedHgt)) | ||||
195 | { | 198 | { | ||
196 | return; // We've already computed tone maps for this granularity | 199 | return; // We've already computed tone maps for this granularity | ||
197 | } | 200 | } | ||
198 | DeleteToneMaps(); | 201 | DeleteToneMaps(); | ||
199 | m_pToneMaps = new unsigned int*[nGranularity * nGranularity]; | 202 | m_pToneMaps = new unsigned int*[nGranularity * nGranularity]; | ||
200 | m_nToneMapGranularity = nGranularity; | 203 | m_nToneMapGranularity = nGranularity; | ||
201 | m_nComputedWid = pImage->width(); | 204 | m_nComputedWid = static_cast<unsigned int> (pImage->width()); | ||
202 | m_nComputedHgt = pImage->height(); | 205 | m_nComputedHgt = static_cast<unsigned int> (pImage->height()); | ||
203 | int u, v; | 206 | int u, v; | ||
204 | for(v = 0; v < nGranularity; v++) | 207 | for(v = 0; v < nGranularity; v++) | ||
205 | { | 208 | { | ||
206 | for(u = 0; u < nGranularity; u++) | 209 | for(u = 0; u < nGranularity; u++) | ||
207 | m_pToneMaps[nGranularity * v + u] = MakeToneMap(pImage, u, v, nGranularity); | 210 | m_pToneMaps[nGranularity * v + u] = MakeToneMap(pImage, u, v, nGranularity); | ||
208 | } | 211 | } | ||
209 | } | 212 | } | ||
210 | 213 | | |||
Show All 9 Lines | 218 | { | |||
220 | int v = y * (nGranularity - 1) / pImage->height(); | 223 | int v = y * (nGranularity - 1) / pImage->height(); | ||
221 | unsigned int x1y1 = m_pToneMaps[m_nToneMapGranularity * v + u][oldTone]; | 224 | unsigned int x1y1 = m_pToneMaps[m_nToneMapGranularity * v + u][oldTone]; | ||
222 | unsigned int x2y1 = m_pToneMaps[m_nToneMapGranularity * v + u + 1][oldTone]; | 225 | unsigned int x2y1 = m_pToneMaps[m_nToneMapGranularity * v + u + 1][oldTone]; | ||
223 | unsigned int x1y2 = m_pToneMaps[m_nToneMapGranularity * (v + 1) + u][oldTone]; | 226 | unsigned int x1y2 = m_pToneMaps[m_nToneMapGranularity * (v + 1) + u][oldTone]; | ||
224 | unsigned int x2y2 = m_pToneMaps[m_nToneMapGranularity * (v + 1) + u + 1][oldTone]; | 227 | unsigned int x2y2 = m_pToneMaps[m_nToneMapGranularity * (v + 1) + u + 1][oldTone]; | ||
225 | int hFac = x - (u * (pImage->width() - 1) / (nGranularity - 1)); | 228 | int hFac = x - (u * (pImage->width() - 1) / (nGranularity - 1)); | ||
226 | if(hFac > m_areaWid) | 229 | if(hFac > m_areaWid) | ||
227 | hFac = m_areaWid; | 230 | hFac = m_areaWid; | ||
228 | unsigned int y1 = (x1y1 * (m_areaWid - hFac) + x2y1 * hFac) / m_areaWid; | 231 | unsigned int y1 = (x1y1 * (static_cast<unsigned int> (m_areaWid) - static_cast<unsigned int> (hFac)) | ||
229 | unsigned int y2 = (x1y2 * (m_areaWid - hFac) + x2y2 * hFac) / m_areaWid; | 232 | + x2y1 * static_cast<unsigned int> (hFac)) / static_cast<unsigned int> (m_areaWid); | ||
233 | | ||||
234 | unsigned int y2 = (x1y2 * (static_cast<unsigned int> (m_areaWid) - static_cast<unsigned int> (hFac)) | ||||
235 | + x2y2 * static_cast<unsigned int> (hFac)) / static_cast<unsigned int> (m_areaWid); | ||||
236 | | ||||
230 | int vFac = y - (v * (pImage->height() - 1) / (nGranularity - 1)); | 237 | int vFac = y - (v * (pImage->height() - 1) / (nGranularity - 1)); | ||
231 | if(vFac > m_areaHgt) | 238 | if(vFac > m_areaHgt) | ||
232 | vFac = m_areaHgt; | 239 | vFac = m_areaHgt; | ||
233 | return (y1 * (m_areaHgt - vFac) + y2 * vFac) / m_areaHgt; | 240 | return (y1 * (static_cast<unsigned int> (m_areaHgt) - static_cast<unsigned int> (vFac)) | ||
241 | + y2 * static_cast<unsigned int> (vFac)) / static_cast<unsigned int> (m_areaHgt); | ||||
234 | } | 242 | } | ||
235 | 243 | | |||
236 | //--------------------------------------------------------------------- | 244 | //--------------------------------------------------------------------- | ||
237 | 245 | | |||
238 | // public | 246 | // public | ||
239 | void kpEffectToneEnhanceApplier::BalanceImageTone(QImage* pImage, double granularity, double amount) | 247 | void kpEffectToneEnhanceApplier::BalanceImageTone(QImage* pImage, double granularity, double amount) | ||
240 | { | 248 | { | ||
241 | if(pImage->width() < MIN_IMAGE_DIM || pImage->height() < MIN_IMAGE_DIM) | 249 | if(pImage->width() < MIN_IMAGE_DIM || pImage->height() < MIN_IMAGE_DIM) | ||
242 | return; // the image is not big enough to perform this operation | 250 | return; // the image is not big enough to perform this operation | ||
243 | int nGranularity = (int)(granularity * (MAX_GRANULARITY - 2)) + 1; | 251 | int nGranularity = static_cast<int> (granularity * (MAX_GRANULARITY - 2)) + 1; | ||
244 | m_areaWid = pImage->width() / nGranularity; | 252 | m_areaWid = pImage->width() / nGranularity; | ||
245 | if(m_areaWid < MIN_IMAGE_DIM) | 253 | if(m_areaWid < MIN_IMAGE_DIM) | ||
246 | m_areaWid = MIN_IMAGE_DIM; | 254 | m_areaWid = MIN_IMAGE_DIM; | ||
247 | m_areaHgt = pImage->height() / nGranularity; | 255 | m_areaHgt = pImage->height() / nGranularity; | ||
248 | if(m_areaHgt < MIN_IMAGE_DIM) | 256 | if(m_areaHgt < MIN_IMAGE_DIM) | ||
249 | m_areaHgt = MIN_IMAGE_DIM; | 257 | m_areaHgt = MIN_IMAGE_DIM; | ||
250 | ComputeToneMaps(pImage, nGranularity); | 258 | ComputeToneMaps(pImage, nGranularity); | ||
251 | int x, y; | 259 | int x, y; | ||
Show All 11 Lines | |||||
263 | } | 271 | } | ||
264 | 272 | | |||
265 | //--------------------------------------------------------------------- | 273 | //--------------------------------------------------------------------- | ||
266 | 274 | | |||
267 | // public static | 275 | // public static | ||
268 | kpImage kpEffectToneEnhance::applyEffect (const kpImage &image, | 276 | kpImage kpEffectToneEnhance::applyEffect (const kpImage &image, | ||
269 | double granularity, double amount) | 277 | double granularity, double amount) | ||
270 | { | 278 | { | ||
271 | if (amount == 0) | 279 | if (amount == 0.0) | ||
272 | return image; | 280 | return image; | ||
273 | 281 | | |||
274 | QImage qimage(image); | 282 | QImage qimage(image); | ||
275 | 283 | | |||
276 | // OPT: Cache the calculated values? | 284 | // OPT: Cache the calculated values? | ||
277 | kpEffectToneEnhanceApplier applier; | 285 | kpEffectToneEnhanceApplier applier; | ||
278 | applier.BalanceImageTone (&qimage, granularity, amount); | 286 | applier.BalanceImageTone (&qimage, granularity, amount); | ||
279 | 287 | | |||
280 | return qimage; | 288 | return qimage; | ||
281 | } | 289 | } | ||
282 | 290 | | |||
283 | //--------------------------------------------------------------------- | 291 | //--------------------------------------------------------------------- |