diff --git a/rtengine/EdgePreserveLab.cc b/rtengine/EdgePreserveLab.cc deleted file mode 100644 index 1f063ec0c..000000000 --- a/rtengine/EdgePreserveLab.cc +++ /dev/null @@ -1,264 +0,0 @@ -#include "EdgePreserveLab.h" -#include "boxblur.h" -#include - -#ifdef _OPENMP -#include -#endif - -//#define MAX(a,b) ((a)<(b)?(b):(a)) -//#define MIN(a,b) ((a)>(b)?(b):(a)) - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -EdgePreserveLab::EdgePreserveLab(unsigned int width, unsigned int height) -{ - w = width; - h = height; - n = w * h; - - //Initialize the matrix just once at construction. - A = new MultiDiagonalSymmetricMatrix(n, 5); - - if(!( - A->CreateDiagonal(0, 0) && - A->CreateDiagonal(1, 1) && - A->CreateDiagonal(2, w - 1) && - A->CreateDiagonal(3, w) && - A->CreateDiagonal(4, w + 1))) { - delete A; - A = NULL; - printf("Error in EdgePreserveLab construction: out of memory.\n"); - } else { - a0 = A->Diagonals[0]; - a_1 = A->Diagonals[1]; - a_w1 = A->Diagonals[2]; - a_w = A->Diagonals[3]; - a_w_1 = A->Diagonals[4]; - } -} - -EdgePreserveLab::~EdgePreserveLab() -{ - delete A; -} - -float *EdgePreserveLab::CreateBlur(float *Source, float LScale, float abScale, float EdgeStoppingLuma, float EdgeStoppingChroma, unsigned int Iterates, float *Blur, bool UseBlurForEdgeStop) -{ - if(Blur == NULL) - UseBlurForEdgeStop = false, //Use source if there's no supplied Blur. - Blur = new float[3 * n]; - - if(LScale == 0.0f) { - memcpy(Blur, Source, 3 * n * sizeof(float)); - return Blur; - } - - //Create the edge stopping function a, rotationally symmetric and just one instead of (ax, ay). Maybe don't need Blur yet, so use its memory. - float *a, *b, *g; - - if(UseBlurForEdgeStop) { - a = new float[n], g = Blur; - } else { - a = Blur, g = Source; - } - - //b = new float[n]; - - unsigned int x, y, i; - unsigned int w1 = w - 1, h1 = h - 1; - float eps = 0.0001f; - float scL = powf(100.0f, LScale); - float scab = powf(200.0f, abScale); - - float * var = new float[w * h]; - rtengine::boxvar(g, var, 1, 1, w, h); - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for(y = 0; y < h1; y++) { - float *rg = &g[w * y]; - - for(x = 0; x < w1; x++) { - //Estimate the central difference gradient in the center of a four pixel square. (gx, gy) is actually 2*gradient. - /*float gx = (fabs((rg[x + 1] - rg[x]) + (rg[x + w + 1] - rg[x + w]))); - float gy = (fabs((rg[x + w] - rg[x]) + (rg[x + w + 1] - rg[x + 1]))); - - //TODO: combine this with gx, gy if not needing separate quantities - float hx = (fabs((rg[x + 1 + n] - rg[x + n]) + (rg[x + w + 1 + n] - rg[x + w + n])) + \ - fabs((rg[x + 1 + 2*n] - rg[x + 2*n]) + (rg[x + w + 1 + 2*n] - rg[x + w + 2*n]))); - float hy = (fabs((rg[x + w + n] - rg[x + n]) + (rg[x + w + 1 + n] - rg[x + 1 + n])) + \ - fabs((rg[x + w + 2*n] - rg[x + 2*n]) + (rg[x + w + 1 + 2*n] - rg[x + 1 + 2*n]))); - */ - //float gradtot = (gx+gy+hx+hy); - //gradhisto[MAX(0,MIN(32767,(int)gradtot))] ++; - - //Apply power to the magnitude of the gradient to get the edge stopping function. - //a[x + w*y] = scL*expf(-100.0f*(gx + gy + hx + hy)/(EdgeStoppingLuma)); - //a[x + w*y] = scL*expf(-var[y*w+x]/SQR(0.02*EdgeStoppingLuma));///(0.1+rg[x]); - a[x + w * y] = scL * expf(-50.0f * sqrt(var[y * w + x]) / (EdgeStoppingLuma + eps)); ///(0.1+rg[x]); - - //b[x + w*y] = (scab)*expf(-20.0f*(gx + gy + Lave*(hx + hy))/(EdgeStoppingChroma)); - //b[x + w*y] = (scab)*expf(-400.0f*SQR(gx + gy + Lave*(hx + hy))/SQR(EdgeStoppingChroma));; - - } - } - - /* Now setup the linear problem. I use the Maxima CAS, here's code for making an FEM formulation for the smoothness term: - p(x, y) := (1 - x)*(1 - y); - P(m, n) := A[m][n]*p(x, y) + A[m + 1][n]*p(1 - x, y) + A[m + 1][n + 1]*p(1 - x, 1 - y) + A[m][n + 1]*p(x, 1 - y); - Integrate(f) := integrate(integrate(f, x, 0, 1), y, 0, 1); - - Integrate(diff(P(u, v), x)*diff(p(x, y), x) + diff(P(u, v), y)*diff(p(x, y), y)); - Integrate(diff(P(u - 1, v), x)*diff(p(1 - x, y), x) + diff(P(u - 1, v), y)*diff(p(1 - x, y), y)); - Integrate(diff(P(u - 1, v - 1), x)*diff(p(1 - x, 1 - y), x) + diff(P(u - 1, v - 1), y)*diff(p(1 - x, 1 - y), y)); - Integrate(diff(P(u, v - 1), x)*diff(p(x, 1 - y), x) + diff(P(u, v - 1), y)*diff(p(x, 1 - y), y)); - So yeah. Use the numeric results of that to fill the matrix A.*/ - memset(a_1, 0, A->DiagonalLength(1)*sizeof(float)); - memset(a_w1, 0, A->DiagonalLength(w - 1)*sizeof(float)); - memset(a_w, 0, A->DiagonalLength(w)*sizeof(float)); - memset(a_w_1, 0, A->DiagonalLength(w + 1)*sizeof(float)); - -//TODO: OMP here? - for(i = y = 0; y != h; y++) { - for(x = 0; x != w; x++, i++) { - float ac; - a0[i] = 1.0; - - //Remember, only fill the lower triangle. Memory for upper is never made. It's symmetric. Trust. - if(x > 0 && y > 0) - ac = a[i - w - 1] / 6.0f, - a_w_1[i - w - 1] -= 2.0f * ac, a_w[i - w] -= ac, - a_1[i - 1] -= ac, a0[i] += 4.0f * ac; - - if(x < w1 && y > 0) - ac = a[i - w] / 6.0f, - a_w[i - w] -= ac, a_w1[i - w + 1] -= 2.0f * ac, - a0[i] += 4.0f * ac; - - if(x > 0 && y < h1) - ac = a[i - 1] / 6.0f, - a_1[i - 1] -= ac, a0[i] += 4.0f * ac; - - if(x < w1 && y < h1) { - a0[i] += 4.0f * a[i] / 6.0f; - } - } - } - - if(UseBlurForEdgeStop) { - delete[] a; - } - - - //Solve & return. - A->CreateIncompleteCholeskyFactorization(1); //Fill-in of 1 seems to work really good. More doesn't really help and less hurts (slightly). - - if(!UseBlurForEdgeStop) { - memcpy(Blur, Source, 3 * n * sizeof(float)); - } - - // blur L channel - SparseConjugateGradient(A->PassThroughVectorProduct, Source, n, false, Blur, 0.0f, (void *)A, Iterates, A->PassThroughCholeskyBackSolve); - - //reset A for ab channels - /*memset(a_1, 0, A->DiagonalLength(1)*sizeof(float)); - memset(a_w1, 0, A->DiagonalLength(w - 1)*sizeof(float)); - memset(a_w, 0, A->DiagonalLength(w)*sizeof(float)); - memset(a_w_1, 0, A->DiagonalLength(w + 1)*sizeof(float)); - for(i = y = 0; y != h; y++){ - for(x = 0; x != w; x++, i++){ - float ac; - a0[i] = 1.0; - - //Remember, only fill the lower triangle. Memory for upper is never made. It's symmetric. Trust. - if(x > 0 && y > 0) - ac = b[i - w - 1]/6.0f, - a_w_1[i - w - 1] -= 2.0f*ac, a_w[i - w] -= ac, - a_1[i - 1] -= ac, a0[i] += 4.0f*ac; - - if(x < w1 && y > 0) - ac = b[i - w]/6.0f, - a_w[i - w] -= ac, a_w1[i - w + 1] -= 2.0f*ac, - a0[i] += 4.0f*ac; - - if(x > 0 && y < h1) - ac = b[i - 1]/6.0f, - a_1[i - 1] -= ac, a0[i] += 4.0f*ac; - - if(x < w1 && y < h1) - a0[i] += 4.0f*b[i]/6.0f; - } - }*/ - /*if(UseBlurForEdgeStop)*/ //delete[] b; - - // blur ab channels - //A->CreateIncompleteCholeskyFactorization(1); //Fill-in of 1 seems to work really good. More doesn't really help and less hurts (slightly). - //SparseConjugateGradient(A->PassThroughVectorProduct, Source+n, n, false, Blur+n, 0.0f, (void *)A, Iterates, A->PassThroughCholeskyBackSolve); - //SparseConjugateGradient(A->PassThroughVectorProduct, Source+2*n, n, false, Blur+2*n, 0.0f, (void *)A, Iterates, A->PassThroughCholeskyBackSolve); - - A->KillIncompleteCholeskyFactorization(); - return Blur; -} - -float *EdgePreserveLab::CreateIteratedBlur(float *Source, float LScale, float abScale, float EdgeStoppingLuma, float EdgeStoppingChroma, unsigned int Iterates, unsigned int Reweightings, float *Blur) -{ - //Simpler outcome? - if(Reweightings == 0) { - return CreateBlur(Source, LScale, abScale, EdgeStoppingLuma, EdgeStoppingChroma, Iterates, Blur); - } - - //Create a blur here, initialize. - if(Blur == NULL) { - Blur = new float[3 * n]; - } - - memcpy(Blur, Source, 3 * n * sizeof(float)); - - //Iteratively improve the blur. - Reweightings++; - - for(unsigned int i = 0; i != Reweightings; i++) { - CreateBlur(Source, LScale, abScale, EdgeStoppingLuma, EdgeStoppingChroma, Iterates, Blur, true); - } - - return Blur; -} - -float *EdgePreserveLab::CompressDynamicRange(float *Source, float LScale, float abScale, float EdgeStoppingLuma, float EdgeStoppingChroma, float CompressionExponent, float DetailBoost, unsigned int Iterates, unsigned int Reweightings, float *Compressed) -{ - //We're working with luminance, which does better logarithmic. - unsigned int i; - //for(i = 0; i != n; i++) - // Source[i] = logf(Source[i] + 0.0001f); - - //Blur. Also setup memory for Compressed (we can just use u since each element of u is used in one calculation). - float *u = CreateIteratedBlur(Source, LScale, abScale, EdgeStoppingLuma, EdgeStoppingChroma, Iterates, Reweightings); - - if(Compressed == NULL) { - Compressed = u; - } - - //Apply compression, detail boost, unlogging. Compression is done on the logged data and detail boost on unlogged. - for(i = 0; i != n; i++) { - //float ce = expf(Source[i] + u[i]*(CompressionExponent - 1.0f)) - 0.0001f; - //float ue = expf(u[i]) - 0.0001f; - //Source[i] = expf(Source[i]) - 0.0001f; - //Compressed[i] = ce + DetailBoost*(Source[i] - ue); - Compressed[i] = u[i];//ue;//for testing, to display blur - } - - if(Compressed != u) { - delete[] u; - } - - return Compressed; -} - - - - diff --git a/rtengine/EdgePreserveLab.h b/rtengine/EdgePreserveLab.h deleted file mode 100644 index e365956c5..000000000 --- a/rtengine/EdgePreserveLab.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once -/* -The EdgePreserveLab files contain standard C++ (standard except the first line) code for creating and, to a -limited extent (create your own uses!), messing with multi scale edge preserving decompositions of a 32 bit single channel -image. As a byproduct it contains a lot of linear algebra which can be useful for optimization problems that -you want to solve in rectangles on rectangular grids. - -Anyway. Basically, this is an implementation of what's presented in the following papers: - Edge-Preserving Decompositions for Multi-Scale Tone and Detail Manipulation - An Iterative Solution Method for Linear Systems of Which the Coefficient Matrix is a Symetric M-Matrix - Color correction for tone mapping - Wikipedia, the free encyclopedia - -First one is most of what matters, next two are details, last everything else. I did a few things differently, especially: - Reformulated the minimization with finite elements instead of finite differences. This results in better conditioning, - slightly better accuracy (less artifacts), the possibility of a better picked edge stopping function, but more memory consumption. - - A single rotationally invariant edge stopping function is used instead of two non-invariant ones. - - Incomplete Cholseky factorization instead of Szeliski's LAHBF. Slower, but not subject to any patents. - - For tone mapping, original images are decomposed instead of their logarithms, and just one decomposition is made; - I find that this way works plenty good (theirs isn't better or worse... just different) and is simpler. - -Written by ben_pcc in Portland, Oregon, USA; code modified by Emil Martinec. - - // EdgePreserveLab.h and EdgePreserveLab.cpp are 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. - // - // This program 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 this program. If not, see . - -*/ - - - -#include -#include -#include -#include "EdgePreservingDecomposition.h" - -class EdgePreserveLab -{ -public: - EdgePreserveLab(unsigned int width, unsigned int height); - ~EdgePreserveLab(); - - //Create an edge preserving blur of Source. Will create and return, or fill into Blur if not NULL. In place not ok. - //If UseBlurForEdgeStop is true, supplied not NULL Blur is used to calculate the edge stopping function instead of Source. - float *CreateBlur(float *Source, float LScale, float abScale, float EdgeStoppingLuma, float EdgeStoppingChroma, unsigned int Iterates, float *Blur = NULL, bool UseBlurForEdgeStop = false); - - //Iterates CreateBlur such that the smoothness term approaches a specific norm via iteratively reweighted least squares. In place not ok. - float *CreateIteratedBlur(float *Source, float LScale, float abScale, float EdgeStoppingLuma, float EdgeStoppingChroma, unsigned int Iterates, unsigned int Reweightings, float *Blur = NULL); - - /*Lowers global contrast while preserving or boosting local contrast. Can fill into Compressed. The smaller Compression - the more compression is applied, with Compression = 1 giving no effect and above 1 the opposite effect. You can totally - use Compression = 1 and play with DetailBoost for some really sweet unsharp masking. If working on luma/grey, consider giving it a logarithm. - In place calculation to save memory (Source == Compressed) is totally ok. Reweightings > 0 invokes CreateIteratedBlur instead of CreateBlur. */ - float *CompressDynamicRange(float *Source, float LScale = 1.0f, float abScale = 5.0f, float EdgeStoppingLuma = 1.0f, float EdgeStoppingChroma = 1.0f, - float CompressionExponent = 0.8f, float DetailBoost = 0.1f, unsigned int Iterates = 20, - unsigned int Reweightings = 0, float *Compressed = NULL); - -private: - MultiDiagonalSymmetricMatrix *A; //The equations are simple enough to not mandate a matrix class, but fast solution NEEDS a complicated preconditioner. - unsigned int w, h, n; - - //Convenient access to the data in A. - float *a0, *a_1, *a_w, *a_w_1, *a_w1; -}; diff --git a/rtengine/EdgePreservingDecomposition.h b/rtengine/EdgePreservingDecomposition.h index 558caa5db..a369bdf4d 100644 --- a/rtengine/EdgePreservingDecomposition.h +++ b/rtengine/EdgePreservingDecomposition.h @@ -60,6 +60,7 @@ class MultiDiagonalSymmetricMatrix { public: MultiDiagonalSymmetricMatrix(int Dimension, int NumberOfDiagonalsInLowerTriangle); + MultiDiagonalSymmetricMatrix(const MultiDiagonalSymmetricMatrix&) = delete; ~MultiDiagonalSymmetricMatrix(); /* Storage of matrix data, and a function to create memory for Diagonals[index]. @@ -118,6 +119,7 @@ class EdgePreservingDecomposition { public: EdgePreservingDecomposition(int width, int height); + EdgePreservingDecomposition(const EdgePreservingDecomposition&) = delete; ~EdgePreservingDecomposition(); //Create an edge preserving blur of Source. Will create and return, or fill into Blur if not NULL. In place not ok. diff --git a/rtengine/LUT.h b/rtengine/LUT.h index 24f883766..c570fe671 100644 --- a/rtengine/LUT.h +++ b/rtengine/LUT.h @@ -167,6 +167,8 @@ public: reset(); } + LUT(const LUT&) = delete; + ~LUT() { if (owner) { diff --git a/rtengine/array2D.h b/rtengine/array2D.h index f9d92ac36..75d784cbc 100644 --- a/rtengine/array2D.h +++ b/rtengine/array2D.h @@ -167,6 +167,8 @@ public: } } + array2D(const array2D&) = delete; + // destructor ~array2D() { diff --git a/rtengine/cieimage.h b/rtengine/cieimage.h index a97622325..d8cf45cf8 100644 --- a/rtengine/cieimage.h +++ b/rtengine/cieimage.h @@ -41,6 +41,8 @@ public: float** h_p; CieImage (int w, int h); + CieImage (const CieImage&) = delete; + ~CieImage (); //Copies image data in Img into this instance. diff --git a/rtengine/cplx_wavelet_dec.h b/rtengine/cplx_wavelet_dec.h index 0ab01be57..c5267897c 100644 --- a/rtengine/cplx_wavelet_dec.h +++ b/rtengine/cplx_wavelet_dec.h @@ -58,6 +58,8 @@ public: template wavelet_decomposition(E * src, int width, int height, int maxlvl, int subsampling, int skipcrop = 1, int numThreads = 1, int Daub4Len = 6); + wavelet_decomposition(const wavelet_decomposition&) = delete; + ~wavelet_decomposition(); internal_type ** level_coeffs(int level) const diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index b832951c3..1f41dd6b4 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -6375,7 +6375,7 @@ void ImProcFunctions::EPDToneMapCIE(CieImage *ncie, float a_w, float c_, float w Qpro = maxQ; } - EdgePreservingDecomposition epd = EdgePreservingDecomposition(Wid, Hei); + EdgePreservingDecomposition epd(Wid, Hei); #pragma omp parallel for @@ -6479,7 +6479,7 @@ void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip) float *a = lab->a[0]; float *b = lab->b[0]; unsigned int i, N = lab->W * lab->H; - EdgePreservingDecomposition epd = EdgePreservingDecomposition(lab->W, lab->H); + EdgePreservingDecomposition epd(lab->W, lab->H); //Due to the taking of logarithms, L must be nonnegative. Further, scale to 0 to 1 using nominal range of L, 0 to 15 bit. float minL = FLT_MAX; diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index 4c2da72a4..9e81f4f90 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -338,13 +338,11 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int Image16* image = new Image16 (cw, ch); float p1, p2, p3, p4, p5, p6; //primaries - double g_a0, g_a1, g_a2, g_a3, g_a4, g_a5; //gamma parameters double pwr; double ts; ga6 = 0.0; pwr = 1.0 / gampos; ts = slpos; - int mode = 0, imax = 0; int t50; int select_temp = 1; //5003K @@ -475,6 +473,9 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int slpos = eps; } + double g_a0, g_a1, g_a2, g_a3, g_a4, g_a5; //gamma parameters + int mode = 0, imax = 0; + Color::calcGamma(pwr, ts, mode, imax, g_a0, g_a1, g_a2, g_a3, g_a4, g_a5); // call to calcGamma with selected gamma and slope : return parameters for LCMS2 ga4 = g_a3 * ts; ga0 = gampos; diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index d5aa54890..fd682d1d5 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -1647,7 +1647,7 @@ void ImProcFunctions::EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterat float sca = params->epd.scale; float gamm = params->wavelet.gamma; float rew = params->epd.reweightingIterates; - EdgePreservingDecomposition epd2 = EdgePreservingDecomposition(W_L, H_L); + EdgePreservingDecomposition epd2(W_L, H_L); cp.TMmeth = 2; //default after testing if(cp.TMmeth == 1) { diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index 86965a612..efb2dacc4 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -48,6 +48,9 @@ public: pm = new base_t [h * w ]; memset(pm, 0, h * w * base_t_size ); } + + PixelsMap(const PixelsMap&) = delete; + ~PixelsMap() { delete [] pm; diff --git a/rtengine/shmap.h b/rtengine/shmap.h index 97a394927..990193378 100644 --- a/rtengine/shmap.h +++ b/rtengine/shmap.h @@ -33,6 +33,8 @@ public: float max_f, min_f, avg; SHMap (int w, int h, bool multiThread); + SHMap(const SHMap&) = delete; + ~SHMap (); void update (Imagefloat* img, double radius, double lumi[3], bool hq, int skip); diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 7777331e9..fcccd1161 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -202,6 +202,8 @@ public: Tag (TagDirectory* parent, const TagAttrib* attr, unsigned char *data, TagType t); Tag (TagDirectory* parent, const TagAttrib* attr, int data, TagType t); // create a new tag from array (used Tag (TagDirectory* parent, const TagAttrib* attr, const char* data); // create a new tag from array (used + Tag(const Tag&) = delete; + ~Tag (); void initType (unsigned char *data, TagType type); void initInt (int data, TagType t, int count = 1); diff --git a/rtgui/previewloader.cc b/rtgui/previewloader.cc index 02082f7a7..e7c3d4fac 100644 --- a/rtgui/previewloader.cc +++ b/rtgui/previewloader.cc @@ -80,6 +80,8 @@ public: threadPool_ = new Glib::ThreadPool(threadCount, 0); } + Impl(const Impl&) = delete; + Glib::ThreadPool* threadPool_; MyMutex mutex_; JobSet jobs_; diff --git a/rtgui/previewloader.h b/rtgui/previewloader.h index 762776ae7..05669d399 100644 --- a/rtgui/previewloader.h +++ b/rtgui/previewloader.h @@ -45,6 +45,8 @@ class PreviewLoader { public: + PreviewLoader(const PreviewLoader&) = delete; + /** * @brief Singleton entry point. * diff --git a/rtgui/profilestore.h b/rtgui/profilestore.h index 2928a01ef..d7b85b5f5 100644 --- a/rtgui/profilestore.h +++ b/rtgui/profilestore.h @@ -176,6 +176,8 @@ private: public: ProfileStore(); + ProfileStore (const ProfileStore&) = delete; + ~ProfileStore(); bool init (); void parseProfiles (); diff --git a/rtgui/thumbimageupdater.cc b/rtgui/thumbimageupdater.cc index 29160236e..a247af5f8 100644 --- a/rtgui/thumbimageupdater.cc +++ b/rtgui/thumbimageupdater.cc @@ -78,6 +78,8 @@ public: threadPool_ = new Glib::ThreadPool(threadCount, 0); } + Impl(const Impl&) = delete; + Glib::ThreadPool* threadPool_; // Need to be a Glib::Threads::Mutex because used in a Glib::Threads::Cond object... diff --git a/rtgui/thumbimageupdater.h b/rtgui/thumbimageupdater.h index ea9cff6d7..8d1fc2cc5 100644 --- a/rtgui/thumbimageupdater.h +++ b/rtgui/thumbimageupdater.h @@ -46,6 +46,8 @@ class ThumbImageUpdater public: + ThumbImageUpdater(const ThumbImageUpdater&) = delete; + /** * @brief Singleton entry point. *