improve stability for ICC storage and avoid race conditions.

preparation step 1 for making dcraw multithread safe.
This commit is contained in:
Steve Herrell
2010-10-28 17:31:05 +02:00
parent 6770a2c4a0
commit d22d77c507
9 changed files with 60 additions and 32 deletions

View File

@@ -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<std::string> getWorkingProfiles () {
std::vector<std::string> getOutputProfiles () {
return iccStore.getOutputProfiles ();
return iccStore->getOutputProfiles ();
}
std::vector<std::string> ICCStore::getOutputProfiles () {
Glib::Mutex::Lock lock(mutex_);
std::vector<std::string> res;
for (std::map<std::string, cmsHPROFILE>::iterator i=fileProfiles.begin(); i!=fileProfiles.end(); i++)
res.push_back (i->first);
@@ -55,14 +55,30 @@ std::vector<std::string> 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<N; i++) {
wProfiles[wpnames[i]] = iccStore.createFromMatrix (wprofiles[i]);
wProfilesGamma[wpnames[i]] = iccStore.createFromMatrix (wprofiles[i], true);
wProfiles[wpnames[i]] = createFromMatrix (wprofiles[i]);
wProfilesGamma[wpnames[i]] = createFromMatrix (wprofiles[i], true);
wMatrices[wpnames[i]] = wprofiles[i];
iwMatrices[wpnames[i]] = iwprofiles[i];
}
@@ -115,6 +131,7 @@ cmsHPROFILE ICCStore::workingSpaceGamma (Glib::ustring name) {
cmsHPROFILE ICCStore::getProfile (Glib::ustring name) {
Glib::Mutex::Lock lock(mutex_);
std::map<std::string, cmsHPROFILE>::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<std::string> ICCStore::parseDir (Glib::ustring pdir) {
Glib::Mutex::Lock lock(mutex_);
fileProfiles.clear ();
fileProfileContents.clear ();
std::vector<std::string> 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;
}
}

View File

@@ -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<std::string> getOutputProfiles ();
};
extern ICCStore iccStore;
#define iccStore ICCStore::getInstance()
//extern const char* wpnames[];
}

View File

@@ -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),

View File

@@ -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;

View File

@@ -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 ();

View File

@@ -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 ();

View File

@@ -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;

View File

@@ -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);

View File

@@ -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; i<im->height; i++)
for (int j=0; j<im->width; j++) {