diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc index aa1b90278..5f5e07139 100644 --- a/rtengine/demosaic_algos.cc +++ b/rtengine/demosaic_algos.cc @@ -21,6 +21,7 @@ #include "rawimagesource.h" #include "rawimagesource_i.h" +#include "jaggedarray.h" #include "median.h" #include "rawimage.h" #include "mytime.h" @@ -94,40 +95,12 @@ void RawImageSource::eahd_demosaic () // end of cielab preparation - float* rh[3]; - float* gh[4]; - float* bh[3]; - float* rv[3]; - float* gv[4]; - float* bv[3]; - float* lLh[3]; - float* lah[3]; - float* lbh[3]; - float* lLv[3]; - float* lav[3]; - float* lbv[3]; - float* homh[3]; - float* homv[3]; - - for (int i = 0; i < 4; i++) { - gh[i] = new float[W]; - gv[i] = new float[W]; - } - - for (int i = 0; i < 3; i++) { - rh[i] = new float[W]; - bh[i] = new float[W]; - rv[i] = new float[W]; - bv[i] = new float[W]; - lLh[i] = new float[W]; - lah[i] = new float[W]; - lbh[i] = new float[W]; - lLv[i] = new float[W]; - lav[i] = new float[W]; - lbv[i] = new float[W]; - homh[i] = new float[W]; - homv[i] = new float[W]; - } + const JaggedArray + rh (W, 3), gh (W, 4), bh (W, 3), + rv (W, 3), gv (W, 4), bv (W, 3), + lLh (W, 3), lah (W, 3), lbh (W, 3), + lLv (W, 3), lav (W, 3), lbv (W, 3), + homh (W, 3), homv (W, 3); // interpolate first two lines interpolate_row_g (gh[0], gv[0], 0); @@ -311,27 +284,9 @@ void RawImageSource::eahd_demosaic () } } - freeArray2(rh, 3); - freeArray2(gh, 4); - freeArray2(bh, 3); - freeArray2(rv, 3); - freeArray2(gv, 4); - freeArray2(bv, 3); - freeArray2(lLh, 3); - freeArray2(lah, 3); - freeArray2(lbh, 3); - freeArray2(homh, 3); - freeArray2(lLv, 3); - freeArray2(lav, 3); - freeArray2(lbv, 3); - freeArray2(homv, 3); - // Interpolate R and B for (int i = 0; i < H; i++) { - if (i == 0) - // rm, gm, bm must be recovered - //interpolate_row_rb_mul_pp (red, blue, NULL, green[i], green[i+1], i, rm, gm, bm, 0, W, 1); - { + if (i == 0) { interpolate_row_rb_mul_pp (red[i], blue[i], NULL, green[i], green[i + 1], i, 1.0, 1.0, 1.0, 0, W, 1); } else if (i == H - 1) { interpolate_row_rb_mul_pp (red[i], blue[i], green[i - 1], green[i], NULL, i, 1.0, 1.0, 1.0, 0, W, 1); @@ -545,7 +500,7 @@ void RawImageSource::hphd_demosaic () plistener->setProgress (0.0); } - float** hpmap = allocArray< float >(W, H, true); + const JaggedArray hpmap (W, H, true); #ifdef _OPENMP #pragma omp parallel @@ -590,17 +545,13 @@ void RawImageSource::hphd_demosaic () #endif hphd_green (hpmap); - freeArray(hpmap, H);//TODO: seems to cause sigabrt ??? why??? if (plistener) { plistener->setProgress (0.66); } for (int i = 0; i < H; i++) { - if (i == 0) - // rm, gm, bm must be recovered - //interpolate_row_rb_mul_pp (red, blue, NULL, green[i], green[i+1], i, rm, gm, bm, 0, W, 1); - { + if (i == 0) { interpolate_row_rb_mul_pp (red[i], blue[i], NULL, green[i], green[i + 1], i, 1.0, 1.0, 1.0, 0, W, 1); } else if (i == H - 1) { interpolate_row_rb_mul_pp (red[i], blue[i], green[i - 1], green[i], NULL, i, 1.0, 1.0, 1.0, 0, W, 1); diff --git a/rtengine/hlmultipliers.cc b/rtengine/hlmultipliers.cc index 8f7c5ef85..35e1d3e87 100644 --- a/rtengine/hlmultipliers.cc +++ b/rtengine/hlmultipliers.cc @@ -20,6 +20,7 @@ #include #include "rawimagesource.h" #include "rawimagesource_i.h" +#include "jaggedarray.h" #include "../rtgui/options.h" namespace rtengine @@ -321,7 +322,7 @@ void RawImageSource::updateHLRecoveryMap_ColorPropagation () int** rec[3]; for (int i = 0; i < 3; i++) { - rec[i] = allocArray (dw, dh); + rec[i] = allocJaggedArray (dw, dh); } float* reds[HR_SCALE]; @@ -333,10 +334,10 @@ void RawImageSource::updateHLRecoveryMap_ColorPropagation () } if (needhr) { - freeArray(needhr, H); + freeJaggedArray(needhr); } - needhr = allocArray (W, H); + needhr = allocJaggedArray (W, H); for (int i = 0; i < dh; i++) { for (int j = 0; j < HR_SCALE; j++) { @@ -413,14 +414,14 @@ void RawImageSource::updateHLRecoveryMap_ColorPropagation () hlmultipliers (rec, max_3, dh, dw); if (hrmap[0] != NULL) { - freeArray (hrmap[0], dh); - freeArray (hrmap[1], dh); - freeArray (hrmap[2], dh); + freeJaggedArray (hrmap[0]); + freeJaggedArray (hrmap[1]); + freeJaggedArray (hrmap[2]); } - hrmap[0] = allocArray (dw, dh); - hrmap[1] = allocArray (dw, dh); - hrmap[2] = allocArray (dw, dh); + hrmap[0] = allocJaggedArray (dw, dh); + hrmap[1] = allocJaggedArray (dw, dh); + hrmap[2] = allocJaggedArray (dw, dh); for (int i = 0; i < dh; i++) for (int j = 0; j < dw; j++) { @@ -431,9 +432,9 @@ void RawImageSource::updateHLRecoveryMap_ColorPropagation () delete ds; - freeArray (rec[0], dh); - freeArray (rec[1], dh); - freeArray (rec[2], dh); + freeJaggedArray (rec[0]); + freeJaggedArray (rec[1]); + freeJaggedArray (rec[2]); } } diff --git a/rtengine/jaggedarray.h b/rtengine/jaggedarray.h new file mode 100644 index 000000000..86d556c7f --- /dev/null +++ b/rtengine/jaggedarray.h @@ -0,0 +1,70 @@ +#ifndef JAGGEDARRAY_H +#define JAGGEDARRAY_H + +namespace rtengine +{ + +// These emulate a jagged array, but use only 2 allocations instead of 1 + W. + +template +inline T** const allocJaggedArray (const int W, const int H, const bool initZero = false) +{ + T** const a = new T*[H]; + a[0] = new T[H * W]; + + for (int i = 1; i < H; ++i) { + a[i] = a[i - 1] + W; + } + + if (initZero) { + std::memset(a[0], 0, sizeof(T) * W * H); + } + + return a; +} + +template +inline void freeJaggedArray (T** const a) +{ + delete [] a[0]; + delete [] a; +} + +template +class JaggedArray +{ +public: + JaggedArray (const int W, const int H, const bool initZero = false) + { + a = allocJaggedArray (W, H, initZero); + } + ~JaggedArray () + { + if (a) { + freeJaggedArray (a); + a = nullptr; + } + } + + JaggedArray (const JaggedArray&) = delete; + JaggedArray& operator= (const JaggedArray&) = delete; + +public: + operator T** const () const + { + return a; + } + +private: + T** a; + +}; + +// Declared but not defined to prevent +// explicitly freeing a JaggedArray implicitly cast to T**. +template +void freeJaggedArray (JaggedArray&); + +} // rtengine + +#endif // JAGGEDARRAY_H diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 0d8c9abd3..d1d4da54f 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -22,6 +22,7 @@ #include "rtengine.h" #include "rawimagesource.h" #include "rawimagesource_i.h" +#include "jaggedarray.h" #include "median.h" #include "rawimage.h" #include "mytime.h" @@ -480,15 +481,11 @@ RawImageSource::~RawImageSource () if (hrmap[0] != NULL) { int dh = H / HR_SCALE; - freeArray(hrmap[0], dh); - freeArray(hrmap[1], dh); - freeArray(hrmap[2], dh); + freeJaggedArray(hrmap[0]); + freeJaggedArray(hrmap[1]); + freeJaggedArray(hrmap[2]); } - //if (needhr) - // freeArray(needhr, H); - //if (hpmap) - // freeArray(hpmap, H); if (camProfile) { cmsCloseProfile (camProfile); } diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index a1bac4363..bef4ad4e2 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -31,37 +31,6 @@ namespace rtengine { -// these two functions "simulate" and jagged array, but just use two allocs -template T** allocArray (int W, int H, bool initZero = false) -{ - - T** t = new T*[H]; - t[0] = new T[H * W]; - - if (initZero) { - memset(t[0], 0, sizeof(T)*W * H); - } - - for (int i = 1; i < H; i++) { - t[i] = t[i - 1] + W; - } - - return t; -} - -template void freeArray (T** a, int H) -{ - - delete [] a[0]; - delete [] a; -} - - -template void freeArray2 (T** a, int H) -{ - delete [] a[0]; -} - class RawImageSource : public ImageSource { diff --git a/rtengine/shmap.cc b/rtengine/shmap.cc index 4f93c80d3..1783a6bc8 100644 --- a/rtengine/shmap.cc +++ b/rtengine/shmap.cc @@ -21,6 +21,7 @@ #include "rtengine.h" #include "rt_math.h" #include "rawimagesource.h" +#include "jaggedarray.h" #undef THREAD_PRIORITY_NORMAL #include "opthelper.h" @@ -114,7 +115,7 @@ void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int rangefn[lutSize - 1] = 1e-15f; // We need one temporary buffer - float ** buffer = allocArray (W, H); + const JaggedArray buffer (W, H); // the final result has to be in map // for an even number of levels that means: map => buffer, buffer => map @@ -157,23 +158,6 @@ void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int } dirpyr_shmap(dirpyrlo[indx], dirpyrlo[1 - indx], W, H, rangefn, level, scale ); - - freeArray(buffer, H); - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - /* - // anti-alias filtering the result - #ifdef _OPENMP - #pragma omp for - #endif - for (int i=0; i0 && j>0 && i (W, H); + const JaggedArray buffer (W, H); // the final result has to be in map // for an even number of levels that means: map => buffer, buffer => map @@ -306,23 +290,6 @@ void SHMap::updateL (float** L, double radius, bool hq, int skip) } dirpyr_shmap(dirpyrlo[indx], dirpyrlo[1 - indx], W, H, rangefn, level, scale ); - - freeArray(buffer, H); - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - /* - // anti-alias filtering the result - #ifdef _OPENMP - #pragma omp for - #endif - for (int i=0; i0 && j>0 && i