diff --git a/rtengine/wavelet.h b/rtengine/wavelet.h deleted file mode 100644 index f655d83ec..000000000 --- a/rtengine/wavelet.h +++ /dev/null @@ -1,312 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - * - * 2010 Ilya Popov - */ - - -#ifndef WAVELET_H_INCLUDED -#define WAVELET_H_INCLUDED - -///////////////////////////////////////////////////////////////////////////// -// Haar wavelets // -///////////////////////////////////////////////////////////////////////////// - -// Bad, strong block effect - -template -void dwt_haar(T * data, size_t pitch, T * buffer, size_t n) -{ - size_t n2a = (n + 1) / 2; - size_t n2 = n/2; - - for(size_t i = 0, j = 0; i < n2; i++, j += 2 * pitch) - { - T a = data[j]; - T b = data[j + pitch]; - buffer[i] = (a + b) / 2; - buffer[n2a + i] = (a - b); - } - - if(n2 < n2a) - { - buffer[n2] = data[pitch * (n-1)]; - } - - for(size_t k = 0, q = 0; k < n; k++, q += pitch) - { - data[q] = buffer[k]; - } -} - -template -void idwt_haar(T * data, size_t pitch, T * buffer, size_t n, int alpha) -{ - size_t n2a = (n + 1) / 2; - size_t n2 = n/2; - - for(size_t i = 0, j = 0; i < n2; i++, j += 2) - { - T p = data[i * pitch]; - T q = (alpha * data[(n2a + i)*pitch]) / 1024; - buffer[j] = p + q / 2; - buffer[j + 1] = p - q / 2; - } - - if(n2 < n2a) - { - buffer[n-1] = data[pitch * n2]; - } - - for(size_t k = 0, q = 0; k < n; k++, q += pitch) - { - data[q] = buffer[k]; - } -} - -///////////////////////////////////////////////////////////////////////////// -// CDF 5/3 wavelets // -///////////////////////////////////////////////////////////////////////////// - - -// buffer must be of length (n + 4) -template -void dwt_53(T * data, size_t pitch, T * buffer, size_t n) -{ - size_t n2 = n/2; - size_t n2a = (n + 1) / 2; - T * tmp = buffer + 2; - - // copy data - - for(size_t i = 0, j = 0; i < n; i++, j += pitch) - { - tmp[i] = data[j]; - } - - // extend mirror-like - - tmp[-1] = tmp[1]; - tmp[-2] = tmp[2]; - - tmp[n] = tmp[n-2]; - tmp[n+1] = tmp[n-3]; - - // calculate coefficients - - for(ptrdiff_t i = -1; i < (ptrdiff_t)n + 1; i += 2) - { - tmp[i] = tmp[i] - (tmp[i-1] + tmp[i+1]) / 2; - } - - for(ptrdiff_t i = 0; i < (ptrdiff_t)n; i += 2) - { - tmp[i] = tmp[i] + (tmp[i-1] + tmp[i+1] + 2) / 4; - } - - // copy with reordering - - for(size_t i = 0, j = 0; i < n; i+=2, j += pitch) - { - data[j] = tmp[i]; - } - - for(size_t i = 1, j = n2a*pitch; i < n; i+=2, j += pitch) - { - data[j] = tmp[i]; - } -} - -template -void idwt_53(T * data, size_t pitch, T * buffer, size_t n, int alpha) -{ - size_t n2 = n/2; - size_t n2a = (n + 1) / 2; - T * tmp = buffer + 2; - - // copy with reordering - - for(size_t i = 0, j = 0; i < n; i+=2, j += pitch) - { - tmp[i] = data[j]; - } - - for(size_t i = 1, j = n2a*pitch; i < n; i+=2, j += pitch) - { - tmp[i] = (alpha * data[j]) / 1024; - } - - // extend mirror-like - - tmp[-1] = tmp[1]; - tmp[-2] = tmp[2]; - - tmp[n] = tmp[n-2]; - tmp[n+1] = tmp[n-3]; - - // calculate coefficients - - for(ptrdiff_t i = 0; i < (ptrdiff_t)n + 1; i += 2) - { - tmp[i] = tmp[i] - (tmp[i-1] + tmp[i+1] + 2) / 4; - } - - for(ptrdiff_t i = 1; i < (ptrdiff_t)n; i += 2) - { - tmp[i] = tmp[i] + (tmp[i-1] + tmp[i+1]) / 2; - } - - // copy data - - for(size_t i = 0, j = 0; i < n; i++, j += pitch) - { - data[j] = tmp[i]; - } -} - -///////////////////////////////////////////////////////////////////////////// -// Edge-avoiding wavelets // -///////////////////////////////////////////////////////////////////////////// -// based on -// Edge-Avoiding Wavelets and their Applications -// Raanan Fattal , -// Hebrew University of Jerusalem, Israel -// -// WCDF variant from this paper is used here -// T must be one of floating-point types -///////////////////////////////////////////////////////////////////////////// - -template -inline T wcdf_weight(T a, T b) -{ - static const T eps = 1; - static const T one = 1.0; - return one / (fabs(a - b) + eps); -} - -// buffer is a temporary storage -// buffer2 must be preserved between dwt and idwt - -template -void dwt_wcdf(T * data, size_t pitch, T * buffer, size_t n, T * buffer2) -{ - size_t n2 = n/2; - size_t n2a = (n + 1) / 2; - T * tmp = buffer + 2; - T * w = buffer2 + 2; - - // copy data - - for(size_t i = 0, j = 0; i < n; i++, j += pitch) - { - tmp[i] = data[j]; - } - - // extend mirror-like - - tmp[-1] = tmp[1]; - tmp[-2] = tmp[2]; - - tmp[n] = tmp[n-2]; - tmp[n+1] = tmp[n-3]; - - // calculate weights - - for(ptrdiff_t i = 0; i < (ptrdiff_t)n - 1; i++) - { - w[i] = wcdf_weight(tmp[i], tmp[i+1]); - //w[i] = 1; - } - - w[-1] = w[-2] = (T)0.0; - w[n-1] = w[n] = w[n + 1] = (T)0.0; - - // calculate coefficients - - for(ptrdiff_t i = 1; i < (ptrdiff_t)n; i += 2) - { - tmp[i] = tmp[i] - (w[i-1]*tmp[i-1] + w[i]*tmp[i+1]) / (w[i-1] + w[i]); - } - - for(ptrdiff_t i = 0; i < (ptrdiff_t)n; i += 2) - { - tmp[i] = tmp[i] + (T)0.5 * (w[i-1]*tmp[i-1] + w[i]*tmp[i+1]) / (w[i-1] + w[i]); - } - - // copy with reordering - - for(size_t i = 0, j = 0; i < n; i+=2, j += pitch) - { - data[j] = tmp[i]; - } - - for(size_t i = 1, j = n2a*pitch; i < n; i+=2, j += pitch) - { - data[j] = tmp[i]; - } -} - -template -void idwt_wcdf(T * data, size_t pitch, T * buffer, size_t n, int alpha, T * buffer2) -{ - size_t n2 = n/2; - size_t n2a = (n + 1) / 2; - T * tmp = buffer + 2; - T * w = buffer2 + 2; - - // copy with reordering - - for(size_t i = 0, j = 0; i < n; i+=2, j += pitch) - { - tmp[i] = data[j]; - } - - for(size_t i = 1, j = n2a*pitch; i < n; i+=2, j += pitch) - { - tmp[i] = (alpha * data[j]) / 1024; - } - - // extend mirror-like - - tmp[-1] = tmp[1]; - tmp[-2] = tmp[2]; - - tmp[n] = tmp[n-2]; - tmp[n+1] = tmp[n-3]; - - // calculate coefficients - - for(ptrdiff_t i = 0; i < (ptrdiff_t)n; i += 2) - { - tmp[i] = tmp[i] - (T)0.5 * (w[i-1]*tmp[i-1] + w[i]*tmp[i+1]) / (w[i-1] + w[i]); - } - - for(ptrdiff_t i = 1; i < (ptrdiff_t)n; i += 2) - { - tmp[i] = tmp[i] + (w[i-1]*tmp[i-1] + w[i]*tmp[i+1]) / (w[i-1] + w[i]); - } - - // copy data - - for(size_t i = 0, j = 0; i < n; i++, j += pitch) - { - data[j] = tmp[i]; - } -} - -////////////////////////////////////////////////////////////////////////////// - -#endif diff --git a/rtengine/wavelet_dec.cc b/rtengine/wavelet_dec.cc deleted file mode 100644 index 5ab9e272a..000000000 --- a/rtengine/wavelet_dec.cc +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - * - * 2010 Ilya Popov - */ - -#include "wavelet_dec.h" - -namespace rtengine -{ - -wavelet_decomposition::~wavelet_decomposition() -{ - for(int i = 0; i < nlevels; i++) - { - delete m_c[i]; - } -} - -}; - diff --git a/rtengine/wavelet_dec.h b/rtengine/wavelet_dec.h deleted file mode 100644 index 6beacf0eb..000000000 --- a/rtengine/wavelet_dec.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - * - * 2010 Ilya Popov - */ - -#ifndef WAVELET_DEC_H_INCLUDED -#define WAVELET_DEC_H_INCLUDED - -#include - -#include "wavelet_level.h" - -namespace rtengine { - -class wavelet_decomposition -{ -public: - - typedef float internal_type; - -private: - - static const int maxlevels = 8; - - int nlevels; - size_t m_w, m_h; - size_t m_w1, m_h1; - - wavelet_level * m_c[maxlevels]; - -public: - - template - wavelet_decomposition(E ** src, size_t w, size_t h); - - ~wavelet_decomposition(); - - template - void reconstruct(E ** dst, const int * c, L & limiter); -}; - -////////////////////////////////////////////////////////////////////////////// - -template -wavelet_decomposition::wavelet_decomposition(E ** src, size_t w, size_t h) -: nlevels(0), m_w(w), m_h(h), m_w1(0), m_h1(0) -{ - m_w1 = w; - m_h1 = h; - - m_c[0] = new wavelet_level(src, m_w1, m_h1); - nlevels = 1; - - while(nlevels < maxlevels) - { - m_c[nlevels] = new wavelet_level(m_c[nlevels - 1]->lowfreq(), m_c[nlevels-1]->lfw(), m_c[nlevels-1]->lfh()); - nlevels ++; - } -} - - -template -void wavelet_decomposition::reconstruct(E ** dst, const int * c, L & l) -{ - noop n; - - for(int level = nlevels - 1; level > 0; level--) - { - int alpha = 1024 + 10 * c[level]; - m_c[level]->reconstruct(m_c[level-1]->lowfreq(), alpha, n); - } - - int alpha = 1024 + 10 * c[0]; - m_c[0]->reconstruct(dst, alpha, l); -} - - -}; - -#endif diff --git a/rtengine/wavelet_level.h b/rtengine/wavelet_level.h deleted file mode 100644 index 832b73143..000000000 --- a/rtengine/wavelet_level.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - * - * 2010 Ilya Popov - */ - -#ifndef WAVELET_LEVEL_H_INCLUDED -#define WAVELET_LEVEL_H_INCLUDED - -#include -#include - -#include "wavelet.h" - -namespace rtengine -{ - -template -class limiter -{ - T min_value, max_value; -public: - limiter(T min, T max) - : min_value(min), max_value(max) - {} - - T operator()(T x) - { - if(x < min_value) - return min_value; - if(x > max_value) - return max_value; - return x; - } -}; - -template -class noop -{ -public: - T operator()(T x) - { - return x; - } -}; - -template -inline T clip(T x, T min_value, T max_value) -{ - if(x < min_value) - return min_value; - if(x > max_value) - return max_value; - return x; -} - -template -void plane_copy(A ** a, B ** b, size_t w, size_t h, L & l) -{ - for(size_t j = 0; j < h; j++) - for(size_t i = 0; i < w; i++) - b[j][i] = static_cast(l(a[j][i])); -} - -////////////////////////////////////////////////////////////////////////////// - -template -class wavelet_level -{ - // full size - size_t m_w, m_h; - - // size of low frequency part - size_t m_w2, m_h2; - - // array of pointers to lines of coeffs - // actually is a single contiguous data array pointed by m_coeffs[0] - T ** m_coeffs; - - // weights storage - T ** m_weights_rows; - T ** m_weights_cols; - - // allocation and destruction of data storage - T ** create(size_t w, size_t h); - void destroy(T ** p); - - void dwt_2d(size_t w, size_t h); - void idwt_2d(size_t w, size_t h, int alpha); - -public: - - template - wavelet_level(E ** src, size_t w, size_t h) - : m_w(w), m_h(h), m_w2((w+1)/2), m_h2((h+1)/2), - m_coeffs(NULL), m_weights_rows(NULL), m_weights_cols(NULL) - { - m_coeffs = create(w, h); - m_weights_rows = create(w + 4, h); - m_weights_cols = create(h + 4, w); - - decompose(src); - } - - ~wavelet_level() - { - destroy(m_coeffs); - destroy(m_weights_rows); - destroy(m_weights_cols); - } - - T ** lowfreq() const - { - return m_coeffs; - } - - size_t lfw() const - { - return m_w2; - } - - size_t lfh() const - { - return m_h2; - } - - template - void decompose(E ** src); - - template - void reconstruct(E ** dst, int alpha, L & limiter); -}; - -////////////////////////////////////////////////////////////////////////////// - -template -void wavelet_level::dwt_2d(size_t w, size_t h) -{ - T * buffer = new T[std::max(w, h) + 4]; - - for(size_t j = 0; j < h; j++) - { - //dwt_haar(m_coeffs[j], 1, buffer, w); - //dwt_53(m_coeffs[j], 1, buffer, w); - dwt_wcdf(m_coeffs[j], 1, buffer, w, m_weights_rows[j]); - } - - for(size_t i = 0; i < w; i++) - { - //dwt_haar(&m_coeffs[0][i], m_pitch, buffer, h); - //dwt_53(&m_coeffs[0][i], w, buffer, h); - dwt_wcdf(&m_coeffs[0][i], w, buffer, h, m_weights_cols[i]); - } - - delete[] buffer; -} - -template -void wavelet_level::idwt_2d(size_t w, size_t h, int alpha) -{ - T * buffer = new T[std::max(w, h) + 4]; - - for(size_t i = 0; i < w; i++) - { - //idwt_haar(&m_coeffs[0][i], m_pitch, buffer, h, alpha); - //idwt_53(&m_coeffs[0][i], w, buffer, h, alpha); - idwt_wcdf(&m_coeffs[0][i], w, buffer, h, alpha, m_weights_cols[i]); - //idwt_noop(&m_coeffs[0][i], w, buffer, h, alpha); - } - - for(size_t j = 0; j < h; j++) - { - //idwt_haar(m_coeffs[j], 1, buffer, w, alpha); - //idwt_53(m_coeffs[j], 1, buffer, w, alpha); - idwt_wcdf(m_coeffs[j], 1, buffer, w, alpha, m_weights_rows[j]); - //idwt_noop(m_coeffs[j], 1, buffer, w, alpha); - } - - delete[] buffer; -} - -template -T ** wavelet_level::create(size_t w, size_t h) -{ - T * data = new T[w * h]; - T ** p = new T*[h]; - for(size_t j = 0; j < h; j++) - { - p[j] = data + w * j; - } - return p; -} - -template -void wavelet_level::destroy(T ** p) -{ - if(p) - { - delete[] p[0]; - - delete[] p; - } -} - -template template -void wavelet_level::decompose(E ** src) -{ - noop l; - - plane_copy(src, m_coeffs, m_w, m_h, l); - - dwt_2d(m_w, m_h); -} - -template template -void wavelet_level::reconstruct(E ** dst, int alpha, L & l) -{ - idwt_2d(m_w, m_h, alpha); - - plane_copy(m_coeffs, dst, m_w, m_h, l); -} - -}; - -#endif