"Fossies" - the Fresh Open Source Software Archive

Member "rawtherapee-5.7/rtengine/cplx_wavelet_dec.h" (10 Sep 2019, 8134 Bytes) of package /linux/misc/rawtherapee-5.7.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "cplx_wavelet_dec.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.6_vs_5.7.

    1 /*
    2  *  This file is part of RawTherapee.
    3  *
    4  *  RawTherapee is free software: you can redistribute it and/or modify
    5  *  it under the terms of the GNU General Public License as published by
    6  *  the Free Software Foundation, either version 3 of the License, or
    7  *  (at your option) any later version.
    8  *
    9  *  RawTherapee is distributed in the hope that it will be useful,
   10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  *  GNU General Public License for more details.
   13  *
   14  *  You should have received a copy of the GNU General Public License
   15  *  along with RawTherapee.  If not, see <https://www.gnu.org/licenses/>.
   16  *
   17  *  2010 Ilya Popov <ilia_popov@rambler.ru>
   18  *  2012 Emil Martinec <ejmartin@uchicago.edu>
   19  */
   20 
   21 #ifndef CPLX_WAVELET_DEC_H_INCLUDED
   22 #define CPLX_WAVELET_DEC_H_INCLUDED
   23 
   24 #include <cstddef>
   25 #include <cmath>
   26 
   27 #include "cplx_wavelet_level.h"
   28 #include "cplx_wavelet_filter_coeffs.h"
   29 #include "noncopyable.h"
   30 
   31 namespace rtengine
   32 {
   33 
   34 class wavelet_decomposition :
   35     public NonCopyable
   36 {
   37 public:
   38 
   39     typedef float internal_type;
   40     float *coeff0;
   41     bool memoryAllocationFailed;
   42 
   43 private:
   44 
   45     static const int maxlevels = 10;//should be greater than any conceivable order of decimation
   46 
   47     int lvltot, subsamp;
   48     int m_w, m_h;//dimensions
   49 
   50     int wavfilt_len, wavfilt_offset;
   51     float *wavfilt_anal;
   52     float *wavfilt_synth;
   53 
   54 
   55     wavelet_level<internal_type> * wavelet_decomp[maxlevels];
   56 
   57 public:
   58 
   59     template<typename E>
   60     wavelet_decomposition(E * src, int width, int height, int maxlvl, int subsampling, int skipcrop = 1, int numThreads = 1, int Daub4Len = 6);
   61 
   62     ~wavelet_decomposition();
   63 
   64     internal_type ** level_coeffs(int level) const
   65     {
   66         return wavelet_decomp[level]->subbands();
   67     }
   68 
   69     int level_W(int level) const
   70     {
   71         return wavelet_decomp[level]->width();
   72     }
   73 
   74     int level_H(int level) const
   75     {
   76         return wavelet_decomp[level]->height();
   77     }
   78 
   79     int level_stride(int level) const
   80     {
   81         return wavelet_decomp[level]->stride();
   82     }
   83 
   84     int maxlevel() const
   85     {
   86         return lvltot + 1;
   87     }
   88 
   89     int subsample() const
   90     {
   91         return subsamp;
   92     }
   93     template<typename E>
   94     void reconstruct(E * dst, const float blend = 1.f);
   95 };
   96 
   97 template<typename E>
   98 wavelet_decomposition::wavelet_decomposition(E * src, int width, int height, int maxlvl, int subsampling, int skipcrop, int numThreads, int Daub4Len)
   99     : coeff0(nullptr), memoryAllocationFailed(false), lvltot(0), subsamp(subsampling), m_w(width), m_h(height)
  100 {
  101 
  102     //initialize wavelet filters
  103     wavfilt_len = Daub4Len;
  104     wavfilt_offset = Daub4_offset;
  105     wavfilt_anal = new float[2 * wavfilt_len];
  106     wavfilt_synth = new float[2 * wavfilt_len];
  107 
  108     if(wavfilt_len == 6) {
  109         for (int n = 0; n < 2; n++) {
  110             for (int i = 0; i < wavfilt_len; i++) {
  111                 wavfilt_anal[wavfilt_len * (n) + i]  = Daub4_anal[n][i];
  112                 wavfilt_synth[wavfilt_len * (n) + i] = Daub4_anal[n][wavfilt_len - 1 - i];
  113                 //n=0 lopass, n=1 hipass
  114             }
  115         }
  116     } else if(wavfilt_len == 8) {
  117         for (int n = 0; n < 2; n++) {
  118             for (int i = 0; i < wavfilt_len; i++) {
  119                 wavfilt_anal[wavfilt_len * (n) + i]  = Daub4_anal8[n][i];
  120                 wavfilt_synth[wavfilt_len * (n) + i] = Daub4_anal8[n][wavfilt_len - 1 - i];
  121                 //n=0 lopass, n=1 hipass
  122             }
  123         }
  124     } else if(wavfilt_len == 12) {
  125         for (int n = 0; n < 2; n++) {
  126             for (int i = 0; i < wavfilt_len; i++) {
  127                 wavfilt_anal[wavfilt_len * (n) + i]  = Daub4_anal12[n][i];
  128                 wavfilt_synth[wavfilt_len * (n) + i] = Daub4_anal12[n][wavfilt_len - 1 - i];
  129                 //n=0 lopass, n=1 hipass
  130             }
  131         }
  132     } else if(wavfilt_len == 16) {
  133         for (int n = 0; n < 2; n++) {
  134             for (int i = 0; i < wavfilt_len; i++) {
  135                 wavfilt_anal[wavfilt_len * (n) + i]  = Daub4_anal16[n][i];
  136                 wavfilt_synth[wavfilt_len * (n) + i] = Daub4_anal16[n][wavfilt_len - 1 - i];
  137                 //n=0 lopass, n=1 hipass
  138             }
  139         }
  140     } else if(wavfilt_len == 4) {
  141         for (int n = 0; n < 2; n++) {
  142             for (int i = 0; i < wavfilt_len; i++) {
  143                 wavfilt_anal[wavfilt_len * (n) + i]  = Daub4_anal0[n][i];
  144                 wavfilt_synth[wavfilt_len * (n) + i] = Daub4_anal0[n][wavfilt_len - 1 - i];
  145                 //n=0 lopass, n=1 hipass
  146             }
  147         }
  148     }
  149 
  150     // after coefficient rotation, data structure is:
  151     // wavelet_decomp[scale][channel={lo,hi1,hi2,hi3}][pixel_array]
  152 
  153     lvltot = 0;
  154     E *buffer[2];
  155     buffer[0] = new (std::nothrow) E[(m_w / 2 + 1) * (m_h / 2 + 1)];
  156 
  157     if(buffer[0] == nullptr) {
  158         memoryAllocationFailed = true;
  159         return;
  160     }
  161 
  162     buffer[1] = new (std::nothrow) E[(m_w / 2 + 1) * (m_h / 2 + 1)];
  163 
  164     if(buffer[1] == nullptr) {
  165         memoryAllocationFailed = true;
  166         delete[] buffer[0];
  167         buffer[0] = nullptr;
  168         return;
  169     }
  170 
  171     int bufferindex = 0;
  172 
  173     wavelet_decomp[lvltot] = new wavelet_level<internal_type>(src, buffer[bufferindex ^ 1], lvltot/*level*/, subsamp, m_w, m_h, \
  174             wavfilt_anal, wavfilt_anal, wavfilt_len, wavfilt_offset, skipcrop, numThreads);
  175 
  176     if(wavelet_decomp[lvltot]->memoryAllocationFailed) {
  177         memoryAllocationFailed = true;
  178     }
  179 
  180     while(lvltot < maxlvl - 1) {
  181         lvltot++;
  182         bufferindex ^= 1;
  183         wavelet_decomp[lvltot] = new wavelet_level<internal_type>(buffer[bufferindex], buffer[bufferindex ^ 1]/*lopass*/, lvltot/*level*/, subsamp, \
  184                 wavelet_decomp[lvltot - 1]->width(), wavelet_decomp[lvltot - 1]->height(), \
  185                 wavfilt_anal, wavfilt_anal, wavfilt_len, wavfilt_offset, skipcrop, numThreads);
  186 
  187         if(wavelet_decomp[lvltot]->memoryAllocationFailed) {
  188             memoryAllocationFailed = true;
  189         }
  190     }
  191 
  192     coeff0 = buffer[bufferindex ^ 1];
  193     delete[] buffer[bufferindex];
  194 }
  195 
  196 template<typename E>
  197 void wavelet_decomposition::reconstruct(E * dst, const float blend)
  198 {
  199 
  200     if(memoryAllocationFailed) {
  201         return;
  202     }
  203 
  204     // data structure is wavcoeffs[scale][channel={lo,hi1,hi2,hi3}][pixel_array]
  205 
  206     if(lvltot >= 1) {
  207         int width = wavelet_decomp[1]->m_w;
  208         int height = wavelet_decomp[1]->m_h;
  209 
  210         E *tmpHi = new (std::nothrow) E[width * height];
  211 
  212         if(tmpHi == nullptr) {
  213             memoryAllocationFailed = true;
  214             return;
  215         }
  216 
  217         for (int lvl = lvltot; lvl > 0; lvl--) {
  218             E *tmpLo = wavelet_decomp[lvl]->wavcoeffs[2]; // we can use this as buffer
  219             wavelet_decomp[lvl]->reconstruct_level(tmpLo, tmpHi, coeff0, coeff0, wavfilt_synth, wavfilt_synth, wavfilt_len, wavfilt_offset);
  220             delete wavelet_decomp[lvl];
  221             wavelet_decomp[lvl] = nullptr;
  222         }
  223 
  224         delete[] tmpHi;
  225     }
  226 
  227     int width = wavelet_decomp[0]->m_w;
  228     int height = wavelet_decomp[0]->m_h2;
  229     E *tmpLo;
  230 
  231     if(wavelet_decomp[0]->bigBlockOfMemoryUsed()) { // bigBlockOfMemoryUsed means that wavcoeffs[2] points to a block of memory big enough to hold the data
  232         tmpLo = wavelet_decomp[0]->wavcoeffs[2];
  233     } else {                                      // allocate new block of memory
  234         tmpLo = new (std::nothrow) E[width * height];
  235 
  236         if(tmpLo == nullptr) {
  237             memoryAllocationFailed = true;
  238             return;
  239         }
  240     }
  241 
  242     E *tmpHi = new (std::nothrow) E[width * height];
  243 
  244     if(tmpHi == nullptr) {
  245         memoryAllocationFailed = true;
  246 
  247         if(!wavelet_decomp[0]->bigBlockOfMemoryUsed()) {
  248             delete[] tmpLo;
  249         }
  250 
  251         return;
  252     }
  253 
  254 
  255     wavelet_decomp[0]->reconstruct_level(tmpLo, tmpHi, coeff0, dst, wavfilt_synth, wavfilt_synth, wavfilt_len, wavfilt_offset, blend);
  256 
  257     if(!wavelet_decomp[0]->bigBlockOfMemoryUsed()) {
  258         delete[] tmpLo;
  259     }
  260 
  261     delete[] tmpHi;
  262     delete wavelet_decomp[0];
  263     wavelet_decomp[0] = nullptr;
  264     delete[] coeff0;
  265     coeff0 = nullptr;
  266 }
  267 
  268 }
  269 
  270 #endif