Retinex: Fixed crash in queue and race conditions in histogram

This commit is contained in:
heckflosse
2015-09-14 14:49:43 +02:00
parent 270367c592
commit c59fca2d6a
5 changed files with 147 additions and 57 deletions

View File

@@ -69,7 +69,7 @@ public:
virtual int load (Glib::ustring fname, bool batch = false) = 0; virtual int load (Glib::ustring fname, bool batch = false) = 0;
virtual void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse) {}; virtual void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse) {};
virtual void demosaic (const RAWParams &raw) {}; virtual void demosaic (const RAWParams &raw) {};
virtual void retinex (ColorManagementParams cmp, RetinexParams deh, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D<float, 3> &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu & lhist16RETI, LUTu &histLRETI) {}; virtual void retinex (ColorManagementParams cmp, RetinexParams deh, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D<float, 3> &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {};
virtual void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {}; virtual void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {};
virtual void retinexPrepareBuffers (ColorManagementParams cmp, RetinexParams retinexParams, multi_array2D<float, 3> &conversionBuffer, LUTu &lhist16RETI) {}; virtual void retinexPrepareBuffers (ColorManagementParams cmp, RetinexParams retinexParams, multi_array2D<float, 3> &conversionBuffer, LUTu &lhist16RETI) {};
virtual void flushRawData () {}; virtual void flushRawData () {};

View File

@@ -77,7 +77,7 @@ ImProcCoordinator::ImProcCoordinator ()
histChroma(256), histChroma(256),
histLRETI(256), histLRETI(256),
CAMBrightCurveJ(), CAMBrightCurveQ(), CAMBrightCurveJ(), CAMBrightCurveQ(),
rCurve(), rCurve(),
@@ -251,7 +251,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
imgsrc->retinexPrepareCurves(params.retinex, cdcurve, dehatransmissionCurve, dehacontlutili, useHsl, lhist16RETI, histLRETI); imgsrc->retinexPrepareCurves(params.retinex, cdcurve, dehatransmissionCurve, dehacontlutili, useHsl, lhist16RETI, histLRETI);
float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax;
imgsrc->retinex( params.icm, params.retinex, cdcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, lhist16RETI, histLRETI);//enabled Retinex imgsrc->retinex( params.icm, params.retinex, cdcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, histLRETI);//enabled Retinex
if(dehaListener) { if(dehaListener) {
dehaListener->minmaxChanged(maxCD, minCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); dehaListener->minmaxChanged(maxCD, minCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax);

View File

@@ -1817,6 +1817,15 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar
#pragma omp parallel #pragma omp parallel
#endif #endif
{ {
// one LUT per thread
LUTu lhist16RETIThr;
if(lhist16RETI)
{
lhist16RETIThr(32769, 0);
lhist16RETIThr.clear();
}
#ifdef __SSE2__ #ifdef __SSE2__
vfloat c32768 = F2V(32768.f); vfloat c32768 = F2V(32768.f);
#endif #endif
@@ -1837,8 +1846,13 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar
_mm_storeu_ps(&conversionBuffer[1][i - border][j - border], S); _mm_storeu_ps(&conversionBuffer[1][i - border][j - border], S);
L *= c32768; L *= c32768;
_mm_storeu_ps(&conversionBuffer[2][i - border][j - border], L); _mm_storeu_ps(&conversionBuffer[2][i - border][j - border], L);
pos = (INT) clipretinex( conversionBuffer[2][i - border][j - border], 0, 32768);//histogram in curve HSL
lhist16RETI[pos]++; if(lhist16RETI) {
for(int p = 0; p < 4; p++) {
pos = (INT) clipretinex( conversionBuffer[2][i - border][j - border + p], 0.f, 32768.f);//histogram in curve HSL
lhist16RETIThr[pos]++;
}
}
} }
#endif #endif
@@ -1850,10 +1864,27 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar
Color::rgb2hslfloat(red[i][j], green[i][j], blue[i][j], conversionBuffer[0][i - border][j - border], conversionBuffer[1][i - border][j - border], L); Color::rgb2hslfloat(red[i][j], green[i][j], blue[i][j], conversionBuffer[0][i - border][j - border], conversionBuffer[1][i - border][j - border], L);
L *= 32768.f; L *= 32768.f;
conversionBuffer[2][i - border][j - border] = L; conversionBuffer[2][i - border][j - border] = L;
pos = (INT) clipretinex(L, 0, 32768);
lhist16RETI[pos]++; if(lhist16RETI) {
pos = (INT) clipretinex(L, 0, 32768);
lhist16RETIThr[pos]++;
}
} }
} }
#ifdef _OPENMP
#pragma omp critical
{
if(lhist16RETI)
{
// Add per Thread LUT to global LUT
for(int i = 0; i < 32769; i++) {
lhist16RETI[i] += lhist16RETIThr[i];
}
}
}
#endif
} }
} else { } else {
TMatrix wprof = iccStore->workingSpaceMatrix (cmp.working); TMatrix wprof = iccStore->workingSpaceMatrix (cmp.working);
@@ -1866,23 +1897,52 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar
// Conversion rgb -> lab is hard to vectorize because it uses a lut (that's not the main problem) // Conversion rgb -> lab is hard to vectorize because it uses a lut (that's not the main problem)
// and it uses a condition inside XYZ2Lab which is almost impossible to vectorize without making it slower... // and it uses a condition inside XYZ2Lab which is almost impossible to vectorize without making it slower...
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for #pragma omp parallel
#endif
{
// one LUT per thread
LUTu lhist16RETIThr;
if(lhist16RETI) {
lhist16RETIThr(32769, 0);
lhist16RETIThr.clear();
}
#ifdef _OPENMP
#pragma omp for
#endif #endif
for (int i = border; i < H - border; i++ ) for (int i = border; i < H - border; i++ )
for (int j = border; j < W - border; j++) { for (int j = border; j < W - border; j++) {
float X, Y, Z, L, aa, bb; float X, Y, Z, L, aa, bb;
int pos; int pos;
//rgb=>lab //rgb=>lab
Color::rgbxyz(red[i][j], green[i][j], blue[i][j], X, Y, Z, wp); Color::rgbxyz(red[i][j], green[i][j], blue[i][j], X, Y, Z, wp);
//convert Lab //convert Lab
Color::XYZ2Lab(X, Y, Z, L, aa, bb); Color::XYZ2Lab(X, Y, Z, L, aa, bb);
conversionBuffer[0][i - border][j - border] = aa; conversionBuffer[0][i - border][j - border] = aa;
conversionBuffer[1][i - border][j - border] = bb; conversionBuffer[1][i - border][j - border] = bb;
conversionBuffer[2][i - border][j - border] = L; conversionBuffer[2][i - border][j - border] = L;
pos = (INT) clipretinex(L, 0, 32768);
lhist16RETI[pos]++;//histogram in Curve Lab if(lhist16RETI) {
pos = (INT) clipretinex(L, 0, 32768);
lhist16RETIThr[pos]++;//histogram in Curve Lab
}
}
#ifdef _OPENMP
#pragma omp critical
{
if(lhist16RETI) {
// Add per Thread LUT to global LUT
for(int i = 0; i < 32769; i++) {
lhist16RETI[i] += lhist16RETIThr[i];
}
}
} }
#endif
}
} }
} }
@@ -1899,7 +1959,7 @@ void RawImageSource::retinexPrepareCurves(RetinexParams retinexParams, LUTf &cdc
retinexParams.getCurves(retinextransmissionCurve); retinexParams.getCurves(retinextransmissionCurve);
} }
void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D<float, 3> &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu & lhist16RETI, LUTu &histLRETI) void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D<float, 3> &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI)
{ {
MyTime t4, t5; MyTime t4, t5;
@@ -1919,42 +1979,72 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, LUTf
LUTf dLcurve; LUTf dLcurve;
LUTu hist16RET; LUTu hist16RET;
float val; float val;
hist16RET(65536, 0);
hist16RET.clear(); if(dehacontlutili && histLRETI) {
hist16RET(32769, 0);
if(dehacontlutili) histLRETI.clear(); hist16RET.clear();
dLcurve(65536, 0); histLRETI.clear();
dLcurve.clear(); dLcurve(32769, 0);
dLcurve.clear();
}
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for #pragma omp parallel
#endif
{
// one LUT per thread
LUTu hist16RETThr;
if(dehacontlutili && histLRETI) {
hist16RETThr(32769, 0);
hist16RETThr.clear();
}
#ifdef _OPENMP
#pragma omp for
#endif #endif
for (int i = 0; i < H - 2 * border; i++ ) for (int i = 0; i < H - 2 * border; i++ )
if(dehacontlutili) if(dehacontlutili)
for (int j = 0; j < W - 2 * border; j++) { for (int j = 0; j < W - 2 * border; j++) {
LBuffer[i][j] = cdcurve[2.f * temp[i][j]] / 2.f; LBuffer[i][j] = cdcurve[2.f * temp[i][j]] / 2.f;
int pos = (INT) clipretinex(LBuffer[i][j], 0, 32768);
hist16RET[pos]++;//histogram in Curve if(histLRETI) {
int pos = (INT) clipretinex(LBuffer[i][j], 0.f, 32768.f);
hist16RETThr[pos]++; //histogram in Curve
}
}
else
for (int j = 0; j < W - 2 * border; j++) {
LBuffer[i][j] = temp[i][j];
}
#ifdef _OPENMP
#pragma omp critical
#endif
{
if(dehacontlutili && histLRETI) {
// Add per Thread LUT to global LUT
for(int i = 0; i < 32769; i++) {
hist16RET[i] += hist16RETThr[i];
}
} }
else }
for (int j = 0; j < W - 2 * border; j++) {
LBuffer[i][j] = temp[i][j];
}
if(dehacontlutili){//update histogram
for (int i = 0; i < 32768; i++) {
val = (double)i / 32767.0;
dLcurve[i] = CLIPD(val);
}
for (int i = 0; i < 32768; i++) {
float hval = dLcurve[i];
int hi = (int)(255.0f * CLIPD(hval));
histLRETI[hi] += hist16RET[i];
} }
if(dehacontlutili && histLRETI) {//update histogram
for (int i = 0; i < 32768; i++) {
val = (double)i / 32767.0;
dLcurve[i] = CLIPD(val);
}
for (int i = 0; i < 32768; i++) {
float hval = dLcurve[i];
int hi = (int)(255.0f * CLIPD(hval));
histLRETI[hi] += hist16RET[i];
}
} }
MSR(LBuffer, conversionBuffer[2], WNew, HNew, deh, dehatransmissionCurve, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); MSR(LBuffer, conversionBuffer[2], WNew, HNew, deh, dehatransmissionCurve, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax);
if(useHsl) { if(useHsl) {

View File

@@ -152,7 +152,7 @@ public:
void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse); void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse);
void demosaic (const RAWParams &raw); void demosaic (const RAWParams &raw);
// void retinex (RAWParams raw, ColorManagementParams cmp, RetinexParams lcur, LUTf & cdcurve, bool dehacontlutili); // void retinex (RAWParams raw, ColorManagementParams cmp, RetinexParams lcur, LUTf & cdcurve, bool dehacontlutili);
void retinex (ColorManagementParams cmp, RetinexParams deh, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D<float, 3> &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu & lhist16RETI, LUTu &histLRETI); void retinex (ColorManagementParams cmp, RetinexParams deh, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D<float, 3> &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI);
void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI); void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI);
void retinexPrepareBuffers (ColorManagementParams cmp, RetinexParams retinexParams, multi_array2D<float, 3> &conversionBuffer, LUTu &lhist16RETI); void retinexPrepareBuffers (ColorManagementParams cmp, RetinexParams retinexParams, multi_array2D<float, 3> &conversionBuffer, LUTu &lhist16RETI);
void flushRawData (); void flushRawData ();

