diff --git a/rtengine/array2D.h b/rtengine/array2D.h index 4b301383b..8d1351cbb 100644 --- a/rtengine/array2D.h +++ b/rtengine/array2D.h @@ -27,7 +27,7 @@ * * creates an array which is valid within the normal C/C++ scope "{ ... }" * - * access to elements is a simple as: + * access to elements is as simple as: * * array2D my_array (10,10); // creates 10x10 array of floats * value = my_array[3][5]; @@ -48,25 +48,18 @@ * array2D my_array ; // empty container. * my_array(10,10) ; // resize to 10x10 array * my_array(10,10,ARRAY2D_CLEAR_DATA) ; // resize to 10x10 and clear data - * my_array(10,10,ARRAY2D_CLEAR_DATA|ARRAY2D_LOCK_DATA) ; same but set a lock on changes * - * !! locked arrays cannot be resized and cannot be unlocked again !! */ #pragma once -#include // for raise() #include +#include +#include "noncopyable.h" // flags for use -#define ARRAY2D_LOCK_DATA 1 -#define ARRAY2D_CLEAR_DATA 2 -#define ARRAY2D_BYREFERENCE 4 -#define ARRAY2D_VERBOSE 8 +constexpr unsigned int ARRAY2D_CLEAR_DATA = 1; +constexpr unsigned int ARRAY2D_BYREFERENCE = 2; -#include -#include - -#include "noncopyable.h" template class array2D : @@ -74,99 +67,80 @@ class array2D : { private: - int x, y, owner; - unsigned int flags; - T ** ptr; - T * data; - bool lock; // useful lock to ensure data is not changed anymore. - void ar_realloc(int w, int h, int offset = 0) + ssize_t width, height; + T** rows; + T* data; + void ar_realloc(ssize_t w, ssize_t h, int offset = 0) { - if ((ptr) && ((h > y) || (4 * h < y))) { - delete[] ptr; - ptr = nullptr; + if (rows && (h > height || 4 * h < height)) { + delete[] rows; + rows = nullptr; + } + if (!rows) { + rows = new T*[h]; } - if ((data) && (((h * w) > (x * y)) || ((h * w) < ((x * y) / 4)))) { + if (data && ((h * w > width * height) || (h * w < (width * height / 4)))) { delete[] data; data = nullptr; } - if (ptr == nullptr) { - ptr = new T*[h]; + width = w; + height = h; + + if (!data) { + data = new T[height * width + offset]; } - if (data == nullptr) { - data = new T[h * w + offset]; + for (ssize_t i = 0; i < height; i++) { + rows[i] = data + offset + width * i; } - - x = w; - y = h; - - for (int i = 0; i < h; i++) { - ptr[i] = data + offset + w * i; - } - - owner = 1; } public: // use as empty declaration, resize before use! // very useful as a member object array2D() : - x(0), y(0), owner(0), flags(0), ptr(nullptr), data(nullptr), lock(false) - { - //printf("got empty array2D init\n"); - } + width(0), height(0), rows(nullptr), data(nullptr) + { } // creator type1 - array2D(int w, int h, unsigned int flgs = 0) + array2D(int w, int h, unsigned int flags = 0) : + width(w), height(h) { - flags = flgs; - lock = flags & ARRAY2D_LOCK_DATA; - data = new T[h * w]; - owner = 1; - x = w; - y = h; - ptr = new T*[h]; + data = new T[height * width]; + rows = new T*[height]; - for (int i = 0; i < h; i++) { - ptr[i] = data + i * w; + for (ssize_t i = 0; i < height; ++i) { + rows[i] = data + i * width; } if (flags & ARRAY2D_CLEAR_DATA) { - memset(data, 0, w * h * sizeof(T)); + memset(data, 0, width * height * sizeof(T)); } } // creator type 2 - array2D(int w, int h, T ** source, unsigned int flgs = 0) + array2D(int w, int h, T ** source, unsigned int flags = 0) : + width(w), height(h) { - flags = flgs; - //if (lock) { printf("array2D attempt to overwrite data\n");raise(SIGSEGV);} - lock = flags & ARRAY2D_LOCK_DATA; - // when by reference - // TODO: improve this code with ar_realloc() - owner = (flags & ARRAY2D_BYREFERENCE) ? 0 : 1; - + const bool owner = !(flags & ARRAY2D_BYREFERENCE); if (owner) { - data = new T[h * w]; + data = new T[height * width]; } else { data = nullptr; } - x = w; - y = h; - ptr = new T*[h]; + rows = new T*[height]; - for (int i = 0; i < h; i++) { + for (ssize_t i = 0; i < height; ++i) { if (owner) { - ptr[i] = data + i * w; - - for (int j = 0; j < w; j++) { - ptr[i][j] = source[i][j]; + rows[i] = data + i * width; + for (ssize_t j = 0; j < width; ++j) { + rows[i][j] = source[i][j]; } } else { - ptr[i] = source[i]; + rows[i] = source[i]; } } } @@ -174,18 +148,8 @@ public: // destructor ~array2D() { - - if (flags & ARRAY2D_VERBOSE) { - printf(" deleting array2D size %dx%d \n", x, y); - } - - if ((owner) && (data)) { - delete[] data; - } - - if (ptr) { - delete[] ptr; - } + delete[] data; + delete[] rows; } void fill(const T val, bool multiThread = false) @@ -193,41 +157,43 @@ public: #ifdef _OPENMP #pragma omp parallel for if(multiThread) #endif - for (int i = 0; i < x * y; ++i) { + for (ssize_t i = 0; i < width * height; ++i) { data[i] = val; } } void free() { - if ((owner) && (data)) { - delete[] data; - data = nullptr; - } + delete[] data; + data = nullptr; - if (ptr) { - delete [] ptr; - ptr = nullptr; - } + delete [] rows; + rows = nullptr; } // use with indices T * operator[](int index) { - assert((index >= 0) && (index < y)); - return ptr[index]; + assert((index >= 0) && (index < height)); + return rows[index]; + } + + const T * operator[](int index) const + { + assert((index >= 0) && (index < height)); + return rows[index]; } // use as pointer to T** operator T**() { - return ptr; + return rows; } // use as pointer to T** operator const T* const *() const { - return ptr; + return rows; } // use as pointer to data @@ -237,86 +203,53 @@ public: return data; } + operator const T*() const + { + // only if owner this will return a valid pointer + return data; + } + // useful within init of parent object // or use as resize of 2D array - void operator()(int w, int h, unsigned int flgs = 0, int offset = 0) + void operator()(int w, int h, unsigned int flags = 0, int offset = 0) { - flags = flgs; - - if (flags & ARRAY2D_VERBOSE) { - printf("got init request %dx%d flags=%u\n", w, h, flags); - printf("previous was data %p ptr %p \n", data, ptr); - } - - if (lock) { // our object was locked so don't allow a change. - printf("got init request but object was locked!\n"); - raise( SIGSEGV); - } - - lock = flags & ARRAY2D_LOCK_DATA; - ar_realloc(w, h, offset); if (flags & ARRAY2D_CLEAR_DATA) { - memset(data + offset, 0, static_cast(w) * h * sizeof(T)); + memset(data + offset, 0, width * height * sizeof(T)); } } - // import from flat data - void operator()(int w, int h, T* copy, unsigned int flgs = 0) + int getWidth() const { - flags = flgs; - - if (flags & ARRAY2D_VERBOSE) { - printf("got init request %dx%d flags=%u\n", w, h, flags); - printf("previous was data %p ptr %p \n", data, ptr); - } - - if (lock) { // our object was locked so don't allow a change. - printf("got init request but object was locked!\n"); - raise( SIGSEGV); - } - - lock = flags & ARRAY2D_LOCK_DATA; - - ar_realloc(w, h); - memcpy(data, copy, w * h * sizeof(T)); + return width; } - int width() const + int getHeight() const { - return x; - } - int height() const - { - return y; + return height; } operator bool() { - return (x > 0 && y > 0); + return (width > 0 && height > 0); } }; template -class multi_array2D +class multi_array2D : public rtengine::NonCopyable { private: array2D list[num]; public: - multi_array2D(int x, int y, int flags = 0, int offset = 0) + multi_array2D(int width, int height, int flags = 0, int offset = 0) { - for (size_t i = 0; i < num; i++) { - list[i](x, y, flags, (i + 1) * offset); + for (size_t i = 0; i < num; ++i) { + list[i](width, height, flags, (i + 1) * offset); } } - ~multi_array2D() - { - //printf("trying to delete the list of array2D objects\n"); - } - array2D & operator[](int index) { assert(static_cast(index) < num); diff --git a/rtengine/guidedfilter.cc b/rtengine/guidedfilter.cc index b3f843bc1..3f5e00e05 100644 --- a/rtengine/guidedfilter.cc +++ b/rtengine/guidedfilter.cc @@ -82,8 +82,8 @@ int calculate_subsampling(int w, int h, int r) void guidedFilter(const array2D &guide, const array2D &src, array2D &dst, int r, float epsilon, bool multithread, int subsampling) { - const int W = src.width(); - const int H = src.height(); + const int W = src.getWidth(); + const int H = src.getHeight(); if (subsampling <= 0) { subsampling = calculate_subsampling(W, H, r); @@ -94,8 +94,8 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 const auto apply = [=](Op op, array2D &res, const array2D &a, const array2D &b, const array2D &c=array2D()) -> void { - const int w = res.width(); - const int h = res.height(); + const int w = res.getWidth(); + const int h = res.getHeight(); #ifdef _OPENMP #pragma omp parallel for if (multithread) @@ -142,12 +142,12 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 const auto f_subsample = [=](array2D &d, const array2D &s) -> void { - if (d.width() == s.width() && d.height() == s.height()) { + if (d.getWidth() == s.getWidth() && d.getHeight() == s.getHeight()) { #ifdef _OPENMP # pragma omp parallel for if (multithread) #endif - for (int y = 0; y < s.height(); ++y) { - for (int x = 0; x < s.width(); ++x) { + for (int y = 0; y < s.getHeight(); ++y) { + for (int x = 0; x < s.getWidth(); ++x) { d[y][x] = s[y][x]; } } @@ -164,9 +164,9 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 const auto f_mean = [multithread](array2D &d, array2D &s, int rad) -> void { - rad = LIM(rad, 0, (min(s.width(), s.height()) - 1) / 2 - 1); - // boxblur(s, d, rad, s.width(), s.height(), multithread); - boxblur(static_cast(s), static_cast(d), rad, s.width(), s.height(), multithread); + rad = LIM(rad, 0, (min(s.getWidth(), s.getHeight()) - 1) / 2 - 1); + // boxblur(s, d, rad, s.getWidth(), s.getHeight(), multithread); + boxblur(static_cast(s), static_cast(d), rad, s.getWidth(), s.getHeight(), multithread); }; array2D I1(w, h); @@ -225,10 +225,10 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 DEBUG_DUMP(meanb); // speedup by heckflosse67 - const int Ws = meana.width(); - const int Hs = meana.height(); - const int Wd = q.width(); - const int Hd = q.height(); + const int Ws = meana.getWidth(); + const int Hs = meana.getHeight(); + const int Wd = q.getWidth(); + const int Hd = q.getHeight(); const float col_scale = float(Ws) / float(Wd); const float row_scale = float(Hs) / float(Hd); @@ -249,8 +249,8 @@ void guidedFilterLog(const array2D &guide, float base, array2D &ch #ifdef _OPENMP # pragma omp parallel for if (multithread) #endif - for (int y = 0; y < chan.height(); ++y) { - for (int x = 0; x < chan.width(); ++x) { + for (int y = 0; y < chan.getHeight(); ++y) { + for (int x = 0; x < chan.getWidth(); ++x) { chan[y][x] = xlin2log(max(chan[y][x], 0.f), base); } } @@ -260,8 +260,8 @@ void guidedFilterLog(const array2D &guide, float base, array2D &ch #ifdef _OPENMP # pragma omp parallel for if (multithread) #endif - for (int y = 0; y < chan.height(); ++y) { - for (int x = 0; x < chan.width(); ++x) { + for (int y = 0; y < chan.getHeight(); ++y) { + for (int x = 0; x < chan.getWidth(); ++x) { chan[y][x] = xlog2lin(max(chan[y][x], 0.f), base); } } diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 4376808f8..6526d0d1e 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -105,8 +105,8 @@ void restore(Imagefloat *rgb, float maxval, bool multithread) int get_dark_channel(const array2D &R, const array2D &G, const array2D &B, array2D &dst, int patchsize, const float ambient[3], bool clip, bool multithread, float strength) { - const int W = R.width(); - const int H = R.height(); + const int W = R.getWidth(); + const int H = R.getHeight(); #ifdef _OPENMP #pragma omp parallel for if (multithread) @@ -164,8 +164,8 @@ int get_dark_channel(const array2D &R, const array2D &G, const arr int get_dark_channel_downsized(const array2D &R, const array2D &G, const array2D &B, array2D &dst, int patchsize, bool multithread) { - const int W = R.width(); - const int H = R.height(); + const int W = R.getWidth(); + const int H = R.getHeight(); #ifdef _OPENMP #pragma omp parallel for if (multithread) @@ -195,8 +195,8 @@ int get_dark_channel_downsized(const array2D &R, const array2D &G, float estimate_ambient_light(const array2D &R, const array2D &G, const array2D &B, const array2D &dark, int patchsize, int npatches, float ambient[3]) { - const int W = R.width(); - const int H = R.height(); + const int W = R.getWidth(); + const int H = R.getHeight(); float darklim = RT_INFINITY_F; { diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index b349a454a..2c86db032 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -1840,8 +1840,8 @@ void tone_eq(array2D &R, array2D &G, array2D &B, const stru { BENCHFUN - const int W = R.width(); - const int H = R.height(); + const int W = R.getWidth(); + const int H = R.getHeight(); array2D Y(W, H); const auto log2 = diff --git a/rtengine/rescale.h b/rtengine/rescale.h index 2138cd8e8..3126a7c58 100644 --- a/rtengine/rescale.h +++ b/rtengine/rescale.h @@ -31,8 +31,8 @@ namespace rtengine inline float getBilinearValue(const array2D &src, float x, float y) { - const int W = src.width(); - const int H = src.height(); + const int W = src.getWidth(); + const int H = src.getHeight(); // Get integer and fractional parts of numbers int xi = x; @@ -57,10 +57,10 @@ inline float getBilinearValue(const array2D &src, float x, float y) inline void rescaleBilinear(const array2D &src, array2D &dst, bool multithread) { - const int Ws = src.width(); - const int Hs = src.height(); - const int Wd = dst.width(); - const int Hd = dst.height(); + const int Ws = src.getWidth(); + const int Hs = src.getHeight(); + const int Wd = dst.getWidth(); + const int Hd = dst.getHeight(); float col_scale = float (Ws) / float (Wd); float row_scale = float (Hs) / float (Hd); @@ -81,10 +81,10 @@ inline void rescaleBilinear(const array2D &src, array2D &dst, bool inline void rescaleNearest(const array2D &src, array2D &dst, bool multithread) { - const int width = src.width(); - const int height = src.height(); - const int nw = dst.width(); - const int nh = dst.height(); + const int width = src.getWidth(); + const int height = src.getHeight(); + const int nw = dst.getWidth(); + const int nh = dst.getHeight(); #ifdef _OPENMP #pragma omp parallel for if (multithread) diff --git a/rtengine/tmo_fattal02.cc b/rtengine/tmo_fattal02.cc index bef41d953..f49fe9c53 100644 --- a/rtengine/tmo_fattal02.cc +++ b/rtengine/tmo_fattal02.cc @@ -123,12 +123,12 @@ public: int getRows() const { - return const_cast(*this).height(); + return const_cast(*this).getHeight(); } int getCols() const { - return const_cast(*this).width(); + return const_cast(*this).getWidth(); } float *data()