From d22d77c507fd66dcad2072aedf329b50d7584d36 Mon Sep 17 00:00:00 2001 From: Steve Herrell Date: Thu, 28 Oct 2010 17:31:05 +0200 Subject: [PATCH] improve stability for ICC storage and avoid race conditions. preparation step 1 for making dcraw multithread safe. --- rtengine/iccstore.cc | 37 ++++++++++++++++++++++++++++++------- rtengine/iccstore.h | 9 +++++++-- rtengine/improcfun.cc | 12 ++++++------ rtengine/init.cc | 2 +- rtengine/iplab2rgb.cc | 8 ++++---- rtengine/rawimagesource.cc | 12 ++++++------ rtengine/rtthumbnail.cc | 2 +- rtengine/simpleprocess.cc | 2 +- rtengine/stdimagesource.cc | 8 ++++---- 9 files changed, 60 insertions(+), 32 deletions(-) diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index 748a3046d..f5e96f713 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -27,8 +27,6 @@ namespace rtengine { -ICCStore iccStore; - const double (*wprofiles[])[3] = {sRGB_d50, adobe_d50, prophoto_d50, widegamut_d50, bruce_d50, beta_d50, best_d50}; const double (*iwprofiles[])[3] = {d50_sRGB, d50_adobe, d50_prophoto, d50_widegamut, d50_bruce, d50_beta, d50_best}; const char* wpnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; @@ -43,11 +41,13 @@ std::vector getWorkingProfiles () { std::vector getOutputProfiles () { - return iccStore.getOutputProfiles (); + return iccStore->getOutputProfiles (); } std::vector ICCStore::getOutputProfiles () { + Glib::Mutex::Lock lock(mutex_); + std::vector res; for (std::map::iterator i=fileProfiles.begin(); i!=fileProfiles.end(); i++) res.push_back (i->first); @@ -55,14 +55,30 @@ std::vector ICCStore::getOutputProfiles () { } -ICCStore::ICCStore () { +ICCStore* +ICCStore::getInstance(void) +{ + static ICCStore* instance_ = 0; + if ( instance_ == 0 ) + { + static Glib::Mutex smutex_; + Glib::Mutex::Lock lock(smutex_); + if ( instance_ == 0 ) + { + instance_ = new ICCStore(); + } + } + return instance_; +} +ICCStore::ICCStore () +{ cmsErrorAction (LCMS_ERROR_SHOW); int N = sizeof(wpnames)/sizeof(wpnames[0]); for (int i=0; i::iterator r = fileProfiles.find (name); if (r!=fileProfiles.end()) @@ -137,11 +154,15 @@ cmsHPROFILE ICCStore::getProfile (Glib::ustring name) { ProfileContent ICCStore::getContent (Glib::ustring name) { + Glib::Mutex::Lock lock(mutex_); + return fileProfileContents[name]; } std::vector ICCStore::parseDir (Glib::ustring pdir) { + Glib::Mutex::Lock lock(mutex_); + fileProfiles.clear (); fileProfileContents.clear (); std::vector result; @@ -309,6 +330,8 @@ cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, G strcpy ((char *)oprof+pbody[5]+12, name.c_str()); - return cmsOpenProfileFromMem (oprof, ntohl(oprof[0])); + cmsHPROFILE p = cmsOpenProfileFromMem (oprof, ntohl(oprof[0])); + delete [] oprof; + return p; } } diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index 3c0a9dc49..5e67b55a7 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -54,9 +54,14 @@ class ICCStore { cmsHPROFILE xyz; cmsHPROFILE srgb; + + Glib::Mutex mutex_; + + ICCStore (); public: - ICCStore (); + + static ICCStore* getInstance(void); int numOfWProfiles (); cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma=false, Glib::ustring name=""); @@ -74,7 +79,7 @@ class ICCStore { std::vector getOutputProfiles (); }; -extern ICCStore iccStore; +#define iccStore ICCStore::getInstance() //extern const char* wpnames[]; } diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 8b9a2f527..c89a0aa91 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -124,7 +124,7 @@ void ImProcFunctions::setScale (double iscale) { void ImProcFunctions::firstAnalysis_ (Image16* original, Glib::ustring wprofile, unsigned int* histogram, int* chroma_radius, int row_from, int row_to) { - TMatrix wprof = iccStore.workingSpaceMatrix (wprofile); + TMatrix wprof = iccStore->workingSpaceMatrix (wprofile); int toxyz[3][3]; toxyz[0][0] = round(32768.0 * wprof[0][0] / 0.96422); toxyz[1][0] = round(32768.0 * wprof[1][0] / 0.96422); @@ -184,12 +184,12 @@ void ImProcFunctions::firstAnalysis (Image16* original, const ProcParams* params if (monitorTransform) cmsDeleteTransform (monitorTransform); monitorTransform = NULL; - cmsHPROFILE monitor = iccStore.getProfile ("file:"+settings->monitorProfile); + cmsHPROFILE monitor = iccStore->getProfile ("file:"+settings->monitorProfile); if (monitor) { - cmsHPROFILE iprof = iccStore.getXYZProfile (); - cmsHPROFILE oprof = iccStore.getProfile (params->icm.output); + cmsHPROFILE iprof = iccStore->getXYZProfile (); + cmsHPROFILE oprof = iccStore->getProfile (params->icm.output); if (!oprof) - oprof = iccStore.getsRGBProfile (); + oprof = iccStore->getsRGBProfile (); lcmsMutex->lock (); monitorTransform = cmsCreateTransform (iprof, TYPE_RGB_16, monitor, TYPE_RGB_8, settings->colorimetricIntent, 0); lcmsMutex->unlock (); @@ -257,7 +257,7 @@ void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, int* tonecurve1, bool processLCE = params->sh.enabled && shmap!=NULL && params->sh.localcontrast>0; double lceamount = params->sh.localcontrast / 200.0; - TMatrix wprof = iccStore.workingSpaceMatrix (params->icm.working); + TMatrix wprof = iccStore->workingSpaceMatrix (params->icm.working); int toxyz[3][3] = { { floor(32768.0 * wprof[0][0] / 0.96422), diff --git a/rtengine/init.cc b/rtengine/init.cc index 167ca3e3a..6e8874160 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -32,7 +32,7 @@ Glib::Mutex* lcmsMutex = NULL; int init (const Settings* s) { settings = s; - iccStore.parseDir (s->iccDirectory); + iccStore->parseDir (s->iccDirectory); CurveFactory::init (); ImProcFunctions::initCache (); delete dcrMutex; diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index cf94f25e7..95900da69 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -114,10 +114,10 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Image8* image = new Image8 (cw, ch); - cmsHPROFILE oprof = iccStore.getProfile (profile); + cmsHPROFILE oprof = iccStore->getProfile (profile); if (oprof) { - cmsHPROFILE iprof = iccStore.getXYZProfile (); + cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_8, settings->colorimetricIntent, 0); lcmsMutex->unlock (); @@ -193,7 +193,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int Image16* image = new Image16 (cw, ch); - cmsHPROFILE oprof = iccStore.getProfile (profile); + cmsHPROFILE oprof = iccStore->getProfile (profile); if (oprof) { #pragma omp parallel for if (multiThread) @@ -222,7 +222,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int za[j-cx] = CLIP(z_); } } - cmsHPROFILE iprof = iccStore.getXYZProfile (); + cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16_PLANAR, oprof, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, 0); lcmsMutex->unlock (); diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index ffbae35f2..212db7fcf 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -782,7 +782,7 @@ int RawImageSource::load (Glib::ustring fname, bool batch) { for (int j=0; j<3; j++) for (int k=0; k<3; k++) cam[i][j] += coeff[k][i] * sRGB_d50[k][j]; - camProfile = iccStore.createFromMatrix (cam, false, "Camera"); + camProfile = iccStore->createFromMatrix (cam, false, "Camera"); inverse33 (cam, icam); if (ri->profile_data) @@ -1165,7 +1165,7 @@ void RawImageSource::colorSpaceConversion (Image16* im, ColorManagementParams cm else if (inProfile=="(camera)" || inProfile=="") in = camprofile; else { - in = iccStore.getProfile (inProfile); + in = iccStore->getProfile (inProfile); if (in==NULL) inProfile = "(camera)"; } @@ -1174,11 +1174,11 @@ void RawImageSource::colorSpaceConversion (Image16* im, ColorManagementParams cm if (inProfile=="(camera)" || inProfile=="" || (inProfile=="(embedded)" && !embedded)) { // in this case we avoid using the slllllooooooowwww lcms -// out = iccStore.workingSpace (wProfile); +// out = iccStore->workingSpace (wProfile); // hTransform = cmsCreateTransform (in, TYPE_RGB_16_PLANAR, out, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, cmsFLAGS_MATRIXINPUT | cmsFLAGS_MATRIXOUTPUT);//cmsFLAGS_MATRIXINPUT | cmsFLAGS_MATRIXOUTPUT); // cmsDoTransform (hTransform, im->data, im->data, im->planestride/2); // cmsDeleteTransform(hTransform); - TMatrix work = iccStore.workingSpaceInverseMatrix (cmp.working); + TMatrix work = iccStore->workingSpaceInverseMatrix (cmp.working); double mat[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; for (int i=0; i<3; i++) for (int j=0; j<3; j++) @@ -1199,8 +1199,8 @@ void RawImageSource::colorSpaceConversion (Image16* im, ColorManagementParams cm } } else { - out = iccStore.workingSpace (cmp.working); -// out = iccStore.workingSpaceGamma (wProfile); + out = iccStore->workingSpace (cmp.working); +// out = iccStore->workingSpaceGamma (wProfile); lcmsMutex->lock (); cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_16_PLANAR, out, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, 0); lcmsMutex->unlock (); diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 3ee47d5a5..39a6c46ec 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -143,7 +143,7 @@ void Thumbnail::init () { for (int j=0; j<3; j++) for (int k=0; k<3; k++) camToD50[i][j] += colorMatrix[k][i] * sRGB_d50[k][j]; - camProfile = iccStore.createFromMatrix (camToD50, false, "Camera"); + camProfile = iccStore->createFromMatrix (camToD50, false, "Camera"); } bool Thumbnail::igammacomputed = false; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 37f46ebab..169b7954c 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -199,7 +199,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p ProfileContent pc; if (params.icm.output.compare (0, 6, "No ICM") && params.icm.output!="") - pc = iccStore.getContent (params.icm.output); + pc = iccStore->getContent (params.icm.output); readyImg->setOutputProfile (pc.data, pc.length); diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 3ef593ead..cbffc3597 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -256,19 +256,19 @@ void StdImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, Previe void StdImageSource::colorSpaceConversion (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded) { cmsHPROFILE in; - cmsHPROFILE out = iccStore.workingSpace (cmp.working); + cmsHPROFILE out = iccStore->workingSpace (cmp.working); if (cmp.input=="(embedded)" || cmp.input=="" || cmp.input=="(camera)") { if (embedded) in = embedded; else - in = iccStore.getsRGBProfile (); + in = iccStore->getsRGBProfile (); } else if (cmp.input!="(none)") { - in = iccStore.getProfile (cmp.input); + in = iccStore->getProfile (cmp.input); if (in==NULL && embedded) in = embedded; else if (in==NULL) - in = iccStore.getsRGBProfile (); + in = iccStore->getsRGBProfile (); else if (cmp.gammaOnInput) for (int i=0; iheight; i++) for (int j=0; jwidth; j++) {