Add inverse to shapemethod - fixed crash retinex inverse

This commit is contained in:
Desmis 2018-01-03 16:47:54 +01:00
parent 63073b470d
commit 7a714e5093
17 changed files with 3583 additions and 3503 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -47,7 +47,7 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst,
int lastlevel = maxlevel;
if (settings->verbose) {
printf ("Dirpyr scaleprev=%i\n", scaleprev);
printf("Dirpyr scaleprev=%i\n", scaleprev);
}
float atten123 = (float) settings->level123_cbdl;
@ -75,7 +75,7 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst,
}
while (lastlevel > 0 && fabs (mult[lastlevel - 1] - 1) < 0.001) {
while (lastlevel > 0 && fabs(mult[lastlevel - 1] - 1) < 0.001) {
lastlevel--;
//printf("last level to process %d \n",lastlevel);
}
@ -88,7 +88,7 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst,
float multi[maxlevel] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f};
float scalefl[maxlevel];
for(int lv = 0; lv < maxlevel; lv++) {
for (int lv = 0; lv < maxlevel; lv++) {
scalefl[lv] = ((float) scales[lv]) / (float) scaleprev;
if (lv >= 1) {
@ -108,34 +108,34 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst,
}
if (settings->verbose) {
printf ("CbDL mult0=%f 1=%f 2=%f 3=%f 4=%f 5=%f\n", multi[0], multi[1], multi[2], multi[3], multi[4], multi[5]);
printf("CbDL mult0=%f 1=%f 2=%f 3=%f 4=%f 5=%f\n", multi[0], multi[1], multi[2], multi[3], multi[4], multi[5]);
}
multi_array2D<float, maxlevel> dirpyrlo (srcwidth, srcheight);
multi_array2D<float, maxlevel> dirpyrlo(srcwidth, srcheight);
level = 0;
//int thresh = 100 * mult[5];
int scale = (int) (scales[level]) / scaleprev;
int scale = (int)(scales[level]) / scaleprev;
if (scale < 1) {
scale = 1;
}
dirpyr_channel (src, dirpyrlo[0], srcwidth, srcheight, 0, scale);
dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale);
level = 1;
while (level < lastlevel) {
scale = (int) (scales[level]) / scaleprev;
scale = (int)(scales[level]) / scaleprev;
if (scale < 1) {
scale = 1;
}
dirpyr_channel (dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, scale);
dirpyr_channel(dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, scale);
level ++;
}
@ -159,11 +159,11 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst,
int j;
for (j = 0; j < srcwidth - 3; j += 4) {
_mm_storeu_ps (&tmpHue[i][j], xatan2f (LVFU (l_b[i][j]), LVFU (l_a[i][j])));
_mm_storeu_ps(&tmpHue[i][j], xatan2f(LVFU(l_b[i][j]), LVFU(l_a[i][j])));
}
for (; j < srcwidth; j++) {
tmpHue[i][j] = xatan2f (l_b[i][j], l_a[i][j]);
tmpHue[i][j] = xatan2f(l_b[i][j], l_a[i][j]);
}
}
@ -172,7 +172,7 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst,
for (int i = 0; i < srcheight; i++) {
for (int j = 0; j < srcwidth; j++) {
tmpHue[i][j] = xatan2f (l_b[i][j], l_a[i][j]);
tmpHue[i][j] = xatan2f(l_b[i][j], l_a[i][j]);
}
}
@ -186,18 +186,18 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst,
#ifdef __SSE2__
#pragma omp parallel
{
__m128 div = _mm_set1_ps (327.68f);
__m128 div = _mm_set1_ps(327.68f);
#pragma omp for
for (int i = 0; i < srcheight; i++) {
int j;
for (j = 0; j < srcwidth - 3; j += 4) {
_mm_storeu_ps (&tmpChr[i][j], _mm_sqrt_ps (SQRV (LVFU (l_b[i][j])) + SQRV (LVFU (l_a[i][j]))) / div);
_mm_storeu_ps(&tmpChr[i][j], _mm_sqrt_ps(SQRV(LVFU(l_b[i][j])) + SQRV(LVFU(l_a[i][j]))) / div);
}
for (; j < srcwidth; j++) {
tmpChr[i][j] = sqrtf (SQR ((l_b[i][j])) + SQR ((l_a[i][j]))) / 327.68f;
tmpChr[i][j] = sqrtf(SQR((l_b[i][j])) + SQR((l_a[i][j]))) / 327.68f;
}
}
}
@ -206,7 +206,7 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst,
for (int i = 0; i < srcheight; i++) {
for (int j = 0; j < srcwidth; j++) {
tmpChr[i][j] = sqrtf (SQR ((l_b[i][j])) + SQR ((l_a[i][j]))) / 327.68f;
tmpChr[i][j] = sqrtf(SQR((l_b[i][j])) + SQR((l_a[i][j]))) / 327.68f;
}
}
@ -216,7 +216,7 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst,
// with the current implementation of idirpyr_eq_channel we can safely use the buffer from last level as buffer, saves some memory
float ** buffer = dirpyrlo[lastlevel - 1];
for(int level = lastlevel - 1; level > 0; level--) {
for (int level = lastlevel - 1; level > 0; level--) {
idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, b_l, t_l, t_r);
}
@ -242,17 +242,17 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst,
for (int i = 0; i < srcheight; i++)
for (int j = 0; j < srcwidth; j++) {
dst[i][j] = CLIP (buffer[i][j]); // TODO: Really a clip necessary?
dst[i][j] = CLIP(buffer[i][j]); // TODO: Really a clip necessary?
}
}
SSEFUNCTION void ImProcFunctions :: cbdl_local_temp (float ** src, float ** dst, float ** loctemp, int srcwidth, int srcheight, const float * mult, float kchro, const double dirpyrThreshold, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scaleprev)
SSEFUNCTION void ImProcFunctions :: cbdl_local_temp(float ** src, float ** dst, float ** loctemp, int srcwidth, int srcheight, const float * mult, float kchro, const double dirpyrThreshold, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scaleprev)
{
int lastlevel = maxlevelloc;
if (settings->verbose) {
printf ("Dirpyr scaleprev=%i\n", scaleprev);
printf("Dirpyr scaleprev=%i\n", scaleprev);
}
float atten123 = (float) settings->level123_cbdl;
@ -279,7 +279,7 @@ SSEFUNCTION void ImProcFunctions :: cbdl_local_temp (float ** src, float ** dst,
t_l = t_r + 0.55f; //avoid too small range
}
while (lastlevel > 0 && fabs (mult[lastlevel - 1] - 1) < 0.001) {
while (lastlevel > 0 && fabs(mult[lastlevel - 1] - 1) < 0.001) {
lastlevel--;
//printf("last level to process %d \n",lastlevel);
@ -316,34 +316,34 @@ SSEFUNCTION void ImProcFunctions :: cbdl_local_temp (float ** src, float ** dst,
}
if (settings->verbose) {
printf ("CbDL local mult0=%f 1=%f 2=%f 3=%f 4=%f\n", multi[0], multi[1], multi[2], multi[3], multi[4]);
printf("CbDL local mult0=%f 1=%f 2=%f 3=%f 4=%f\n", multi[0], multi[1], multi[2], multi[3], multi[4]);
}
multi_array2D<float, maxlevelloc> dirpyrlo (srcwidth, srcheight);
multi_array2D<float, maxlevelloc> dirpyrlo(srcwidth, srcheight);
level = 0;
//int thresh = 100 * mult[5];
int scale = (int) (scalesloc[level]) / scaleprev;
int scale = (int)(scalesloc[level]) / scaleprev;
if (scale < 1) {
scale = 1;
}
dirpyr_channel (src, dirpyrlo[0], srcwidth, srcheight, 0, scale);
dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale);
level = 1;
while (level < lastlevel) {
scale = (int) (scalesloc[level]) / scaleprev;
scale = (int)(scalesloc[level]) / scaleprev;
if (scale < 1) {
scale = 1;
}
dirpyr_channel (dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, scale);
dirpyr_channel(dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, scale);
level ++;
}
@ -354,31 +354,31 @@ SSEFUNCTION void ImProcFunctions :: cbdl_local_temp (float ** src, float ** dst,
float ** buffer = dirpyrlo[lastlevel - 1];
for (int level = lastlevel - 1; level > 0; level--) {
idirpyr_eq_channel_loc (dirpyrlo[level], dirpyrlo[level - 1], loctemp, buffer, srcwidth, srcheight, level, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, gamutlab, b_l, t_l, t_r, b_r, choice );
idirpyr_eq_channel_loc(dirpyrlo[level], dirpyrlo[level - 1], loctemp, buffer, srcwidth, srcheight, level, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, gamutlab, b_l, t_l, t_r, b_r, choice);
}
scale = scalesloc[0];
idirpyr_eq_channel_loc (dirpyrlo[0], dst, loctemp, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, gamutlab, b_l, t_l, t_r, b_r, choice );
idirpyr_eq_channel_loc(dirpyrlo[0], dst, loctemp, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, gamutlab, b_l, t_l, t_r, b_r, choice);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#pragma omp parallel for
for (int i = 0; i < srcheight; i++)
for (int j = 0; j < srcwidth; j++) {
dst[i][j] = src[i][j];
loctemp[i][j] = CLIP (buffer[i][j]); // TODO: Really a clip necessary?
loctemp[i][j] = CLIP(buffer[i][j]); // TODO: Really a clip necessary?
// dst[i][j] = CLIP (buffer[i][j]); // TODO: Really a clip necessary?
}
}
void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, float b_l, float t_l, float t_r, int scaleprev)
void ImProcFunctions :: dirpyr_equalizercam(CieImage *ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, float b_l, float t_l, float t_r, int scaleprev)
{
int lastlevel = maxlevel;
if (settings->verbose) {
printf ("CAM dirpyr scaleprev=%i\n", scaleprev);
printf("CAM dirpyr scaleprev=%i\n", scaleprev);
}
float atten123 = (float) settings->level123_cbdl;
@ -406,7 +406,7 @@ void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float
t_l = t_r + 0.55f; //avoid too small range
}
while (fabs (mult[lastlevel - 1] - 1) < 0.001 && lastlevel > 0) {
while (fabs(mult[lastlevel - 1] - 1) < 0.001 && lastlevel > 0) {
lastlevel--;
//printf("last level to process %d \n",lastlevel);
}
@ -420,7 +420,7 @@ void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float
float multi[maxlevel] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f};
float scalefl[maxlevel];
for(int lv = 0; lv < maxlevel; lv++) {
for (int lv = 0; lv < maxlevel; lv++) {
scalefl[lv] = ((float) scales[lv]) / (float) scaleprev;
// if(scalefl[lv] < 1.f) multi[lv] = 1.f; else multi[lv]=(float) mult[lv];
@ -442,34 +442,34 @@ void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float
}
if (settings->verbose) {
printf ("CAM CbDL mult0=%f 1=%f 2=%f 3=%f 4=%f 5=%f\n", multi[0], multi[1], multi[2], multi[3], multi[4], multi[5]);
printf("CAM CbDL mult0=%f 1=%f 2=%f 3=%f 4=%f 5=%f\n", multi[0], multi[1], multi[2], multi[3], multi[4], multi[5]);
}
multi_array2D<float, maxlevel> dirpyrlo (srcwidth, srcheight);
multi_array2D<float, maxlevel> dirpyrlo(srcwidth, srcheight);
level = 0;
int scale = (int) (scales[level]) / scaleprev;
int scale = (int)(scales[level]) / scaleprev;
if (scale < 1) {
scale = 1;
}
dirpyr_channel (src, dirpyrlo[0], srcwidth, srcheight, 0, scale);
dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale);
level = 1;
while (level < lastlevel) {
scale = (int) (scales[level]) / scaleprev;
scale = (int)(scales[level]) / scaleprev;
if (scale < 1) {
scale = 1;
}
dirpyr_channel (dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, scale);
dirpyr_channel(dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, scale);
level ++;
}
@ -479,13 +479,13 @@ void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float
float ** buffer = dirpyrlo[lastlevel - 1];
for (int level = lastlevel - 1; level > 0; level--) {
idirpyr_eq_channelcam (dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold, h_p, C_p, skinprot, b_l, t_l, t_r);
idirpyr_eq_channelcam(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold, h_p, C_p, skinprot, b_l, t_l, t_r);
}
idirpyr_eq_channelcam (dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, h_p, C_p, skinprot, b_l, t_l, t_r);
idirpyr_eq_channelcam(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, h_p, C_p, skinprot, b_l, t_l, t_r);
if(execdir) {
if (execdir) {
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16)
#endif
@ -493,7 +493,7 @@ void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float
for (int i = 0; i < srcheight; i++)
for (int j = 0; j < srcwidth; j++) {
if (ncie->J_p[i][j] > 8.f && ncie->J_p[i][j] < 92.f) {
dst[i][j] = CLIP ( buffer[i][j] ); // TODO: Really a clip necessary?
dst[i][j] = CLIP(buffer[i][j]); // TODO: Really a clip necessary?
} else {
dst[i][j] = src[i][j];
}
@ -501,7 +501,7 @@ void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float
} else {
for (int i = 0; i < srcheight; i++)
for (int j = 0; j < srcwidth; j++) {
dst[i][j] = CLIP ( buffer[i][j] ); // TODO: Really a clip necessary?
dst[i][j] = CLIP(buffer[i][j]); // TODO: Really a clip necessary?
}
}
}
@ -522,7 +522,7 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** da
#endif
{
#ifdef __SSE2__
__m128 thousandv = _mm_set1_ps ( 1000.0f );
__m128 thousandv = _mm_set1_ps(1000.0f);
__m128 dirwtv, valv, normv, dftemp1v, dftemp2v;
// multiplied each value of domkerv by 1000 to avoid multiplication by 1000 inside the loop
float domkerv[5][5][4] ALIGNED16 = {{{1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}}, {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, {{1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}}};
@ -541,10 +541,10 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** da
float norm = 0.f;
for (int inbr = max (0, i - scalewin); inbr <= min (height - 1, i + scalewin); inbr += scale) {
for (int jnbr = max (0, j - scalewin); jnbr <= j + scalewin; jnbr += scale) {
for (int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) {
for (int jnbr = max(0, j - scalewin); jnbr <= j + scalewin; jnbr += scale) {
//printf("i=%d ",(inbr-i)/scale+halfwin);
dirwt = DIRWT (inbr, jnbr, i, j);
dirwt = DIRWT(inbr, jnbr, i, j);
val += dirwt * data_fine[inbr][jnbr];
norm += dirwt;
}
@ -558,29 +558,29 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** da
for (; j < width - scalewin - 3; j += 4) {
valv = _mm_setzero_ps();
normv = _mm_setzero_ps();
dftemp1v = LVFU (data_fine[i][j]);
dftemp1v = LVFU(data_fine[i][j]);
for (int inbr = MAX (0, i - scalewin); inbr <= MIN (height - 1, i + scalewin); inbr += scale) {
for (int inbr = MAX(0, i - scalewin); inbr <= MIN(height - 1, i + scalewin); inbr += scale) {
int indexihlp = (inbr - i) / scale + halfwin;
for (int jnbr = j - scalewin, indexjhlp = 0; jnbr <= j + scalewin; jnbr += scale, indexjhlp++) {
dftemp2v = LVFU (data_fine[inbr][jnbr]);
dirwtv = LVF (domkerv[indexihlp][indexjhlp]) / (vabsf (dftemp1v - dftemp2v) + thousandv);
dftemp2v = LVFU(data_fine[inbr][jnbr]);
dirwtv = LVF(domkerv[indexihlp][indexjhlp]) / (vabsf(dftemp1v - dftemp2v) + thousandv);
valv += dirwtv * dftemp2v;
normv += dirwtv;
}
}
_mm_storeu_ps ( &data_coarse[i][j], valv / normv); //low pass filter
_mm_storeu_ps(&data_coarse[i][j], valv / normv); //low pass filter
}
for (; j < width - scalewin; j++) {
float val = 0.f;
float norm = 0.f;
for (int inbr = max (0, i - scalewin); inbr <= min (height - 1, i + scalewin); inbr += scale) {
for (int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) {
for (int jnbr = j - scalewin; jnbr <= j + scalewin; jnbr += scale) {
dirwt = DIRWT (inbr, jnbr, i, j);
dirwt = DIRWT(inbr, jnbr, i, j);
val += dirwt * data_fine[inbr][jnbr];
norm += dirwt;
}
@ -595,9 +595,9 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** da
float val = 0.f;
float norm = 0.f;
for (int inbr = max (0, i - scalewin); inbr <= min (height - 1, i + scalewin); inbr += scale) {
for (int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) {
for (int jnbr = j - scalewin; jnbr <= j + scalewin; jnbr += scale) {
dirwt = DIRWT (inbr, jnbr, i, j);
dirwt = DIRWT(inbr, jnbr, i, j);
val += dirwt * data_fine[inbr][jnbr];
norm += dirwt;
}
@ -612,9 +612,9 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** da
float val = 0.f;
float norm = 0.f;
for (int inbr = max (0, i - scalewin); inbr <= min (height - 1, i + scalewin); inbr += scale) {
for (int jnbr = j - scalewin; jnbr <= min (width - 1, j + scalewin); jnbr += scale) {
dirwt = DIRWT (inbr, jnbr, i, j);
for (int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) {
for (int jnbr = j - scalewin; jnbr <= min(width - 1, j + scalewin); jnbr += scale) {
dirwt = DIRWT(inbr, jnbr, i, j);
val += dirwt * data_fine[inbr][jnbr];
norm += dirwt;
}
@ -631,7 +631,7 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** da
#endif
{
#ifdef __SSE2__
__m128 thousandv = _mm_set1_ps ( 1000.0f );
__m128 thousandv = _mm_set1_ps(1000.0f);
__m128 dirwtv, valv, normv, dftemp1v, dftemp2v;
#endif // __SSE2__
int j;
@ -647,9 +647,9 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** da
float val = 0.f;
float norm = 0.f;
for (int inbr = max (0, i - scale); inbr <= min (height - 1, i + scale); inbr += scale) {
for (int jnbr = max (0, j - scale); jnbr <= j + scale; jnbr += scale) {
dirwt = RANGEFN (fabsf (data_fine[inbr][jnbr] - data_fine[i][j]));
for (int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) {
for (int jnbr = max(0, j - scale); jnbr <= j + scale; jnbr += scale) {
dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr] - data_fine[i][j]));
val += dirwt * data_fine[inbr][jnbr];
norm += dirwt;
}
@ -663,27 +663,27 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** da
for (; j < width - scale - 3; j += 4) {
valv = _mm_setzero_ps();
normv = _mm_setzero_ps();
dftemp1v = LVFU (data_fine[i][j]);
dftemp1v = LVFU(data_fine[i][j]);
for (int inbr = MAX (0, i - scale); inbr <= MIN (height - 1, i + scale); inbr += scale) {
for (int inbr = MAX(0, i - scale); inbr <= MIN(height - 1, i + scale); inbr += scale) {
for (int jnbr = j - scale; jnbr <= j + scale; jnbr += scale) {
dftemp2v = LVFU (data_fine[inbr][jnbr]);
dirwtv = thousandv / (vabsf (dftemp2v - dftemp1v) + thousandv);
dftemp2v = LVFU(data_fine[inbr][jnbr]);
dirwtv = thousandv / (vabsf(dftemp2v - dftemp1v) + thousandv);
valv += dirwtv * dftemp2v;
normv += dirwtv;
}
}
_mm_storeu_ps ( &data_coarse[i][j], valv / normv); //low pass filter
_mm_storeu_ps(&data_coarse[i][j], valv / normv); //low pass filter
}
for (; j < width - scale; j++) {
float val = 0.f;
float norm = 0.f;
for (int inbr = max (0, i - scale); inbr <= min (height - 1, i + scale); inbr += scale) {
for (int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) {
for (int jnbr = j - scale; jnbr <= j + scale; jnbr += scale) {
dirwt = RANGEFN (fabsf (data_fine[inbr][jnbr] - data_fine[i][j]));
dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr] - data_fine[i][j]));
val += dirwt * data_fine[inbr][jnbr];
norm += dirwt;
}
@ -698,9 +698,9 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** da
float val = 0.f;
float norm = 0.f;
for (int inbr = max (0, i - scale); inbr <= min (height - 1, i + scale); inbr += scale) {
for (int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) {
for (int jnbr = j - scale; jnbr <= j + scale; jnbr += scale) {
dirwt = RANGEFN (fabsf (data_fine[inbr][jnbr] - data_fine[i][j]));
dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr] - data_fine[i][j]));
val += dirwt * data_fine[inbr][jnbr];
norm += dirwt;
}
@ -715,9 +715,9 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** da
float val = 0.f;
float norm = 0.f;
for (int inbr = max (0, i - scale); inbr <= min (height - 1, i + scale); inbr += scale) {
for (int jnbr = j - scale; jnbr <= min (width - 1, j + scale); jnbr += scale) {
dirwt = RANGEFN (fabsf (data_fine[inbr][jnbr] - data_fine[i][j]));
for (int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) {
for (int jnbr = j - scale; jnbr <= min(width - 1, j + scale); jnbr += scale) {
dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr] - data_fine[i][j]));
val += dirwt * data_fine[inbr][jnbr];
norm += dirwt;
}
@ -731,7 +731,7 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** da
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void ImProcFunctions::idirpyr_eq_channel_loc (float ** data_coarse, float ** data_fine, float ** loctemp, float ** buffer, int width, int height, int level, float mult[5], const double dirpyrThreshold, float ** hue, float ** chrom, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice)
void ImProcFunctions::idirpyr_eq_channel_loc(float ** data_coarse, float ** data_fine, float ** loctemp, float ** buffer, int width, int height, int level, float mult[5], const double dirpyrThreshold, float ** hue, float ** chrom, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice)
{
// const float skinprotneg = -skinprot;
// const float factorHard = (1.f - skinprotneg / 100.f);
@ -756,19 +756,19 @@ void ImProcFunctions::idirpyr_eq_channel_loc (float ** data_coarse, float ** dat
// multbis[level] = 1.f + 0.45f * (mult[level] - 1.f);
// }
LUTf irangefn (0x20000);
LUTf irangefn(0x20000);
{
const float noisehi = 1.33f * noise * dirpyrThreshold / expf (level * log (3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf (level * log (3.0));
const float noisehi = 1.33f * noise * dirpyrThreshold / expf(level * log(3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf(level * log(3.0));
//printf("level=%i multlev=%f noisehi=%f noiselo=%f skinprot=%f\n",level,mult[level], noisehi, noiselo, skinprot);
for (int i = 0; i < 0x20000; i++) {
if (abs (i - 0x10000) > noisehi || multbis[level] < 1.0) {
if (abs(i - 0x10000) > noisehi || multbis[level] < 1.0) {
irangefn[i] = multbis[level] + offs;
} else {
if (abs (i - 0x10000) < noiselo) {
if (abs(i - 0x10000) < noiselo) {
irangefn[i] = 1.f + offs ;
} else {
irangefn[i] = 1.f + offs + (multbis[level] - 1.f) * (noisehi - abs (i - 0x10000)) / (noisehi - noiselo + 0.01f) ;
irangefn[i] = 1.f + offs + (multbis[level] - 1.f) * (noisehi - abs(i - 0x10000)) / (noisehi - noiselo + 0.01f) ;
}
}
}
@ -850,19 +850,19 @@ void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fin
multbis[level] = 1.f + 0.45f * (mult[level] - 1.f);
}
LUTf irangefn (0x20000);
LUTf irangefn(0x20000);
{
const float noisehi = 1.33f * noise * dirpyrThreshold / expf (level * log (3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf (level * log (3.0));
const float noisehi = 1.33f * noise * dirpyrThreshold / expf(level * log(3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf(level * log(3.0));
//printf("level=%i multlev=%f noisehi=%f noiselo=%f skinprot=%f\n",level,mult[level], noisehi, noiselo, skinprot);
for (int i = 0; i < 0x20000; i++) {
if (abs (i - 0x10000) > noisehi || multbis[level] < 1.0) {
if (abs(i - 0x10000) > noisehi || multbis[level] < 1.0) {
irangefn[i] = multbis[level] + offs;
} else {
if (abs (i - 0x10000) < noiselo) {
if (abs(i - 0x10000) < noiselo) {
irangefn[i] = 1.f + offs ;
} else {
irangefn[i] = 1.f + offs + (multbis[level] - 1.f) * (noisehi - abs (i - 0x10000)) / (noisehi - noiselo + 0.01f) ;
irangefn[i] = 1.f + offs + (multbis[level] - 1.f) * (noisehi - abs(i - 0x10000)) / (noisehi - noiselo + 0.01f) ;
}
}
}
@ -888,7 +888,7 @@ void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fin
// These values are precalculated now
float modhue = hue[i][j];
float modchro = chrom[i][j];
Color::SkinSatCbdl ((data_fine[i][j]) / 327.68f, modhue, modchro, skinprot, scale, true, b_l, t_l, t_r);
Color::SkinSatCbdl((data_fine[i][j]) / 327.68f, modhue, modchro, skinprot, scale, true, b_l, t_l, t_r);
buffer[i][j] += (1.f + (irangefn[hipass + 0x10000]) * scale) * hipass ;
}
} else
@ -902,7 +902,7 @@ void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fin
// These values are precalculated now
float modhue = hue[i][j];
float modchro = chrom[i][j];
Color::SkinSatCbdl ((data_fine[i][j]) / 327.68f, modhue, modchro, skinprotneg, scale, false, b_l, t_l, t_r);
Color::SkinSatCbdl((data_fine[i][j]) / 327.68f, modhue, modchro, skinprotneg, scale, false, b_l, t_l, t_r);
float correct = irangefn[hipass + 0x10000];
if (scale == 1.f) {//image hard
@ -941,19 +941,19 @@ void ImProcFunctions::idirpyr_eq_channelcam(float ** data_coarse, float ** data_
multbis[level] = 1.f + 0.45f * (mult[level] - 1.f);
}
LUTf irangefn (0x20000);
LUTf irangefn(0x20000);
{
const float noisehi = 1.33f * noise * dirpyrThreshold / expf (level * log (3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf (level * log (3.0));
const float noisehi = 1.33f * noise * dirpyrThreshold / expf(level * log(3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf(level * log(3.0));
//printf("level=%i multlev=%f noisehi=%f noiselo=%f skinprot=%f\n",level,mult[level], noisehi, noiselo, skinprot);
for (int i = 0; i < 0x20000; i++) {
if (abs (i - 0x10000) > noisehi || multbis[level] < 1.0) {
if (abs(i - 0x10000) > noisehi || multbis[level] < 1.0) {
irangefn[i] = multbis[level] + offs;
} else {
if (abs (i - 0x10000) < noiselo) {
if (abs(i - 0x10000) < noiselo) {
irangefn[i] = 1.f + offs ;
} else {
irangefn[i] = 1.f + offs + (multbis[level] - 1.f) * (noisehi - abs (i - 0x10000)) / (noisehi - noiselo + 0.01f) ;
irangefn[i] = 1.f + offs + (multbis[level] - 1.f) * (noisehi - abs(i - 0x10000)) / (noisehi - noiselo + 0.01f) ;
}
}
}
@ -976,7 +976,7 @@ void ImProcFunctions::idirpyr_eq_channelcam(float ** data_coarse, float ** data_
for (int j = 0; j < width; j++) {
float hipass = (data_fine[i][j] - data_coarse[i][j]);
float scale = 1.f;
Color::SkinSatCbdlCam ((data_fine[i][j]) / 327.68f, l_a_h[i][j], l_b_c[i][j], skinprot, scale, true, b_l, t_l, t_r);
Color::SkinSatCbdlCam((data_fine[i][j]) / 327.68f, l_a_h[i][j], l_b_c[i][j], skinprot, scale, true, b_l, t_l, t_r);
buffer[i][j] += (1.f + (irangefn[hipass + 0x10000]) * scale) * hipass ;
}
} else
@ -989,7 +989,7 @@ void ImProcFunctions::idirpyr_eq_channelcam(float ** data_coarse, float ** data_
float scale = 1.f;
float correct;
correct = irangefn[hipass + 0x10000];
Color::SkinSatCbdlCam ((data_fine[i][j]) / 327.68f, l_a_h[i][j], l_b_c[i][j], skinprotneg, scale, false, b_l, t_l, t_r);
Color::SkinSatCbdlCam((data_fine[i][j]) / 327.68f, l_a_h[i][j], l_b_c[i][j], skinprotneg, scale, false, b_l, t_l, t_r);
if (scale == 1.f) {//image hard
buffer[i][j] += (1.f + (correct) * factorHard) * hipass ;

File diff suppressed because it is too large Load Diff

View File

@ -48,11 +48,13 @@
#undef CLIPD
#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f)
namespace {
namespace
{
using namespace rtengine;
// begin of helper function for rgbProc()
void shadowToneCurve(const LUTf &shtonecurve, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize) {
void shadowToneCurve(const LUTf &shtonecurve, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize)
{
#ifdef __SSE2__
vfloat cr = F2V(0.299f);
@ -63,7 +65,8 @@ void shadowToneCurve(const LUTf &shtonecurve, float *rtemp, float *gtemp, float
for (int i = istart, ti = 0; i < tH; i++, ti++) {
int j = jstart, tj = 0;
#ifdef __SSE2__
for (; j < tW - 3; j+=4, tj+=4) {
for (; j < tW - 3; j += 4, tj += 4) {
vfloat rv = LVF(rtemp[ti * tileSize + tj]);
vfloat gv = LVF(gtemp[ti * tileSize + tj]);
@ -76,7 +79,9 @@ void shadowToneCurve(const LUTf &shtonecurve, float *rtemp, float *gtemp, float
STVF(gtemp[ti * tileSize + tj], gv * tonefactorv);
STVF(btemp[ti * tileSize + tj], bv * tonefactorv);
}
#endif
for (; j < tW; j++, tj++) {
float r = rtemp[ti * tileSize + tj];
@ -93,7 +98,8 @@ void shadowToneCurve(const LUTf &shtonecurve, float *rtemp, float *gtemp, float
}
}
void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize, float exp_scale, float comp, float hlrange) {
void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize, float exp_scale, float comp, float hlrange)
{
#ifdef __SSE2__
vfloat threev = F2V(3.f);
@ -103,7 +109,8 @@ void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, flo
for (int i = istart, ti = 0; i < tH; i++, ti++) {
int j = jstart, tj = 0;
#ifdef __SSE2__
for (; j < tW - 3; j+=4, tj+=4) {
for (; j < tW - 3; j += 4, tj += 4) {
vfloat rv = LVF(rtemp[ti * tileSize + tj]);
vfloat gv = LVF(gtemp[ti * tileSize + tj]);
@ -112,14 +119,15 @@ void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, flo
//TODO: proper treatment of out-of-gamut colors
//float tonefactor = hltonecurve[(0.299f*r+0.587f*g+0.114f*b)];
vmask maxMask = vmaskf_ge(vmaxf(rv, vmaxf(gv, bv)), maxvalfv);
if(_mm_movemask_ps((vfloat)maxMask)) {
if (_mm_movemask_ps((vfloat)maxMask)) {
for (int k = 0; k < 4; ++k) {
float r = rtemp[ti * tileSize + tj + k];
float g = gtemp[ti * tileSize + tj + k];
float b = btemp[ti * tileSize + tj + k];
float tonefactor = ((r < MAXVALF ? hltonecurve[r] : CurveFactory::hlcurve (exp_scale, comp, hlrange, r) ) +
(g < MAXVALF ? hltonecurve[g] : CurveFactory::hlcurve (exp_scale, comp, hlrange, g) ) +
(b < MAXVALF ? hltonecurve[b] : CurveFactory::hlcurve (exp_scale, comp, hlrange, b) ) ) / 3.0;
float tonefactor = ((r < MAXVALF ? hltonecurve[r] : CurveFactory::hlcurve(exp_scale, comp, hlrange, r)) +
(g < MAXVALF ? hltonecurve[g] : CurveFactory::hlcurve(exp_scale, comp, hlrange, g)) +
(b < MAXVALF ? hltonecurve[b] : CurveFactory::hlcurve(exp_scale, comp, hlrange, b))) / 3.0;
// note: tonefactor includes exposure scaling, that is here exposure slider and highlight compression takes place
rtemp[ti * tileSize + tj + k] = r * tonefactor;
@ -134,7 +142,9 @@ void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, flo
STVF(btemp[ti * tileSize + tj], bv * tonefactorv);
}
}
#endif
for (; j < tW; j++, tj++) {
float r = rtemp[ti * tileSize + tj];
@ -143,9 +153,9 @@ void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, flo
//TODO: proper treatment of out-of-gamut colors
//float tonefactor = hltonecurve[(0.299f*r+0.587f*g+0.114f*b)];
float tonefactor = ((r < MAXVALF ? hltonecurve[r] : CurveFactory::hlcurve (exp_scale, comp, hlrange, r) ) +
(g < MAXVALF ? hltonecurve[g] : CurveFactory::hlcurve (exp_scale, comp, hlrange, g) ) +
(b < MAXVALF ? hltonecurve[b] : CurveFactory::hlcurve (exp_scale, comp, hlrange, b) ) ) / 3.0;
float tonefactor = ((r < MAXVALF ? hltonecurve[r] : CurveFactory::hlcurve(exp_scale, comp, hlrange, r)) +
(g < MAXVALF ? hltonecurve[g] : CurveFactory::hlcurve(exp_scale, comp, hlrange, g)) +
(b < MAXVALF ? hltonecurve[b] : CurveFactory::hlcurve(exp_scale, comp, hlrange, b))) / 3.0;
// note: tonefactor includes exposure scaling, that is here exposure slider and highlight compression takes place
rtemp[ti * tileSize + tj] = r * tonefactor;
@ -155,30 +165,36 @@ void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, flo
}
}
void proPhotoBlue(float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize) {
void proPhotoBlue(float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize)
{
// this is a hack to avoid the blue=>black bug (Issue 2141)
for (int i = istart, ti = 0; i < tH; i++, ti++) {
int j = jstart, tj = 0;
#ifdef __SSE2__
for (; j < tW - 3; j+=4, tj+=4) {
for (; j < tW - 3; j += 4, tj += 4) {
vfloat rv = LVF(rtemp[ti * tileSize + tj]);
vfloat gv = LVF(gtemp[ti * tileSize + tj]);
vmask zeromask = vorm(vmaskf_eq(rv, ZEROV), vmaskf_eq(gv, ZEROV));
if(_mm_movemask_ps((vfloat)zeromask)) {
if (_mm_movemask_ps((vfloat)zeromask)) {
for (int k = 0; k < 4; ++k) {
float r = rtemp[ti * tileSize + tj + k];
float g = gtemp[ti * tileSize + tj + k];
if (r == 0.0f || g == 0.0f) {
float b = btemp[ti * tileSize + tj + k];
float h, s, v;
Color::rgb2hsv (r, g, b, h, s, v);
Color::rgb2hsv(r, g, b, h, s, v);
s *= 0.99f;
Color::hsv2rgb (h, s, v, rtemp[ti * tileSize + tj + k], gtemp[ti * tileSize + tj + k], btemp[ti * tileSize + tj + k]);
Color::hsv2rgb(h, s, v, rtemp[ti * tileSize + tj + k], gtemp[ti * tileSize + tj + k], btemp[ti * tileSize + tj + k]);
}
}
}
}
#endif
for (; j < tW; j++, tj++) {
float r = rtemp[ti * tileSize + tj];
float g = gtemp[ti * tileSize + tj];
@ -186,77 +202,79 @@ void proPhotoBlue(float *rtemp, float *gtemp, float *btemp, int istart, int tH,
if (r == 0.0f || g == 0.0f) {
float b = btemp[ti * tileSize + tj];
float h, s, v;
Color::rgb2hsv (r, g, b, h, s, v);
Color::rgb2hsv(r, g, b, h, s, v);
s *= 0.99f;
Color::hsv2rgb (h, s, v, rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj]);
Color::hsv2rgb(h, s, v, rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj]);
}
}
}
}
void customToneCurve(const ToneCurve &customToneCurve, ToneCurveParams::TcMode curveMode, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize, PerceptualToneCurveState ptcApplyState) {
void customToneCurve(const ToneCurve &customToneCurve, ToneCurveParams::TcMode curveMode, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize, PerceptualToneCurveState ptcApplyState)
{
if (curveMode == ToneCurveParams::TcMode::STD) { // Standard
for (int i = istart, ti = 0; i < tH; i++, ti++) {
const StandardToneCurve& userToneCurve = static_cast<const StandardToneCurve&> (customToneCurve);
userToneCurve.BatchApply (
0, tW - jstart,
&rtemp[ti * tileSize], &gtemp[ti * tileSize], &btemp[ti * tileSize]);
const StandardToneCurve& userToneCurve = static_cast<const StandardToneCurve&>(customToneCurve);
userToneCurve.BatchApply(
0, tW - jstart,
&rtemp[ti * tileSize], &gtemp[ti * tileSize], &btemp[ti * tileSize]);
}
} else if (curveMode == ToneCurveParams::TcMode::FILMLIKE) { // Adobe like
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
const AdobeToneCurve& userToneCurve = static_cast<const AdobeToneCurve&> (customToneCurve);
userToneCurve.Apply (rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj]);
const AdobeToneCurve& userToneCurve = static_cast<const AdobeToneCurve&>(customToneCurve);
userToneCurve.Apply(rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj]);
}
}
} else if (curveMode == ToneCurveParams::TcMode::SATANDVALBLENDING) { // apply the curve on the saturation and value channels
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
const SatAndValueBlendingToneCurve& userToneCurve = static_cast<const SatAndValueBlendingToneCurve&> (customToneCurve);
const SatAndValueBlendingToneCurve& userToneCurve = static_cast<const SatAndValueBlendingToneCurve&>(customToneCurve);
rtemp[ti * tileSize + tj] = CLIP<float> (rtemp[ti * tileSize + tj]);
gtemp[ti * tileSize + tj] = CLIP<float> (gtemp[ti * tileSize + tj]);
btemp[ti * tileSize + tj] = CLIP<float> (btemp[ti * tileSize + tj]);
userToneCurve.Apply (rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj]);
userToneCurve.Apply(rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj]);
}
}
} else if (curveMode == ToneCurveParams::TcMode::WEIGHTEDSTD) { // apply the curve to the rgb channels, weighted
const WeightedStdToneCurve& userToneCurve = static_cast<const WeightedStdToneCurve&> (customToneCurve);
const WeightedStdToneCurve& userToneCurve = static_cast<const WeightedStdToneCurve&>(customToneCurve);
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
rtemp[ti * tileSize + tj] = CLIP<float> (rtemp[ti * tileSize + tj]);
gtemp[ti * tileSize + tj] = CLIP<float> (gtemp[ti * tileSize + tj]);
btemp[ti * tileSize + tj] = CLIP<float> (btemp[ti * tileSize + tj]);
userToneCurve.Apply (rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj]);
userToneCurve.Apply(rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj]);
}
}
} else if (curveMode == ToneCurveParams::TcMode::LUMINANCE) { // apply the curve to the luminance channel
const LuminanceToneCurve& userToneCurve = static_cast<const LuminanceToneCurve&> (customToneCurve);
const LuminanceToneCurve& userToneCurve = static_cast<const LuminanceToneCurve&>(customToneCurve);
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
rtemp[ti * tileSize + tj] = CLIP<float> (rtemp[ti * tileSize + tj]);
gtemp[ti * tileSize + tj] = CLIP<float> (gtemp[ti * tileSize + tj]);
btemp[ti * tileSize + tj] = CLIP<float> (btemp[ti * tileSize + tj]);
userToneCurve.Apply (rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj]);
userToneCurve.Apply(rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj]);
}
}
} else if (curveMode == ToneCurveParams::TcMode::PERCEPTUAL) { // apply curve while keeping color appearance constant
const PerceptualToneCurve& userToneCurve = static_cast<const PerceptualToneCurve&> (customToneCurve);
const PerceptualToneCurve& userToneCurve = static_cast<const PerceptualToneCurve&>(customToneCurve);
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
rtemp[ti * tileSize + tj] = CLIP<float> (rtemp[ti * tileSize + tj]);
gtemp[ti * tileSize + tj] = CLIP<float> (gtemp[ti * tileSize + tj]);
btemp[ti * tileSize + tj] = CLIP<float> (btemp[ti * tileSize + tj]);
userToneCurve.Apply (rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj], ptcApplyState);
userToneCurve.Apply(rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj], ptcApplyState);
}
}
}
}
void fillEditFloat(float *editIFloatTmpR, float *editIFloatTmpG, float *editIFloatTmpB, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize) {
void fillEditFloat(float *editIFloatTmpR, float *editIFloatTmpG, float *editIFloatTmpB, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize)
{
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
editIFloatTmpR[ti * tileSize + tj] = Color::gamma2curve[rtemp[ti * tileSize + tj]] / 65535.f;
@ -1919,7 +1937,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb
// level of adaptation
const float deg = (params->colorappearance.degree) / 100.0f;
const float pilot = params->colorappearance.autodegree ? 2.0f : deg;
const float degout = (params->colorappearance.degreeout) / 100.0f;
const float pilotout = params->colorappearance.autodegreeout ? 2.0f : degout;
@ -3378,7 +3396,7 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer
};
bool mixchannels = params->chmixer.enabled &&
(params->chmixer.red[0] != 100 || params->chmixer.red[1] != 0 || params->chmixer.red[2] != 0 ||
(params->chmixer.red[0] != 100 || params->chmixer.red[1] != 0 || params->chmixer.red[2] != 0 ||
params->chmixer.green[0] != 0 || params->chmixer.green[1] != 100 || params->chmixer.green[2] != 0 ||
params->chmixer.blue[0] != 0 || params->chmixer.blue[1] != 0 || params->chmixer.blue[2] != 100);
@ -3387,10 +3405,10 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer
FlatCurve* vCurve = nullptr;
FlatCurve* bwlCurve = nullptr;
FlatCurveType hCurveType = (FlatCurveType)params->hsvequalizer.hcurve.at (0);
FlatCurveType sCurveType = (FlatCurveType)params->hsvequalizer.scurve.at (0);
FlatCurveType vCurveType = (FlatCurveType)params->hsvequalizer.vcurve.at (0);
FlatCurveType bwlCurveType = (FlatCurveType)params->blackwhite.luminanceCurve.at (0);
FlatCurveType hCurveType = (FlatCurveType)params->hsvequalizer.hcurve.at(0);
FlatCurveType sCurveType = (FlatCurveType)params->hsvequalizer.scurve.at(0);
FlatCurveType vCurveType = (FlatCurveType)params->hsvequalizer.vcurve.at(0);
FlatCurveType bwlCurveType = (FlatCurveType)params->blackwhite.luminanceCurve.at(0);
bool hCurveEnabled = params->hsvequalizer.enabled && hCurveType > FCT_Linear;
bool sCurveEnabled = params->hsvequalizer.enabled && sCurveType > FCT_Linear;
bool vCurveEnabled = params->hsvequalizer.enabled && vCurveType > FCT_Linear;
@ -3642,7 +3660,7 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer
#pragma omp parallel if (multiThread)
#endif
{
size_t perChannelSizeBytes = padToAlignment(sizeof (float) * TS * TS + 4 * 64);
size_t perChannelSizeBytes = padToAlignment(sizeof(float) * TS * TS + 4 * 64);
AlignedBuffer<float> buffer(3 * perChannelSizeBytes);
char *editIFloatBuffer = nullptr;
char *editWhateverBuffer = nullptr;
@ -3661,8 +3679,8 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer
float *editIFloatTmpR = nullptr, *editIFloatTmpG = nullptr, *editIFloatTmpB = nullptr, *editWhateverTmp = nullptr;
if (editImgFloat) {
editIFloatBuffer = (char *) malloc (3 * sizeof (float) * TS * TS + 20 * 64 + 63);
char *data = (char*) ( ( uintptr_t (editIFloatBuffer) + uintptr_t (63)) / 64 * 64);
editIFloatBuffer = (char *) malloc(3 * sizeof(float) * TS * TS + 20 * 64 + 63);
char *data = (char*)((uintptr_t (editIFloatBuffer) + uintptr_t (63)) / 64 * 64);
editIFloatTmpR = (float (*))data;
editIFloatTmpG = (float (*))((char*)editIFloatTmpR + sizeof(float) * TS * TS + 4 * 64);
@ -3670,8 +3688,8 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer
}
if (editWhatever) {
editWhateverBuffer = (char *) malloc (sizeof (float) * TS * TS + 20 * 64 + 63);
char *data = (char*) ( ( uintptr_t (editWhateverBuffer) + uintptr_t (63)) / 64 * 64);
editWhateverBuffer = (char *) malloc(sizeof(float) * TS * TS + 20 * 64 + 63);
char *data = (char*)((uintptr_t (editWhateverBuffer) + uintptr_t (63)) / 64 * 64);
editWhateverTmp = (float (*))data;
}
@ -3790,13 +3808,16 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer
for (int i = istart, ti = 0; i < tH; i++, ti++) {
int j = jstart, tj = 0;
#ifdef __SSE2__
for (; j < tW - 3; j+=4, tj+=4) {
for (; j < tW - 3; j += 4, tj += 4) {
//brightness/contrast
STVF(rtemp[ti * TS + tj], tonecurve(LVF(rtemp[ti * TS + tj])));
STVF(gtemp[ti * TS + tj], tonecurve(LVF(gtemp[ti * TS + tj])));
STVF(btemp[ti * TS + tj], tonecurve(LVF(btemp[ti * TS + tj])));
}
#endif
for (; j < tW; j++, tj++) {
//brightness/contrast
rtemp[ti * TS + tj] = tonecurve[rtemp[ti * TS + tj]];
@ -4534,15 +4555,16 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer
// filling the pipette buffer by the content of the temp pipette buffers
if (editImgFloat) {
editImgFloat->r (i, j) = editIFloatTmpR[ti * TS + tj];
editImgFloat->g (i, j) = editIFloatTmpG[ti * TS + tj];
editImgFloat->b (i, j) = editIFloatTmpB[ti * TS + tj];
editImgFloat->r(i, j) = editIFloatTmpR[ti * TS + tj];
editImgFloat->g(i, j) = editIFloatTmpG[ti * TS + tj];
editImgFloat->b(i, j) = editIFloatTmpB[ti * TS + tj];
} else if (editWhatever) {
editWhatever->v (i, j) = editWhateverTmp[ti * TS + tj];
editWhatever->v(i, j) = editWhateverTmp[ti * TS + tj];
}
}
}
}
// ready, fill lab
for (int i = istart, ti = 0; i < tH; i++, ti++) {
Color::RGB2Lab(&rtemp[ti * TS], &gtemp[ti * TS], &btemp[ti * TS], &(lab->L[i][jstart]), &(lab->a[i][jstart]), &(lab->b[i][jstart]), toxyz, tW - jstart);
@ -5607,7 +5629,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve(PipetteBuffer *pipetteBuf
if (!params->labCurve.enabled) {
return;
}
int W = lold->W;
int H = lold->H;
// lhskcurve.dump("lh_curve");

View File

@ -3987,7 +3987,7 @@ void ImProcFunctions::InverseReti_Local(const struct local_params & lp, LabImage
if (lp.shapmet == 0) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
} else if (lp.shapmet == 1) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
calcTransitionrect(lox, loy, ach, lp, zone, localFactor);
}
// calcTransition(lox, loy, ach, lp, zone, localFactor);
@ -4493,7 +4493,7 @@ void ImProcFunctions::InverseBlurNoise_Local(const struct local_params & lp, Lab
if (lp.shapmet == 0) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
} else if (lp.shapmet == 1) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
calcTransitionrect(lox, loy, ach, lp, zone, localFactor);
}
// calcTransition(lox, loy, ach, lp, zone, localFactor);
@ -5057,7 +5057,7 @@ void ImProcFunctions::InverseContrast_Local(float ave, struct local_contra & lco
if (lp.shapmet == 0) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
} else if (lp.shapmet == 1) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
calcTransitionrect(lox, loy, ach, lp, zone, localFactor);
}
// calcTransition(lox, loy, ach, lp, zone, localFactor);
@ -5365,7 +5365,7 @@ void ImProcFunctions::InverseSharp_Local(float **loctemp, const float hueplus, c
if (lp.shapmet == 0) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
} else if (lp.shapmet == 1) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
calcTransitionrect(lox, loy, ach, lp, zone, localFactor);
}
// calcTransition(lox, loy, ach, lp, zone, localFactor);
@ -7607,7 +7607,7 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, La
if (lp.shapmet == 0) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
} else if (lp.shapmet == 1) {
calcTransition(lox, loy, ach, lp, zone, localFactor);//rect not good
calcTransitionrect(lox, loy, ach, lp, zone, localFactor);//rect not good
}
// calcTransition(lox, loy, ach, lp, zone, localFactor);
@ -12023,7 +12023,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
tmpl = new LabImage(Wd, Hd);
} /* else {
} else {
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16)
@ -12035,11 +12035,11 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
orig1[ir][jr] = transformed->L[ir][jr];
}
tmpl = new LabImage (transformed->W, transformed->H);
tmpl = new LabImage(transformed->W, transformed->H);
}
*/
float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax;
ImProcFunctions::MSRLocal(orig, tmpl->L, orig1, Wd, Hd, params->locallab, sk, locRETgainCcurve, 0, 4, 0.8f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax);
#ifdef _OPENMP
@ -12093,7 +12093,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
orig1[ir][jr] = sqrt(SQR(bufreti->a[ir][jr]) + SQR(bufreti->b[ir][jr]));
}
} /* else {
} else {
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16)
@ -12101,11 +12101,11 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
for (int ir = 0; ir < GH; ir += 1)
for (int jr = 0; jr < GW; jr += 1) {
orig[ir][jr] = sqrt (SQR (original->a[ir][jr]) + SQR (original->b[ir][jr]));
orig1[ir][jr] = sqrt (SQR (transformed->a[ir][jr]) + SQR (transformed->b[ir][jr]));
orig[ir][jr] = sqrt(SQR(original->a[ir][jr]) + SQR(original->b[ir][jr]));
orig1[ir][jr] = sqrt(SQR(transformed->a[ir][jr]) + SQR(transformed->b[ir][jr]));
}
}
*/
ImProcFunctions::MSRLocal(orig, tmpl->L, orig1, Wd, Hd, params->locallab, sk, locRETgainCcurve, 1, 4, 0.8f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax);
if (!lp.invret && call <= 3) {
@ -12146,7 +12146,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
// printf ("minch=%2.2f maxch=%2.2f", minch, maxch);
} /* else {
} else {
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16)
@ -12163,7 +12163,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
}
}
*/
if (!lp.invret) {

View File

@ -52,10 +52,10 @@
namespace
{
void retinex_scales ( float* scales, int nscales, int mode, int s, float high)
void retinex_scales(float* scales, int nscales, int mode, int s, float high)
{
if ( nscales == 1 ) {
scales[0] = (float)s / 2.f;
if (nscales == 1) {
scales[0] = (float)s / 2.f;
} else if (nscales == 2) {
scales[1] = (float) s / 2.f;
scales[0] = (float) s;
@ -63,32 +63,32 @@ void retinex_scales ( float* scales, int nscales, int mode, int s, float high)
float size_step = (float) s / (float) nscales;
if (mode == 0) {
for (int i = 0; i < nscales; ++i ) {
for (int i = 0; i < nscales; ++i) {
scales[nscales - i - 1] = 2.0f + (float)i * size_step;
}
} else if (mode == 1) {
size_step = (float)log (s - 2.0f) / (float) nscales;
size_step = (float)log(s - 2.0f) / (float) nscales;
for (int i = 0; i < nscales; ++i ) {
scales[nscales - i - 1] = 2.0f + (float)pow (10.f, (i * size_step) / log (10.f));
for (int i = 0; i < nscales; ++i) {
scales[nscales - i - 1] = 2.0f + (float)pow(10.f, (i * size_step) / log(10.f));
}
} else if (mode == 2) {
size_step = (float) log (s - 2.0f) / (float) nscales;
size_step = (float) log(s - 2.0f) / (float) nscales;
for ( int i = 0; i < nscales; ++i ) {
scales[i] = s - (float)pow (10.f, (i * size_step) / log (10.f));
for (int i = 0; i < nscales; ++i) {
scales[i] = s - (float)pow(10.f, (i * size_step) / log(10.f));
}
} else if (mode == 3) {
size_step = (float) log (s - 2.0f) / (float) nscales;
size_step = (float) log(s - 2.0f) / (float) nscales;
for ( int i = 0; i < nscales; ++i ) {
scales[i] = high * s - (float)pow (10.f, (i * size_step) / log (10.f));
for (int i = 0; i < nscales; ++i) {
scales[i] = high * s - (float)pow(10.f, (i * size_step) / log(10.f));
}
}
}
}
void mean_stddv2 ( float **dst, float &mean, float &stddv, int W_L, int H_L, float &maxtr, float &mintr)
void mean_stddv2(float **dst, float &mean, float &stddv, int W_L, int H_L, float &maxtr, float &mintr)
{
// summation using double precision to avoid too large summation error for large pictures
double vsquared = 0.f;
@ -104,7 +104,7 @@ void mean_stddv2 ( float **dst, float &mean, float &stddv, int W_L, int H_L, flo
#pragma omp for reduction(+:sum,vsquared) nowait // this leads to differences, but parallel summation is more accurate
#endif
for (int i = 0; i < H_L; i++ )
for (int i = 0; i < H_L; i++)
for (int j = 0; j < W_L; j++) {
sum += dst[i][j];
vsquared += (dst[i][j] * dst[i][j]);
@ -122,10 +122,10 @@ void mean_stddv2 ( float **dst, float &mean, float &stddv, int W_L, int H_L, flo
}
}
mean = sum / (double) (W_L * H_L);
mean = sum / (double)(W_L * H_L);
vsquared /= (double) W_L * H_L;
stddv = ( vsquared - (mean * mean) );
stddv = (float)sqrt (stddv);
stddv = (vsquared - (mean * mean));
stddv = (float)sqrt(stddv);
}
}
@ -148,13 +148,13 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
int iter = deh.iter;
int gradient = deh.scal;
int scal = 3;//disabled scal
int nei = (int) (2.8f * deh.neigh); //def = 220
int nei = (int)(2.8f * deh.neigh); //def = 220
float vart = (float)deh.vart / 100.f;//variance
float gradvart = (float)deh.grad;
float gradstr = (float)deh.grads;
float strength = (float) deh.str / 100.f; // Blend with original L channel data
float limD = (float) deh.limd;
limD = pow (limD, 1.7f); //about 2500 enough
limD = pow(limD, 1.7f); //about 2500 enough
limD *= useHslLin ? 10.f : 1.f;
float ilimD = 1.f / limD;
float hig = ((float) deh.highl) / 100.f;
@ -169,7 +169,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
constexpr float elogt = 2.71828f;
bool lhutili = false;
FlatCurve* shcurve = new FlatCurve (deh.lhcurve); //curve L=f(H)
FlatCurve* shcurve = new FlatCurve(deh.lhcurve); //curve L=f(H)
if (!shcurve || shcurve->isIdentity()) {
if (shcurve) {
@ -287,7 +287,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
}
}
scal = round (sc);
scal = round(sc);
float ks = 1.f;
if (gradstr != 0) {
@ -323,7 +323,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
constexpr auto maxRetinexScales = 8;
float RetinexScales[maxRetinexScales];
retinex_scales ( RetinexScales, scal, moderetinex, nei / grad, high );
retinex_scales(RetinexScales, scal, moderetinex, nei / grad, high);
float *src[H_L] ALIGNED16;
float *srcBuffer = new float[H_L * W_L];
@ -386,29 +386,29 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
}
}
const float logBetaGain = xlogf (16384.f);
const float logBetaGain = xlogf(16384.f);
float pond = logBetaGain / (float) scal;
if (!useHslLin) {
pond /= log (elogt);
pond /= log(elogt);
}
auto shmap = ((mapmet == 2 || mapmet == 3 || mapmet == 4) && it == 1) ? new SHMap (W_L, H_L, true) : nullptr;
auto shmap = ((mapmet == 2 || mapmet == 3 || mapmet == 4) && it == 1) ? new SHMap(W_L, H_L, true) : nullptr;
float *buffer = new float[W_L * H_L];;
for ( int scale = scal - 1; scale >= 0; scale-- ) {
for (int scale = scal - 1; scale >= 0; scale--) {
#ifdef _OPENMP
#pragma omp parallel
#endif
{
if (scale == scal - 1)
{
gaussianBlur (src, out, W_L, H_L, RetinexScales[scale], buffer);
} else { // reuse result of last iteration
gaussianBlur(src, out, W_L, H_L, RetinexScales[scale], buffer);
} else // reuse result of last iteration
{
// out was modified in last iteration => restore it
if ((((mapmet == 2 && scale > 1) || mapmet == 3 || mapmet == 4) || (mapmet > 0 && mapcontlutili)) && it == 1)
{
if ((((mapmet == 2 && scale > 1) || mapmet == 3 || mapmet == 4) || (mapmet > 0 && mapcontlutili)) && it == 1) {
#ifdef _OPENMP
#pragma omp for
#endif
@ -420,8 +420,9 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
}
}
gaussianBlur (out, out, W_L, H_L, sqrtf (SQR (RetinexScales[scale]) - SQR (RetinexScales[scale + 1])), buffer);
gaussianBlur(out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), buffer);
}
if ((((mapmet == 2 && scale > 2) || mapmet == 3 || mapmet == 4) || (mapmet > 0 && mapcontlutili)) && it == 1 && scale > 0)
{
// out will be modified => store it for use in next iteration. We even don't need a new buffer because 'buffer' is free after gaussianBlur :)
@ -438,15 +439,15 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
}
if (((mapmet == 2 && scale > 2) || mapmet == 3 || mapmet == 4) && it == 1) {
shmap->updateL (out, shradius, true, 1);
shmap->updateL(out, shradius, true, 1);
h_th = shmap->max_f - deh.htonalwidth * (shmap->max_f - shmap->avg) / 100;
s_th = deh.stonalwidth * (shmap->avg - shmap->min_f) / 100;
}
#ifdef __SSE2__
vfloat pondv = F2V (pond);
vfloat limMinv = F2V (ilimdx);
vfloat limMaxv = F2V (limdx);
vfloat pondv = F2V(pond);
vfloat limMinv = F2V(ilimdx);
vfloat limMaxv = F2V(limdx);
#endif
@ -504,11 +505,11 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
if (useHslLin) {
for (; j < W_L - 3; j += 4) {
_mm_storeu_ps (&luminance[i][j], LVFU (luminance[i][j]) + pondv * (LIMV (LVFU (src[i][j]) / LVFU (out[i][j]), limMinv, limMaxv) ));
_mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * (LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv)));
}
} else {
for (; j < W_L - 3; j += 4) {
_mm_storeu_ps (&luminance[i][j], LVFU (luminance[i][j]) + pondv * xlogf (LIMV (LVFU (src[i][j]) / LVFU (out[i][j]), limMinv, limMaxv) ));
_mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * xlogf(LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv)));
}
}
@ -516,11 +517,11 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
if (useHslLin) {
for (; j < W_L; j++) {
luminance[i][j] += pond * (LIM (src[i][j] / out[i][j], ilimdx, limdx));
luminance[i][j] += pond * (LIM(src[i][j] / out[i][j], ilimdx, limdx));
}
} else {
for (; j < W_L; j++) {
luminance[i][j] += pond * xlogf (LIM (src[i][j] / out[i][j], ilimdx, limdx)); // /logt ?
luminance[i][j] += pond * xlogf(LIM(src[i][j] / out[i][j], ilimdx, limdx)); // /logt ?
}
}
}
@ -541,7 +542,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
float stddv = 0.f;
// I call mean_stddv2 instead of mean_stddv ==> logBetaGain
mean_stddv2 ( luminance, mean, stddv, W_L, H_L, maxtr, mintr);
mean_stddv2(luminance, mean, stddv, W_L, H_L, maxtr, mintr);
//printf("mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", mean, stddv, delta, maxtr, mintr);
//mean_stddv( luminance, mean, stddv, W_L, H_L, logBetaGain, maxtr, mintr);
@ -569,9 +570,9 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
#pragma omp for schedule(dynamic,16)
#endif
for (int i = 0; i < H_L; i++ )
for (int i = 0; i < H_L; i++)
for (int j = 0; j < W_L; j++) { //for mintr to maxtr evalate absciss in function of original transmission
if (LIKELY (fabsf (luminance[i][j] - mean) < stddv)) {
if (LIKELY(fabsf(luminance[i][j] - mean) < stddv)) {
absciss = asig * luminance[i][j] + bsig;
} else if (luminance[i][j] >= mean) {
absciss = amax * luminance[i][j] + bmax;
@ -606,7 +607,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
for (int i = borderL; i < hei - borderL; i++) {
for (int j = borderL; j < wid - borderL; j++) {
tmL[i][j] = median (luminance[i][j], luminance[i - 1][j], luminance[i + 1][j], luminance[i][j + 1], luminance[i][j - 1], luminance[i - 1][j - 1], luminance[i - 1][j + 1], luminance[i + 1][j - 1], luminance[i + 1][j + 1]); //3x3
tmL[i][j] = median(luminance[i][j], luminance[i - 1][j], luminance[i + 1][j], luminance[i][j + 1], luminance[i][j - 1], luminance[i - 1][j - 1], luminance[i - 1][j + 1], luminance[i + 1][j - 1], luminance[i + 1][j + 1]); //3x3
}
}
@ -614,7 +615,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
#pragma omp parallel for
#endif
for (int i = borderL; i < hei - borderL; i++ ) {
for (int i = borderL; i < hei - borderL; i++) {
for (int j = borderL; j < wid - borderL; j++) {
luminance[i][j] = tmL[i][j];
}
@ -626,7 +627,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
// I call mean_stddv2 instead of mean_stddv ==> logBetaGain
//mean_stddv( luminance, mean, stddv, W_L, H_L, 1.f, maxtr, mintr);
mean_stddv2 ( luminance, mean, stddv, W_L, H_L, maxtr, mintr);
mean_stddv2(luminance, mean, stddv, W_L, H_L, maxtr, mintr);
}
@ -647,7 +648,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
float delta = maxi - mini;
//printf("maxi=%f mini=%f mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", maxi, mini, mean, stddv, delta, maxtr, mintr);
if ( !delta ) {
if (!delta) {
delta = 1.0f;
}
@ -675,7 +676,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
stddv = 0.f;
// I call mean_stddv2 instead of mean_stddv ==> logBetaGain
mean_stddv2 ( luminance, mean, stddv, W_L, H_L, maxtr, mintr);
mean_stddv2(luminance, mean, stddv, W_L, H_L, maxtr, mintr);
float asig = 0.f, bsig = 0.f, amax = 0.f, bmax = 0.f, amin = 0.f, bmin = 0.f;
if (dehagaintransmissionCurve && mean != 0.f && stddv != 0.f) { //if curve
@ -703,14 +704,14 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
#pragma omp for schedule(dynamic,16) nowait
#endif
for ( int i = 0; i < H_L; i ++ )
for (int i = 0; i < H_L; i ++)
for (int j = 0; j < W_L; j++) {
float gan;
if (dehagaintransmissionCurve && mean != 0.f && stddv != 0.f) {
float absciss;
if (LIKELY (fabsf (luminance[i][j] - mean) < stddv)) {
if (LIKELY(fabsf(luminance[i][j] - mean) < stddv)) {
absciss = asig * luminance[i][j] + bsig;
} else if (luminance[i][j] >= mean) {
absciss = amax * luminance[i][j] + bmax;
@ -726,7 +727,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
gan = 0.5f;
}
float cd = gan * cdfactor * ( luminance[i][j] ) + offse;
float cd = gan * cdfactor * (luminance[i][j]) + offse;
cdmax = cd > cdmax ? cd : cdmax;
cdmin = cd < cdmin ? cd : cdmin;
@ -739,9 +740,9 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
float valparam;
if (useHsl || useHslLin) {
valparam = float ((shcurve->getVal (HH) - 0.5f));
valparam = float ((shcurve->getVal(HH) - 0.5f));
} else {
valparam = float ((shcurve->getVal (Color::huelab_to_huehsv2 (HH)) - 0.5f));
valparam = float ((shcurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f));
}
str *= (1.f + 2.f * valparam);
@ -753,7 +754,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
}
if (viewmet == 0) {
luminance[i][j] = intp (str, clipretinex ( cd, 0.f, 32768.f ), originalLuminance[i][j]);
luminance[i][j] = intp(str, clipretinex(cd, 0.f, 32768.f), originalLuminance[i][j]);
} else if (viewmet == 1) {
luminance[i][j] = out[i][j];
} else if (viewmet == 4) {
@ -801,7 +802,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
}
}
void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* const *originalLuminance, const int width, const int height, const LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const int chrome, const int scall, const float krad, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax)
void ImProcFunctions::MSRLocal(float** luminance, float** templ, const float* const *originalLuminance, const int width, const int height, const LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const int chrome, const int scall, const float krad, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax)
{
BENCHFUN
bool py = true;
@ -813,24 +814,24 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
// constexpr bool useHsl = false; //never used
constexpr bool useHslLin = false;//never used
const float offse = 0.f; //loc.offs;
const float chrT = (float) (loc.chrrt) / 100.f;
const float chrT = (float)(loc.chrrt) / 100.f;
const int scal = scall;//3;//loc.scale;;
const float vart = loc.vart / 100.f;//variance
const float strength = loc.str / 100.f; // Blend with original L channel data
float limD = 10.f;//(float) loc.limd;
limD = pow (limD, 1.7f); //about 2500 enough
limD = pow(limD, 1.7f); //about 2500 enough
//limD *= useHslLin ? 10.f : 1.f;
float ilimD = 1.f / limD;
const float elogt = 2.71828f;
//empirical skip evaluation : very difficult because quasi all parameters interfere
//to test on several images
int nei = (int) (krad * loc.neigh);
int nei = (int)(krad * loc.neigh);
if (skip >= 4) {
nei = (int) (0.1f * nei + 2.f); //not too bad
nei = (int)(0.1f * nei + 2.f); //not too bad
} else if (skip > 1 && skip < 4) {
nei = (int) (0.3f * nei + 2.f);
nei = (int)(0.3f * nei + 2.f);
}
int moderetinex = 0;
@ -850,7 +851,7 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
constexpr auto maxRetinexScales = 8;
float RetinexScales[maxRetinexScales];
retinex_scales ( RetinexScales, scal, moderetinex, nei, high );
retinex_scales(RetinexScales, scal, moderetinex, nei, high);
const int H_L = height;
@ -888,18 +889,18 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
out[i] = &outBuffer[i * W_L];
}
const float logBetaGain = xlogf (16384.f);
const float logBetaGain = xlogf(16384.f);
float pond = logBetaGain / (float) scal;
if (!useHslLin) {
pond /= log (elogt);
pond /= log(elogt);
}
auto shmap = mapmet == 4 ? new SHMap (W_L, H_L, true) : nullptr;
auto shmap = mapmet == 4 ? new SHMap(W_L, H_L, true) : nullptr;
float *buffer = new float[W_L * H_L];
for ( int scale = scal - 1; scale >= 0; scale-- ) {
for (int scale = scal - 1; scale >= 0; scale--) {
#ifdef _OPENMP
#pragma omp parallel
#endif
@ -907,11 +908,11 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
if (scale == scal - 1)
{
gaussianBlur (src, out, W_L, H_L, RetinexScales[scale], buffer);
} else { // reuse result of last iteration
gaussianBlur(src, out, W_L, H_L, RetinexScales[scale], buffer);
} else // reuse result of last iteration
{
// out was modified in last iteration => restore it
if (((mapmet == 4)) && it == 1)
{
if (((mapmet == 4)) && it == 1) {
#ifdef _OPENMP
#pragma omp for
@ -924,8 +925,9 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
}
}
gaussianBlur (out, out, W_L, H_L, sqrtf (SQR (RetinexScales[scale]) - SQR (RetinexScales[scale + 1])), buffer);
gaussianBlur(out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), buffer);
}
if ((mapmet == 4) && it == 1 && scale > 0)
{
// out will be modified => store it for use in next iteration. We even don't need a new buffer because 'buffer' is free after gaussianBlur :)
@ -945,7 +947,7 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
float h_thcomp, s_thcomp;
if ((mapmet == 4) && it == 1) {
shmap->updateL (out, shradius, true, 1);
shmap->updateL(out, shradius, true, 1);
h_thcomp = 0.f;//shmap->max_f - loc.htonalwidth * (shmap->max_f - shmap->avg) / 100.f;
h_th = h_thcomp - (shHighlights * h_thcomp);
s_thcomp = 0.f;//loc.stonalwidth * (shmap->avg - shmap->min_f) / 100.f;
@ -973,9 +975,9 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
}
#ifdef __SSE2__
vfloat pondv = F2V (pond);
vfloat limMinv = F2V (ilimD);
vfloat limMaxv = F2V (limD);
vfloat pondv = F2V(pond);
vfloat limMinv = F2V(ilimD);
vfloat limMaxv = F2V(limD);
#endif
#ifdef _OPENMP
@ -989,11 +991,11 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
if (useHslLin) { //keep in case of ??
for (; j < W_L - 3; j += 4) {
_mm_storeu_ps (&luminance[i][j], LVFU (luminance[i][j]) + pondv * (LIMV (LVFU (src[i][j]) / LVFU (out[i][j]), limMinv, limMaxv) ));
_mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * (LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv)));
}
} else {//always Lab mode due to Wavelet
for (; j < W_L - 3; j += 4) {
_mm_storeu_ps (&luminance[i][j], LVFU (luminance[i][j]) + pondv * xlogf (LIMV (LVFU (src[i][j]) / LVFU (out[i][j]), limMinv, limMaxv) ));
_mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * xlogf(LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv)));
}
}
@ -1001,11 +1003,11 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
if (useHslLin) {
for (; j < W_L; j++) {
luminance[i][j] += pond * (LIM (src[i][j] / out[i][j], ilimD, limD));
luminance[i][j] += pond * (LIM(src[i][j] / out[i][j], ilimD, limD));
}
} else {
for (; j < W_L; j++) {
luminance[i][j] += pond * xlogf (LIM (src[i][j] / out[i][j], ilimD, limD)); // /logt ?
luminance[i][j] += pond * xlogf(LIM(src[i][j] / out[i][j], ilimD, limD)); // /logt ?
}
}
}
@ -1025,7 +1027,7 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
mean = 0.f;
stddv = 0.f;
mean_stddv2 ( luminance, mean, stddv, W_L, H_L, maxtr, mintr);
mean_stddv2(luminance, mean, stddv, W_L, H_L, maxtr, mintr);
//printf("mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", mean, stddv, delta, maxtr, mintr);
// mean_stddv( luminance, mean, stddv, W_L, H_L, logBetaGain, maxtr, mintr);
@ -1088,7 +1090,7 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
// float pp[9], temp;
for (int j = borderL; j < wid - borderL; j++) {
tmL[i][j] = median (luminance[i][j], luminance[i - 1][j], luminance[i + 1][j], luminance[i][j + 1], luminance[i][j - 1], luminance[i - 1][j - 1], luminance[i - 1][j + 1], luminance[i + 1][j - 1], luminance[i + 1][j + 1]); //3x3
tmL[i][j] = median(luminance[i][j], luminance[i - 1][j], luminance[i + 1][j], luminance[i][j + 1], luminance[i][j - 1], luminance[i - 1][j - 1], luminance[i - 1][j + 1], luminance[i + 1][j - 1], luminance[i + 1][j + 1]); //3x3
}
}
@ -1096,7 +1098,7 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
#pragma omp parallel for
#endif
for (int i = borderL; i < hei - borderL; i++ ) {
for (int i = borderL; i < hei - borderL; i++) {
for (int j = borderL; j < wid - borderL; j++) {
luminance[i][j] = tmL[i][j];
}
@ -1108,7 +1110,7 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
// I call mean_stddv2 instead of mean_stddv ==> logBetaGain
// mean_stddv( luminance, mean, stddv, W_L, H_L, 1.f, maxtr, mintr);
mean_stddv2 ( luminance, mean, stddv, W_L, H_L, maxtr, mintr);
mean_stddv2(luminance, mean, stddv, W_L, H_L, maxtr, mintr);
}
@ -1129,7 +1131,7 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
delta = maxi - mini;
//printf("maxi=%f mini=%f mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", maxi, mini, mean, stddv, delta, maxtr, mintr);
if ( !delta ) {
if (!delta) {
delta = 1.0f;
}
@ -1152,7 +1154,7 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
stddv = 0.f;
// I call mean_stddv2 instead of mean_stddv ==> logBetaGain
mean_stddv2 ( luminance, mean, stddv, W_L, H_L, maxtr, mintr);
mean_stddv2(luminance, mean, stddv, W_L, H_L, maxtr, mintr);
float asig = 0.f, bsig = 0.f, amax = 0.f, bmax = 0.f, amin = 0.f, bmin = 0.f;
// bool gaincurve = false; //wavRETgainCcurve
const bool hasWavRetGainCurve = locRETgainCcurve && mean != 0.f && stddv != 0.f;
@ -1188,12 +1190,12 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
#pragma omp for schedule(dynamic,16)
#endif
for ( int i = 0; i < H_L; i ++ )
for (int i = 0; i < H_L; i ++)
for (int j = 0; j < W_L; j++) {
if (hasWavRetGainCurve) {
float absciss;
if (LIKELY (fabsf (luminance[i][j] - mean) < stddv)) {
if (LIKELY(fabsf(luminance[i][j] - mean) < stddv)) {
absciss = asig * luminance[i][j] + bsig;
} else if (luminance[i][j] >= mean) {
absciss = amax * luminance[i][j] + bmax;
@ -1208,7 +1210,7 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
cdmax = cd > cdmax ? cd : cdmax;
cdmin = cd < cdmin ? cd : cdmin;
luminance[i][j] = LIM ( cd, 0.f, maxclip ) * str + (1.f - str) * originalLuminance[i][j];
luminance[i][j] = LIM(cd, 0.f, maxclip) * str + (1.f - str) * originalLuminance[i][j];
// templ[i][j] = LIM( cd, 0.f, maxclip ) * str + (1.f - str) * originalLuminance[i][j];
// luminance[i][j] = LIM( cd, 0.f, maxclip );
}

View File

@ -2995,7 +2995,7 @@ bool MetaDataParams::operator!=(const MetaDataParams &other) const
}
ProcParams::ProcParams ()
ProcParams::ProcParams()
{
setDefaults();
}
@ -3086,8 +3086,8 @@ void ProcParams::setDefaults()
raw = RAWParams();
metadata = MetaDataParams();
exif.clear ();
iptc.clear ();
exif.clear();
iptc.clear();
rank = 0;
colorlabel = 0;
@ -5389,13 +5389,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
if (keyFile.has_group("MetaData")) {
int mode = int(MetaDataParams::TUNNEL);
assignFromKeyfile(keyFile, "MetaData", "Mode", pedited, mode, pedited->metadata.mode);
if (mode >= int(MetaDataParams::TUNNEL) && mode <= int(MetaDataParams::STRIP)) {
metadata.mode = static_cast<MetaDataParams::Mode>(mode);
}
}
if (keyFile.has_group ("Exif")) {
std::vector<Glib::ustring> keys = keyFile.get_keys ("Exif");
if (keyFile.has_group("Exif")) {
std::vector<Glib::ustring> keys = keyFile.get_keys("Exif");
for (const auto& key : keyFile.get_keys("Exif")) {
exif[key] = keyFile.get_string("Exif", key);

View File

@ -21,7 +21,7 @@ namespace rtengine
extern const Settings* settings;
RawImage::RawImage( const Glib::ustring &name )
RawImage::RawImage(const Glib::ustring &name)
: data(nullptr)
, prefilters(0)
, filename(name)
@ -37,31 +37,31 @@ RawImage::RawImage( const Glib::ustring &name )
RawImage::~RawImage()
{
if(ifp) {
if (ifp) {
fclose(ifp);
ifp = nullptr;
}
if( image ) {
if (image) {
free(image);
}
if(allocation) {
if (allocation) {
delete [] allocation;
allocation = nullptr;
}
if(float_raw_image) {
if (float_raw_image) {
delete [] float_raw_image;
float_raw_image = nullptr;
}
if(data) {
if (data) {
delete [] data;
data = nullptr;
}
if(profile_data) {
if (profile_data) {
delete [] profile_data;
profile_data = nullptr;
}
@ -83,7 +83,7 @@ eSensorType RawImage::getSensorType()
/* Similar to dcraw scale_colors for coeff. calculation, but without actual pixels scaling.
* need pixels in data[][] available
*/
void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblack_, bool forceAutoWB)
void RawImage::get_colorsCoeff(float *pre_mul_, float *scale_mul_, float *cblack_, bool forceAutoWB)
{
unsigned sum[8], c;
unsigned W = this->get_width();
@ -91,7 +91,7 @@ void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblac
float val;
double dsum[8], dmin, dmax;
if(isXtrans()) {
if (isXtrans()) {
// for xtrans files dcraw stores black levels in cblack[6] .. cblack[41], but all are equal, so we just use cblack[6]
for (int c = 0; c < 4; c++) {
cblack_[c] = (float) this->get_cblack(6);
@ -101,6 +101,7 @@ void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblac
for (int c = 0; c < 4; c++) {
cblack_[c] = this->get_cblack(c);
}
for (int c = 0; c < 4; c++) {
cblack_[FC(c / 2, c % 2)] = this->get_cblack(6 + c / 2 % this->get_cblack(4) * this->get_cblack(5) + c % 2 % this->get_cblack(5));
pre_mul_[c] = this->get_pre_mul(c);
@ -113,9 +114,10 @@ void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblac
}
if (this->get_cam_mul(0) == -1 || forceAutoWB) {
if(!data) { // this happens only for thumbnail creation when get_cam_mul(0) == -1
if (!data) { // this happens only for thumbnail creation when get_cam_mul(0) == -1
compress_image(0, false);
}
memset(dsum, 0, sizeof dsum);
if (this->isBayer()) {
@ -191,11 +193,11 @@ skip_block2:
}
}
for(int c = 0; c < 4; c++) {
for (int c = 0; c < 4; c++) {
dsum[c] -= cblack_[c] * dsum[c + 4];
}
} else if(isXtrans()) {
} else if (isXtrans()) {
#pragma omp parallel
{
double dsumthr[8];
@ -280,7 +282,7 @@ skip_block3:
sum[c] += val;
sum[c + 4]++;
if ( this->isBayer()) {
if (this->isBayer()) {
break;
}
}
@ -315,8 +317,7 @@ skip_block:
if (sum[0] && sum[1] && sum[2] && sum[3])
for (int c = 0; c < 4; c++) {
pre_mul_[c] = (float) sum[c + 4] / sum[c];
}
else if (this->get_cam_mul(0) && this->get_cam_mul(2)) {
} else if (this->get_cam_mul(0) && this->get_cam_mul(2)) {
pre_mul_[0] = this->get_cam_mul(0);
pre_mul_[1] = this->get_cam_mul(1);
pre_mul_[2] = this->get_cam_mul(2);
@ -407,17 +408,17 @@ skip_block:
}
}
int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, ProgressListener *plistener, double progressRange)
int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, ProgressListener *plistener, double progressRange)
{
ifname = filename.c_str();
image = nullptr;
verbose = settings->verbose;
oprof = nullptr;
if(!ifp) {
ifp = gfopen (ifname); // Maps to either file map or direct fopen
if (!ifp) {
ifp = gfopen(ifname); // Maps to either file map or direct fopen
} else {
fseek (ifp, 0, SEEK_SET);
fseek(ifp, 0, SEEK_SET);
}
if (!ifp) {
@ -453,9 +454,9 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro
return 2;
}
if(!strcmp(make,"Fujifilm") && raw_height * raw_width * 2u != raw_size) {
if (!strcmp(make, "Fujifilm") && raw_height * raw_width * 2u != raw_size) {
parse_fuji_compressed_header();
}
}
if (flip == 5) {
this->rotate_deg = 270;
@ -469,28 +470,28 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro
this->rotate_deg = 0;
}
if( loadData ) {
if (loadData) {
use_camera_wb = 1;
shrink = 0;
if (settings->verbose) {
printf ("Loading %s %s image from %s...\n", make, model, filename.c_str());
printf("Loading %s %s image from %s...\n", make, model, filename.c_str());
}
iheight = height;
iwidth = width;
if (filters || colors == 1) {
raw_image = (ushort *) calloc ((raw_height + 7) * raw_width, 2);
merror (raw_image, "main()");
raw_image = (ushort *) calloc((raw_height + 7) * raw_width, 2);
merror(raw_image, "main()");
}
// dcraw needs this global variable to hold pixel data
image = (dcrawImage_t)calloc (height * width * sizeof * image + meta_length, 1);
meta_data = (char *) (image + height * width);
image = (dcrawImage_t)calloc(height * width * sizeof * image + meta_length, 1);
meta_data = (char *)(image + height * width);
if(!image) {
if (!image) {
return 200;
}
@ -503,7 +504,7 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro
}
*/
// Load raw pixels data
fseek (ifp, data_offset, SEEK_SET);
fseek(ifp, data_offset, SEEK_SET);
(this->*load_raw)();
if (plistener) {
@ -517,13 +518,15 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro
if (cc && cc->has_rawCrop()) {
int lm, tm, w, h;
cc->get_rawCrop(lm, tm, w, h);
if(isXtrans()) {
shiftXtransMatrix(6 - ((top_margin - tm)%6), 6 - ((left_margin - lm)%6));
if (isXtrans()) {
shiftXtransMatrix(6 - ((top_margin - tm) % 6), 6 - ((left_margin - lm) % 6));
} else {
if(((int)top_margin - tm) & 1) { // we have an odd border difference
if (((int)top_margin - tm) & 1) { // we have an odd border difference
filters = (filters << 4) | (filters >> 28); // left rotate filters by 4 bits
}
}
left_margin = lm;
top_margin = tm;
@ -553,7 +556,7 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro
}
crop_masked_pixels();
free (raw_image);
free(raw_image);
raw_image = nullptr;
} else {
if (get_maker() == "Sigma" && cc && cc->has_rawCrop()) { // foveon images
@ -581,8 +584,8 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro
// Load embedded profile
if (profile_length) {
profile_data = new char[profile_length];
fseek ( ifp, profile_offset, SEEK_SET);
fread ( profile_data, 1, profile_length, ifp);
fseek(ifp, profile_offset, SEEK_SET);
fread(profile_data, 1, profile_length, ifp);
}
/*
@ -612,10 +615,10 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro
if (RT_whitelevel_from_constant) {
maximum_c4[i] = cc->get_WhiteLevel(i, iso_speed, aperture);
if(tiff_bps > 0 && maximum_c4[i] > 0 && !isFoveon()) {
if (tiff_bps > 0 && maximum_c4[i] > 0 && !isFoveon()) {
unsigned compare = ((uint64_t)1 << tiff_bps) - 1; // use uint64_t to avoid overflow if tiff_bps == 32
while(static_cast<uint64_t>(maximum_c4[i]) > compare) {
while (static_cast<uint64_t>(maximum_c4[i]) > compare) {
maximum_c4[i] >>= 1;
}
}
@ -624,11 +627,10 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro
}
if (black_c4[0] == -1) {
if(isXtrans())
if (isXtrans())
for (int c = 0; c < 4; c++) {
black_c4[c] = cblack[6];
}
else
} else
// RT constants not set, bring in the DCRAW single channel black constant
for (int c = 0; c < 4; c++) {
@ -664,7 +666,7 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro
}
}
if ( closeFile ) {
if (closeFile) {
fclose(ifp);
ifp = nullptr;
}
@ -678,7 +680,7 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro
float** RawImage::compress_image(int frameNum, bool freeImage)
{
if( !image ) {
if (!image) {
return nullptr;
}
@ -714,7 +716,7 @@ float** RawImage::compress_image(int frameNum, bool freeImage)
}
// copy pixel raw data: the compressed format earns space
if( float_raw_image ) {
if (float_raw_image) {
#pragma omp parallel for
for (int row = 0; row < height; row++)
@ -746,10 +748,11 @@ float** RawImage::compress_image(int frameNum, bool freeImage)
this->data[row][col] = image[row * width + col][0];
}
} else {
if(get_maker() == "Sigma" && dng_version) { // Hack to prevent sigma dng files from crashing
if (get_maker() == "Sigma" && dng_version) { // Hack to prevent sigma dng files from crashing
height -= top_margin;
width -= left_margin;
}
#pragma omp parallel for
for (int row = 0; row < height; row++)
@ -760,50 +763,51 @@ float** RawImage::compress_image(int frameNum, bool freeImage)
}
}
if(freeImage) {
if (freeImage) {
free(image); // we don't need this anymore
image = nullptr;
}
return data;
}
bool
RawImage::is_supportedThumb() const
{
return ( (thumb_width * thumb_height) > 0 &&
( write_thumb == &rtengine::RawImage::jpeg_thumb ||
write_thumb == &rtengine::RawImage::ppm_thumb) &&
!thumb_load_raw );
return ((thumb_width * thumb_height) > 0 &&
(write_thumb == &rtengine::RawImage::jpeg_thumb ||
write_thumb == &rtengine::RawImage::ppm_thumb) &&
!thumb_load_raw);
}
bool
RawImage::is_jpegThumb() const
{
return ( (thumb_width * thumb_height) > 0 &&
write_thumb == &rtengine::RawImage::jpeg_thumb &&
!thumb_load_raw );
return ((thumb_width * thumb_height) > 0 &&
write_thumb == &rtengine::RawImage::jpeg_thumb &&
!thumb_load_raw);
}
bool
RawImage::is_ppmThumb() const
{
return ( (thumb_width * thumb_height) > 0 &&
write_thumb == &rtengine::RawImage::ppm_thumb &&
!thumb_load_raw );
return ((thumb_width * thumb_height) > 0 &&
write_thumb == &rtengine::RawImage::ppm_thumb &&
!thumb_load_raw);
}
void RawImage::getXtransMatrix( int XtransMatrix[6][6])
void RawImage::getXtransMatrix(int XtransMatrix[6][6])
{
for(int row = 0; row < 6; row++)
for(int col = 0; col < 6; col++) {
for (int row = 0; row < 6; row++)
for (int col = 0; col < 6; col++) {
XtransMatrix[row][col] = xtrans[row][col];
}
}
void RawImage::getRgbCam (float rgbcam[3][4])
void RawImage::getRgbCam(float rgbcam[3][4])
{
for(int row = 0; row < 3; row++)
for(int col = 0; col < 4; col++) {
for (int row = 0; row < 3; row++)
for (int col = 0; col < 4; col++) {
rgbcam[row][col] = rgb_cam[row][col];
}

View File

@ -33,7 +33,7 @@ namespace rtengine
struct badPix {
uint16_t x;
uint16_t y;
badPix( uint16_t xc, uint16_t yc ): x(xc), y(yc) {}
badPix(uint16_t xc, uint16_t yc): x(xc), y(yc) {}
};
class PixelsMap :
@ -46,12 +46,12 @@ class PixelsMap :
base_t *pm;
public:
PixelsMap(int width, int height )
PixelsMap(int width, int height)
: h(height)
{
w = (width / (base_t_size * 8)) + 1;
pm = new base_t [h * w ];
memset(pm, 0, h * w * base_t_size );
memset(pm, 0, h * w * base_t_size);
}
~PixelsMap()
@ -70,7 +70,7 @@ public:
// if a pixel is set returns true
bool get(int x, int y)
{
return (pm[y * w + x / (base_t_size * 8) ] & (base_t)1 << (x % (base_t_size * 8)) ) != 0;
return (pm[y * w + x / (base_t_size * 8) ] & (base_t)1 << (x % (base_t_size * 8))) != 0;
}
// set a pixel
@ -80,10 +80,10 @@ public:
}
// set pixels from a list
int set( std::vector<badPix> &bp)
int set(std::vector<badPix> &bp)
{
for(std::vector<badPix>::iterator iter = bp.begin(); iter != bp.end(); ++iter) {
set( iter->x, iter->y);
for (std::vector<badPix>::iterator iter = bp.begin(); iter != bp.end(); ++iter) {
set(iter->x, iter->y);
}
return bp.size();
@ -91,7 +91,7 @@ public:
void clear()
{
memset(pm, 0, h * w * base_t_size );
memset(pm, 0, h * w * base_t_size);
}
// return 0 if at least one pixel in the word(base_t) is set, otherwise return the number of pixels to skip to the next word base_t
int skipIfZero(int x, int y)
@ -105,11 +105,11 @@ class RawImage: public DCraw
{
public:
explicit RawImage( const Glib::ustring &name );
explicit RawImage(const Glib::ustring &name);
~RawImage();
int loadRaw (bool loadData, unsigned int imageNum = 0, bool closeFile = true, ProgressListener *plistener = nullptr, double progressRange = 1.0);
void get_colorsCoeff( float* pre_mul_, float* scale_mul_, float* cblack_, bool forceAutoWB );
int loadRaw(bool loadData, unsigned int imageNum = 0, bool closeFile = true, ProgressListener *plistener = nullptr, double progressRange = 1.0);
void get_colorsCoeff(float* pre_mul_, float* scale_mul_, float* cblack_, bool forceAutoWB);
void set_prefilters()
{
if (isBayer() && get_colors() == 3) {
@ -124,7 +124,10 @@ public:
float** compress_image(int frameNum, bool freeImage = true); // revert to compressed pixels format and release image data
float** data; // holds pixel values, data[i][j] corresponds to the ith row and jth column
unsigned prefilters; // original filters saved ( used for 4 color processing )
unsigned int getFrameCount() const { return is_raw; }
unsigned int getFrameCount() const
{
return is_raw;
}
protected:
Glib::ustring filename; // complete filename
int rotate_deg; // 0,90,180,270 degree of rotation: info taken by dcraw from exif
@ -173,8 +176,8 @@ public:
}
eSensorType getSensorType();
void getRgbCam (float rgbcam[3][4]);
void getXtransMatrix ( int xtransMatrix[6][6]);
void getRgbCam(float rgbcam[3][4]);
void getXtransMatrix(int xtransMatrix[6][6]);
unsigned get_filters() const
{
return filters;
@ -195,7 +198,7 @@ public:
return maximum;
}
}
unsigned short get_whiteSample( int r, int c ) const
unsigned short get_whiteSample(int r, int c) const
{
return white[r][c];
}
@ -229,13 +232,13 @@ public:
return std::string(model);
}
float get_cam_mul(int c )const
float get_cam_mul(int c)const
{
return cam_mul[c];
}
float get_pre_mul(int c )const
float get_pre_mul(int c)const
{
if(std::isfinite(pre_mul[c])) {
if (std::isfinite(pre_mul[c])) {
return pre_mul[c];
} else {
std::cout << "Failure decoding '" << filename << "', please file a bug report including the raw file and the line below:" << std::endl;
@ -243,7 +246,7 @@ public:
return 1.f;
}
}
float get_rgb_cam( int r, int c) const
float get_rgb_cam(int r, int c) const
{
return rgb_cam[r][c];
}
@ -320,7 +323,7 @@ public:
}
public:
bool ISRED (unsigned row, unsigned col) const
bool ISRED(unsigned row, unsigned col) const
{
return ((filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) == 0);
}
@ -328,15 +331,15 @@ public:
{
return ((filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) == 1);
}
bool ISBLUE (unsigned row, unsigned col) const
bool ISBLUE(unsigned row, unsigned col) const
{
return ((filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) == 2);
}
unsigned FC (unsigned row, unsigned col) const
unsigned FC(unsigned row, unsigned col) const
{
return (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3);
}
bool ISXTRANSRED (unsigned row, unsigned col) const
bool ISXTRANSRED(unsigned row, unsigned col) const
{
return ((xtrans[(row) % 6][(col) % 6]) == 0);
}
@ -344,16 +347,16 @@ public:
{
return ((xtrans[(row) % 6][(col) % 6]) == 1);
}
bool ISXTRANSBLUE (unsigned row, unsigned col) const
bool ISXTRANSBLUE(unsigned row, unsigned col) const
{
return ((xtrans[(row) % 6][(col) % 6]) == 2);
}
unsigned XTRANSFC (unsigned row, unsigned col) const
unsigned XTRANSFC(unsigned row, unsigned col) const
{
return (xtrans[(row) % 6][(col) % 6]);
}
unsigned DNGVERSION ( ) const
unsigned DNGVERSION() const
{
return dng_version;
}

File diff suppressed because it is too large Load Diff

View File

@ -38,9 +38,9 @@ private:
static DiagonalCurve *phaseOneIccCurve;
static DiagonalCurve *phaseOneIccCurveInv;
static LUTf invGrad; // for fast_demosaic
static LUTf initInvGrad ();
static void colorSpaceConversion_ (Imagefloat* im, const ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName);
int defTransform (int tran);
static LUTf initInvGrad();
static void colorSpaceConversion_(Imagefloat* im, const ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName);
int defTransform(int tran);
protected:
MyMutex getImageMutex; // locks getImage
@ -96,36 +96,36 @@ protected:
float psBlueBrightness[4];
void hphd_vertical (float** hpmap, int col_from, int col_to);
void hphd_horizontal (float** hpmap, int row_from, int row_to);
void hphd_green (float** hpmap);
void processFalseColorCorrectionThread (Imagefloat* im, array2D<float> &rbconv_Y, array2D<float> &rbconv_I, array2D<float> &rbconv_Q, array2D<float> &rbout_I, array2D<float> &rbout_Q, const int row_from, const int row_to);
void hlRecovery (const std::string &method, float* red, float* green, float* blue, int width, float* hlmax);
void transformRect (const PreviewProps &pp, int tran, int &sx1, int &sy1, int &width, int &height, int &fw);
void transformPosition (int x, int y, int tran, int& tx, int& ty);
void hphd_vertical(float** hpmap, int col_from, int col_to);
void hphd_horizontal(float** hpmap, int row_from, int row_to);
void hphd_green(float** hpmap);
void processFalseColorCorrectionThread(Imagefloat* im, array2D<float> &rbconv_Y, array2D<float> &rbconv_I, array2D<float> &rbconv_Q, array2D<float> &rbout_I, array2D<float> &rbout_Q, const int row_from, const int row_to);
void hlRecovery(const std::string &method, float* red, float* green, float* blue, int width, float* hlmax);
void transformRect(const PreviewProps &pp, int tran, int &sx1, int &sy1, int &width, int &height, int &fw);
void transformPosition(int x, int y, int tran, int& tx, int& ty);
unsigned FC(int row, int col)
{
return ri->FC(row, col);
}
inline void getRowStartEnd (int x, int &start, int &end);
inline void getRowStartEnd(int x, int &start, int &end);
static void getProfilePreprocParams(cmsHPROFILE in, float& gammafac, float& lineFac, float& lineSum);
public:
RawImageSource ();
~RawImageSource ();
RawImageSource();
~RawImageSource();
int load (const Glib::ustring &fname);
void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise = true);
void demosaic (const RAWParams &raw);
void retinex (const ColorManagementParams& cmp, const RetinexParams &deh, ToneCurveParams Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D<float, 4> &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI);
void retinexPrepareCurves (const RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI);
void retinexPrepareBuffers (const ColorManagementParams& cmp, const RetinexParams &retinexParams, multi_array2D<float, 4> &conversionBuffer, LUTu &lhist16RETI);
void flushRawData ();
void flushRGB ();
void HLRecovery_Global (ToneCurveParams hrp);
void refinement_lassus (int PassCount);
int load(const Glib::ustring &fname);
void preprocess(const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise = true);
void demosaic(const RAWParams &raw);
void retinex(const ColorManagementParams& cmp, const RetinexParams &deh, ToneCurveParams Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D<float, 4> &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI);
void retinexPrepareCurves(const RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI);
void retinexPrepareBuffers(const ColorManagementParams& cmp, const RetinexParams &retinexParams, multi_array2D<float, 4> &conversionBuffer, LUTu &lhist16RETI);
void flushRawData();
void flushRGB();
void HLRecovery_Global(ToneCurveParams hrp);
void refinement_lassus(int PassCount);
void refinement(int PassCount);
bool isRGBSourceModified() const
@ -134,43 +134,43 @@ public:
}
void processFlatField(const RAWParams &raw, RawImage *riFlatFile, unsigned short black[4]);
void copyOriginalPixels(const RAWParams &raw, RawImage *ri, RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData );
void cfaboxblur (RawImage *riFlatFile, float* cfablur, int boxH, int boxW);
void scaleColors (int winx, int winy, int winw, int winh, const RAWParams &raw, array2D<float> &rawData); // raw for cblack
void copyOriginalPixels(const RAWParams &raw, RawImage *ri, RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData);
void cfaboxblur(RawImage *riFlatFile, float* cfablur, int boxH, int boxW);
void scaleColors(int winx, int winy, int winw, int winh, const RAWParams &raw, array2D<float> &rawData); // raw for cblack
void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw);
eSensorType getSensorType () const
void getImage(const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw);
eSensorType getSensorType() const
{
return ri != nullptr ? ri->getSensorType() : ST_NONE;
}
ColorTemp getWB () const
ColorTemp getWB() const
{
return camera_wb;
}
void getAutoWBMultipliers (double &rm, double &gm, double &bm);
ColorTemp getSpotWB (std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, int tran, double equal);
bool isWBProviderReady ()
void getAutoWBMultipliers(double &rm, double &gm, double &bm);
ColorTemp getSpotWB(std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, int tran, double equal);
bool isWBProviderReady()
{
return rawData;
}
double getDefGain () const
double getDefGain() const
{
return defGain;
}
void getFullSize (int& w, int& h, int tr = TR_NONE);
void getSize (const PreviewProps &pp, int& w, int& h);
void getFullSize(int& w, int& h, int tr = TR_NONE);
void getSize(const PreviewProps &pp, int& w, int& h);
int getRotateDegree() const
{
return ri->get_rotateDegree();
}
FrameData* getImageData (unsigned int frameNum)
FrameData* getImageData(unsigned int frameNum)
{
return idata->getFrameData (frameNum);
return idata->getFrameData(frameNum);
}
ImageMatrices* getImageMatrices ()
ImageMatrices* getImageMatrices()
{
return &imatrices;
}
@ -179,62 +179,66 @@ public:
return true;
}
void setProgressListener (ProgressListener* pl)
void setProgressListener(ProgressListener* pl)
{
plistener = pl;
}
void getAutoExpHistogram (LUTu & histogram, int& histcompr);
void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw);
void getAutoExpHistogram(LUTu & histogram, int& histcompr);
void getRAWHistogram(LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw);
DCPProfile *getDCP(const ColorManagementParams &cmp, DCPProfile::ApplyState &as);
void convertColorSpace(Imagefloat* image, const ColorManagementParams &cmp, const ColorTemp &wb);
static bool findInputProfile(Glib::ustring inProfile, cmsHPROFILE embedded, std::string camName, DCPProfile **dcpProf, cmsHPROFILE& in);
static void colorSpaceConversion (Imagefloat* im, const ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName)
static void colorSpaceConversion(Imagefloat* im, const ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName)
{
colorSpaceConversion_ (im, cmp, wb, pre_mul, embedded, camprofile, cam, camName);
colorSpaceConversion_(im, cmp, wb, pre_mul, embedded, camprofile, cam, camName);
}
static void inverse33 (const double (*coeff)[3], double (*icoeff)[3]);
static void inverse33(const double (*coeff)[3], double (*icoeff)[3]);
void boxblur2(float** src, float** dst, float** temp, int H, int W, int box );
void boxblur_resamp(float **src, float **dst, float** temp, int H, int W, int box, int samp );
void boxblur2(float** src, float** dst, float** temp, int H, int W, int box);
void boxblur_resamp(float **src, float **dst, float** temp, int H, int W, int box, int samp);
void MSR(float** luminance, float **originalLuminance, float **exLuminance, LUTf & mapcurve, bool &mapcontlutili, int width, int height, const RetinexParams &deh, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax);
void HLRecovery_inpaint (float** red, float** green, float** blue);
static void HLRecovery_Luminance (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval);
static void HLRecovery_CIELab (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval, double cam[3][3], double icam[3][3]);
static void HLRecovery_blend (float* rin, float* gin, float* bin, int width, float maxval, float* hlmax);
static void init ();
static void cleanup ();
void setCurrentFrame(unsigned int frameNum) {
void HLRecovery_inpaint(float** red, float** green, float** blue);
static void HLRecovery_Luminance(float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval);
static void HLRecovery_CIELab(float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval, double cam[3][3], double icam[3][3]);
static void HLRecovery_blend(float* rin, float* gin, float* bin, int width, float maxval, float* hlmax);
static void init();
static void cleanup();
void setCurrentFrame(unsigned int frameNum)
{
currFrame = std::min(numFrames - 1, frameNum);
ri = riFrames[currFrame];
}
int getFrameCount() {return numFrames;}
int getFrameCount()
{
return numFrames;
}
protected:
typedef unsigned short ushort;
void processFalseColorCorrection (Imagefloat* i, const int steps);
inline void convert_row_to_YIQ (const float* const r, const float* const g, const float* const b, float* Y, float* I, float* Q, const int W);
inline void convert_row_to_RGB (float* r, float* g, float* b, const float* const Y, const float* const I, const float* const Q, const int W);
inline void convert_to_RGB (float &r, float &g, float &b, const float Y, const float I, const float Q);
void processFalseColorCorrection(Imagefloat* i, const int steps);
inline void convert_row_to_YIQ(const float* const r, const float* const g, const float* const b, float* Y, float* I, float* Q, const int W);
inline void convert_row_to_RGB(float* r, float* g, float* b, const float* const Y, const float* const I, const float* const Q, const int W);
inline void convert_to_RGB(float &r, float &g, float &b, const float Y, const float I, const float Q);
inline void convert_to_cielab_row (float* ar, float* ag, float* ab, float* oL, float* oa, float* ob);
inline void interpolate_row_g (float* agh, float* agv, int i);
inline void interpolate_row_rb (float* ar, float* ab, float* pg, float* cg, float* ng, int i);
inline void interpolate_row_rb_mul_pp (float* ar, float* ab, float* pg, float* cg, float* ng, int i, float r_mul, float g_mul, float b_mul, int x1, int width, int skip);
inline void convert_to_cielab_row(float* ar, float* ag, float* ab, float* oL, float* oa, float* ob);
inline void interpolate_row_g(float* agh, float* agv, int i);
inline void interpolate_row_rb(float* ar, float* ab, float* pg, float* cg, float* ng, int i);
inline void interpolate_row_rb_mul_pp(float* ar, float* ab, float* pg, float* cg, float* ng, int i, float r_mul, float g_mul, float b_mul, int x1, int width, int skip);
void CA_correct_RT (const bool autoCA, const double cared, const double cablue, const double caautostrength, array2D<float> &rawData);
void CA_correct_RT(const bool autoCA, const double cared, const double cablue, const double caautostrength, array2D<float> &rawData);
void ddct8x8s(int isgn, float a[8][8]);
void processRawWhitepoint (float expos, float preser, array2D<float> &rawData); // exposure before interpolation
void processRawWhitepoint(float expos, float preser, array2D<float> &rawData); // exposure before interpolation
int interpolateBadPixelsBayer( PixelsMap &bitmapBads, array2D<float> &rawData );
int interpolateBadPixelsNColours( PixelsMap &bitmapBads, const int colours );
int interpolateBadPixelsXtrans( PixelsMap &bitmapBads );
int findHotDeadPixels( PixelsMap &bpMap, float thresh, bool findHotPixels, bool findDeadPixels );
int interpolateBadPixelsBayer(PixelsMap &bitmapBads, array2D<float> &rawData);
int interpolateBadPixelsNColours(PixelsMap &bitmapBads, const int colours);
int interpolateBadPixelsXtrans(PixelsMap &bitmapBads);
int findHotDeadPixels(PixelsMap &bpMap, float thresh, bool findHotPixels, bool findDeadPixels);
void cfa_linedn (float linenoiselevel);//Emil's line denoise
void cfa_linedn(float linenoiselevel); //Emil's line denoise
void green_equilibrate_global (array2D<float> &rawData);
void green_equilibrate (float greenthresh, array2D<float> &rawData);//Emil's green equilibration
void green_equilibrate_global(array2D<float> &rawData);
void green_equilibrate(float greenthresh, array2D<float> &rawData); //Emil's green equilibration
void nodemosaic(bool bw);
void eahd_demosaic();
@ -252,8 +256,8 @@ protected:
void border_interpolate(unsigned int border, float (*image)[4], unsigned int start = 0, unsigned int end = 0);
void border_interpolate2(int winw, int winh, int lborders);
void dcb_initTileLimits(int &colMin, int &rowMin, int &colMax, int &rowMax, int x0, int y0, int border);
void fill_raw( float (*cache )[3], int x0, int y0, float** rawData);
void fill_border( float (*cache )[3], int border, int x0, int y0);
void fill_raw(float (*cache)[3], int x0, int y0, float** rawData);
void fill_border(float (*cache)[3], int border, int x0, int y0);
void copy_to_buffer(float (*image2)[2], float (*image)[3]);
void dcb_hid(float (*image)[3], int x0, int y0);
void dcb_color(float (*image)[3], int x0, int y0);
@ -265,13 +269,13 @@ protected:
void restore_from_buffer(float (*image)[3], float (*image2)[2]);
void dcb_refinement(float (*image)[3], uint8_t *map, int x0, int y0);
void dcb_color_full(float (*image)[3], int x0, int y0, float (*chroma)[2]);
void cielab (const float (*rgb)[3], float* l, float* a, float *b, const int width, const int height, const int labWidth, const float xyz_cam[3][3]);
void xtransborder_interpolate (int border);
void xtrans_interpolate (const int passes, const bool useCieLab);
void fast_xtrans_interpolate ();
void cielab(const float (*rgb)[3], float* l, float* a, float *b, const int width, const int height, const int labWidth, const float xyz_cam[3][3]);
void xtransborder_interpolate(int border);
void xtrans_interpolate(const int passes, const bool useCieLab);
void fast_xtrans_interpolate();
void pixelshift(int winx, int winy, int winw, int winh, const RAWParams::BayerSensor &bayerParams, unsigned int frame, const std::string &make, const std::string &model, float rawWpCorrection);
void hflip (Imagefloat* im);
void vflip (Imagefloat* im);
void hflip(Imagefloat* im);
void vflip(Imagefloat* im);
void getRawValues(int x, int y, int rotate, int &R, int &G, int &B);
};

View File

@ -56,12 +56,12 @@ void adjust_radius(const T &default_param, double scale_factor, T &param)
class ImageProcessor
{
public:
ImageProcessor (ProcessingJob* pjob, int& errorCode,
ProgressListener* pl, bool flush):
job (static_cast<ProcessingJobImpl*> (pjob)),
errorCode (errorCode),
pl (pl),
flush (flush),
ImageProcessor(ProcessingJob* pjob, int& errorCode,
ProgressListener* pl, bool flush):
job(static_cast<ProcessingJobImpl*>(pjob)),
errorCode(errorCode),
pl(pl),
flush(flush),
// internal state
ipf_p(nullptr),
ii(nullptr),
@ -2467,18 +2467,20 @@ private:
}
switch (params.metadata.mode) {
case MetaDataParams::TUNNEL:
// Sending back the whole first root, which won't necessarily be the selected frame number
// and may contain subframe depending on initial raw's hierarchy
readyImg->setMetadata (ii->getMetaData()->getRootExifData ());
break;
case MetaDataParams::EDIT:
// ask for the correct frame number, but may contain subframe depending on initial raw's hierarchy
readyImg->setMetadata (ii->getMetaData()->getBestExifData(imgsrc, &params.raw), params.exif, params.iptc);
break;
default: // case MetaDataParams::STRIP
// nothing to do
break;
case MetaDataParams::TUNNEL:
// Sending back the whole first root, which won't necessarily be the selected frame number
// and may contain subframe depending on initial raw's hierarchy
readyImg->setMetadata(ii->getMetaData()->getRootExifData());
break;
case MetaDataParams::EDIT:
// ask for the correct frame number, but may contain subframe depending on initial raw's hierarchy
readyImg->setMetadata(ii->getMetaData()->getBestExifData(imgsrc, &params.raw), params.exif, params.iptc);
break;
default: // case MetaDataParams::STRIP
// nothing to do
break;
}
@ -2747,20 +2749,20 @@ private:
} // namespace
IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool flush)
IImage16* processImage(ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool flush)
{
ImageProcessor proc (pjob, errorCode, pl, flush);
ImageProcessor proc(pjob, errorCode, pl, flush);
return proc();
}
void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl)
void batchProcessingThread(ProcessingJob* job, BatchProcessingListener* bpl)
{
ProcessingJob* currentJob = job;
while (currentJob) {
int errorCode;
IImage16* img = processImage (currentJob, errorCode, bpl, true);
IImage16* img = processImage(currentJob, errorCode, bpl, true);
if (errorCode) {
bpl->error(M("MAIN_MSG_CANNOTLOAD"));
@ -2776,11 +2778,11 @@ void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl)
}
}
void startBatchProcessing (ProcessingJob* job, BatchProcessingListener* bpl)
void startBatchProcessing(ProcessingJob* job, BatchProcessingListener* bpl)
{
if (bpl) {
Glib::Thread::create (sigc::bind (sigc::ptr_fun (batchProcessingThread), job, bpl), 0, true, true, Glib::THREAD_PRIORITY_LOW);
Glib::Thread::create(sigc::bind(sigc::ptr_fun(batchProcessingThread), job, bpl), 0, true, true, Glib::THREAD_PRIORITY_LOW);
}
}

View File

@ -400,7 +400,7 @@ Locallab::Locallab():
ctboxshape->pack_start(*labmshape, Gtk::PACK_SHRINK, 4);
ctboxshape->set_tooltip_markup(M("TP_LOCALLAB_SHAPE_TOOLTIP"));
//ctboxshape->set_tooltip_markup(M("TP_LOCALLAB_SHAPE_TOOLTIP"));
ctboxEx->pack_start(*labmEx, Gtk::PACK_SHRINK, 4);
ctboxEx->set_tooltip_markup(M("TP_LOCALLAB_EXCLUTYPE_TOOLTIP"));

View File

@ -193,64 +193,64 @@ Gtk::Widget* Preferences::getBatchProcPanel()
appendBehavList(mi, M("TP_LOCALCONTRAST_AMOUNT"), ADDSET_LOCALCONTRAST_AMOUNT, false);
appendBehavList(mi, M("TP_LOCALCONTRAST_DARKNESS"), ADDSET_LOCALCONTRAST_DARKNESS, false);
appendBehavList(mi, M("TP_LOCALCONTRAST_LIGHTNESS"), ADDSET_LOCALCONTRAST_LIGHTNESS, false);
mi = behModel->append ();
mi->set_value (behavColumns.label, M ("TP_EPD_LABEL"));
appendBehavList (mi, M ("TP_EPD_STRENGTH"), ADDSET_EPD_STRENGTH, false);
appendBehavList (mi, M ("TP_EPD_GAMMA"), ADDSET_EPD_GAMMA, false);
appendBehavList (mi, M ("TP_EPD_EDGESTOPPING"), ADDSET_EPD_EDGESTOPPING, false);
appendBehavList (mi, M ("TP_EPD_SCALE"), ADDSET_EPD_SCALE, false);
appendBehavList (mi, M ("TP_EPD_REWEIGHTINGITERATES"), ADDSET_EPD_REWEIGHTINGITERATES, false);
mi = behModel->append ();
mi->set_value (behavColumns.label, M ("TP_TM_FATTAL_LABEL"));
appendBehavList (mi, M ("TP_TM_FATTAL_THRESHOLD"), ADDSET_FATTAL_ALPHA, false);
appendBehavList (mi, M ("TP_TM_FATTAL_AMOUNT"), ADDSET_FATTAL_BETA, false);
mi = behModel->append();
mi->set_value(behavColumns.label, M("TP_EPD_LABEL"));
appendBehavList(mi, M("TP_EPD_STRENGTH"), ADDSET_EPD_STRENGTH, false);
appendBehavList(mi, M("TP_EPD_GAMMA"), ADDSET_EPD_GAMMA, false);
appendBehavList(mi, M("TP_EPD_EDGESTOPPING"), ADDSET_EPD_EDGESTOPPING, false);
appendBehavList(mi, M("TP_EPD_SCALE"), ADDSET_EPD_SCALE, false);
appendBehavList(mi, M("TP_EPD_REWEIGHTINGITERATES"), ADDSET_EPD_REWEIGHTINGITERATES, false);
mi = behModel->append ();
mi->set_value (behavColumns.label, M ("TP_RETINEX_LABEL"));
appendBehavList (mi, M ("TP_RETINEX_STRENGTH"), ADDSET_RETI_STR, false);
appendBehavList (mi, M ("TP_RETINEX_NEIGHBOR"), ADDSET_RETI_NEIGH, false);
appendBehavList (mi, M ("TP_RETINEX_VARIANCE"), ADDSET_RETI_VART, false);
appendBehavList (mi, M ("TP_RETINEX_GAMMA"), ADDSET_RETI_GAM, false);
appendBehavList (mi, M ("TP_RETINEX_SLOPE"), ADDSET_RETI_SLO, false);
appendBehavList (mi, M ("TP_RETINEX_GAIN"), ADDSET_RETI_GAIN, false);
appendBehavList (mi, M ("TP_RETINEX_OFFSET"), ADDSET_RETI_OFFS, false);
appendBehavList (mi, M ("TP_RETINEX_THRESHOLD"), ADDSET_RETI_LIMD, false);
mi = behModel->append();
mi->set_value(behavColumns.label, M("TP_TM_FATTAL_LABEL"));
appendBehavList(mi, M("TP_TM_FATTAL_THRESHOLD"), ADDSET_FATTAL_ALPHA, false);
appendBehavList(mi, M("TP_TM_FATTAL_AMOUNT"), ADDSET_FATTAL_BETA, false);
mi = behModel->append ();
mi->set_value (behavColumns.label, M ("TP_SHADOWSHLIGHTS_LABEL"));
appendBehavList (mi, M ("TP_SHADOWSHLIGHTS_HIGHLIGHTS"), ADDSET_SH_HIGHLIGHTS, false);
appendBehavList (mi, M ("TP_SHADOWSHLIGHTS_SHADOWS"), ADDSET_SH_SHADOWS, false);
mi = behModel->append();
mi->set_value(behavColumns.label, M("TP_RETINEX_LABEL"));
appendBehavList(mi, M("TP_RETINEX_STRENGTH"), ADDSET_RETI_STR, false);
appendBehavList(mi, M("TP_RETINEX_NEIGHBOR"), ADDSET_RETI_NEIGH, false);
appendBehavList(mi, M("TP_RETINEX_VARIANCE"), ADDSET_RETI_VART, false);
appendBehavList(mi, M("TP_RETINEX_GAMMA"), ADDSET_RETI_GAM, false);
appendBehavList(mi, M("TP_RETINEX_SLOPE"), ADDSET_RETI_SLO, false);
appendBehavList(mi, M("TP_RETINEX_GAIN"), ADDSET_RETI_GAIN, false);
appendBehavList(mi, M("TP_RETINEX_OFFSET"), ADDSET_RETI_OFFS, false);
appendBehavList(mi, M("TP_RETINEX_THRESHOLD"), ADDSET_RETI_LIMD, false);
mi = behModel->append ();
mi->set_value (behavColumns.label, M ("TP_LABCURVE_LABEL"));
appendBehavList (mi, M ("TP_LABCURVE_BRIGHTNESS"), ADDSET_LC_BRIGHTNESS, false);
appendBehavList (mi, M ("TP_LABCURVE_CONTRAST"), ADDSET_LC_CONTRAST, false);
appendBehavList (mi, M ("TP_LABCURVE_CHROMATICITY"), ADDSET_LC_CHROMATICITY, false);
mi = behModel->append();
mi->set_value(behavColumns.label, M("TP_SHADOWSHLIGHTS_LABEL"));
appendBehavList(mi, M("TP_SHADOWSHLIGHTS_HIGHLIGHTS"), ADDSET_SH_HIGHLIGHTS, false);
appendBehavList(mi, M("TP_SHADOWSHLIGHTS_SHADOWS"), ADDSET_SH_SHADOWS, false);
mi = behModel->append (); // Used for both Resize and Post-Resize sharpening
mi->set_value (behavColumns.label, M ("TP_SHARPENING_LABEL"));
appendBehavList (mi, M ("TP_SHARPENING_RADIUS"), ADDSET_SHARP_RADIUS, false);
appendBehavList (mi, M ("TP_SHARPENING_AMOUNT"), ADDSET_SHARP_AMOUNT, false);
appendBehavList (mi, M ("TP_SHARPENING_RLD_DAMPING"), ADDSET_SHARP_DAMPING, false);
appendBehavList (mi, M ("TP_SHARPENING_RLD_ITERATIONS"), ADDSET_SHARP_ITER, false);
appendBehavList (mi, M ("TP_SHARPENING_EDTOLERANCE"), ADDSET_SHARP_EDGETOL, false);
appendBehavList (mi, M ("TP_SHARPENING_HALOCONTROL"), ADDSET_SHARP_HALOCTRL, false);
mi = behModel->append();
mi->set_value(behavColumns.label, M("TP_LABCURVE_LABEL"));
appendBehavList(mi, M("TP_LABCURVE_BRIGHTNESS"), ADDSET_LC_BRIGHTNESS, false);
appendBehavList(mi, M("TP_LABCURVE_CONTRAST"), ADDSET_LC_CONTRAST, false);
appendBehavList(mi, M("TP_LABCURVE_CHROMATICITY"), ADDSET_LC_CHROMATICITY, false);
mi = behModel->append ();
mi->set_value (behavColumns.label, M ("TP_SHARPENEDGE_LABEL"));
appendBehavList (mi, M ("TP_SHARPENEDGE_PASSES"), ADDSET_SHARPENEDGE_PASS, false);
appendBehavList (mi, M ("TP_SHARPENEDGE_AMOUNT"), ADDSET_SHARPENEDGE_AMOUNT, false);
mi = behModel->append(); // Used for both Resize and Post-Resize sharpening
mi->set_value(behavColumns.label, M("TP_SHARPENING_LABEL"));
appendBehavList(mi, M("TP_SHARPENING_RADIUS"), ADDSET_SHARP_RADIUS, false);
appendBehavList(mi, M("TP_SHARPENING_AMOUNT"), ADDSET_SHARP_AMOUNT, false);
appendBehavList(mi, M("TP_SHARPENING_RLD_DAMPING"), ADDSET_SHARP_DAMPING, false);
appendBehavList(mi, M("TP_SHARPENING_RLD_ITERATIONS"), ADDSET_SHARP_ITER, false);
appendBehavList(mi, M("TP_SHARPENING_EDTOLERANCE"), ADDSET_SHARP_EDGETOL, false);
appendBehavList(mi, M("TP_SHARPENING_HALOCONTROL"), ADDSET_SHARP_HALOCTRL, false);
mi = behModel->append ();
mi->set_value (behavColumns.label, M ("TP_SHARPENMICRO_LABEL"));
appendBehavList (mi, M ("TP_SHARPENMICRO_AMOUNT"), ADDSET_SHARPENMICRO_AMOUNT, false);
appendBehavList (mi, M ("TP_SHARPENMICRO_UNIFORMITY"), ADDSET_SHARPENMICRO_UNIFORMITY, false);
mi = behModel->append();
mi->set_value(behavColumns.label, M("TP_SHARPENEDGE_LABEL"));
appendBehavList(mi, M("TP_SHARPENEDGE_PASSES"), ADDSET_SHARPENEDGE_PASS, false);
appendBehavList(mi, M("TP_SHARPENEDGE_AMOUNT"), ADDSET_SHARPENEDGE_AMOUNT, false);
mi = behModel->append ();
mi->set_value (behavColumns.label, M ("TP_DIRPYRDENOISE_LABEL"));
mi = behModel->append();
mi->set_value(behavColumns.label, M("TP_SHARPENMICRO_LABEL"));
appendBehavList(mi, M("TP_SHARPENMICRO_AMOUNT"), ADDSET_SHARPENMICRO_AMOUNT, false);
appendBehavList(mi, M("TP_SHARPENMICRO_UNIFORMITY"), ADDSET_SHARPENMICRO_UNIFORMITY, false);
mi = behModel->append();
mi->set_value(behavColumns.label, M("TP_DIRPYRDENOISE_LABEL"));
//appendBehavList (mi, M("TP_DIRPYRDENOISE_LUMA")+", "+M("TP_DIRPYRDENOISE_CHROMA"), ADDSET_DIRPYRDN_CHLUM, true);
appendBehavList(mi, M("TP_DIRPYRDENOISE_LUMA"), ADDSET_DIRPYRDN_LUMA, true);
appendBehavList(mi, M("TP_DIRPYRDENOISE_LDETAIL"), ADDSET_DIRPYRDN_LUMDET, true);