View File

@@ -118,15 +118,15 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
if(params.retinex.enabled) { //enabled Retinex if(params.retinex.enabled) { //enabled Retinex
LUTf cdcurve (65536, 0); LUTf cdcurve (65536, 0);
LUTu dum; LUTu dummy;
RetinextransmissionCurve dehatransmissionCurve; RetinextransmissionCurve dehatransmissionCurve;
bool dehacontlutili = false; bool dehacontlutili = false;
bool useHsl = false; bool useHsl = false;
multi_array2D<float, 3> conversionBuffer(1, 1); multi_array2D<float, 3> conversionBuffer(1, 1);
imgsrc->retinexPrepareBuffers(params.icm, params.retinex, conversionBuffer, dum); imgsrc->retinexPrepareBuffers(params.icm, params.retinex, conversionBuffer, dummy);
imgsrc->retinexPrepareCurves(params.retinex, cdcurve, dehatransmissionCurve, dehacontlutili, useHsl, dum, dum); imgsrc->retinexPrepareCurves(params.retinex, cdcurve, dehatransmissionCurve, dehacontlutili, useHsl, dummy, dummy );
float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax;
imgsrc->retinex( params.icm, params.retinex, cdcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, dum, dum); imgsrc->retinex( params.icm, params.retinex, cdcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, dummy);
} }
if (pl) { if (pl) {