Merge with 572a875474cb7c02682801dc30daab16a0d3c20b

This commit is contained in:
natureh 510 2013-01-27 01:09:04 +01:00
parent f3e0647a32
commit ee33ca0b7d
25 changed files with 808 additions and 575 deletions

View File

@ -285,6 +285,38 @@ WINDOWS
FFTW:
- Instructions: http://www.fftw.org/install/windows.html
- Specific instructions more suitable for RawTherapee purposes:
1. Download the official fftw64 DLL package from http://www.fftw.org/download.html,
unpack it somewhere you can reach it with MSYS
(Hint: in MSYS console to change directory to 'C:/DirName' execute 'cd /C/DirName')
2. in MSYS command line, execute:
dlltool --def libfftw3f-3.def --dllname libfftw3f-3.dll --output-lib libfftw3f-3.a
dlltool --def libfftw3l-3.def --dllname libfftw3l-3.dll --output-lib libfftw3l-3.a
dlltool --def libfftw3-3.def --dllname libfftw3-3.dll --output-lib libfftw3-3.a
This will generate generate 'libfftw3f-3.a.a' file
3. copy files:
libfftw3f-3.dll -> MinGW64/bin
libfftw3l-3.dll -> MinGW64/bin
libfftw3-3.dll -> MinGW64/bin
libfftw3f-3.a.a -> MinGW64/lib
fftw3.f.h -> MinGW64/include
4. Create a new textfile MinGW64/lib/pkgconfig/fftw3f.pc with the following contents:
prefix=/mingw64
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: fftw3f
Description: FFTW3 Float
Version: 3.3
Libs: -L${libdir} -lfftw3f-3 -lm
Cflags: -I${includedir}
IMPORTANT:
@ -356,6 +388,24 @@ WINDOWS
- You'll find the compiled program in the subdirectory named like the
value of CMAKE_BUILD_TYPE ("Release" in this example).
METHOD 3:
Here is a sample batch file to compile RawTherapee in Windows
Adjust directory names to match your setup
set GTKMM_BASEPATH=C:\gtkmm64
set GTKMM64_BASEPATH=C:\gtkmm64
set MINGW_BASEPATH=C:\MinGW64
set PATH=%PATH%;C:\gtkmm64\bin;C:\MinGW64\bin;C:\CMake\bin;C:\DevTools\XMPToolkit\bin
set PKG_CONFIG_PATH=C:\MinGW64\lib\pkgconfig;c:\gtkmm64\lib\pkgconfig
set RT_SOURCECODE_PATH=C:\Users\YOURNAME\workspace\rawtherapee_default
set RT_BUILD_PATH=C:\Users\YOURNAME\rt_builds\rt_default_release
cd %RT_BUILD_PATH%
cmake -DCMAKE_BUILD_TYPE=Release -G "MinGW Makefiles" -DPROC_TARGET_NUMBER:STRING=2 -C%RT_SOURCECODE_PATH%\Win32CMakeOptions-Sample.txt %RT_SOURCECODE_PATH%
mingw32-make -j12 install
pause
LINUX
-----

View File

@ -918,14 +918,15 @@ TP_COLORAPP_CONTRAST_Q;Contraste (Q)
TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contraste dans CIECAM02 pour le curseur (Q); est différent du contraste Lab et RVB
TP_COLORAPP_CONTRAST_TOOLTIP;Contraste dans CIECAM02 pour le curseur (J); est différent du contraste Lab et RVB
TP_COLORAPP_CURVEEDITOR1;Courbe tonale 1
TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Histogramme affiche L (lab) avant CIECAM.\n On peut voir le résultat dans la fenêtre histogramme.\n Histogramme de J/Q avant/après si la cas à cocher "Données CIECAM" est activée.\n (J,Q) ne sont pas affichés dans le panneau histogramme
TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Histogramme affiche L (lab) avant CIECAM02.\nOn peut voir le résultat dans la fenêtre histogramme.\n Histogramme de J/Q avant/après si la cas à cocher "Données CIECAM" est activée.\n (J,Q) ne sont pas affichés dans le panneau histogramme
TP_COLORAPP_CURVEEDITOR2;Courbe tonale 2
TP_COLORAPP_CURVEEDITOR2_TOOLTIP;usage similaire aux courbes tonales exposition
TP_COLORAPP_CURVEEDITOR3;Courbes chroma
TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Vous pouvez choisir entre chroma -saturation- niveau couleurs.\n Histogramme affiche la chromaticité Lab avant CIECAM.\n On peut voir le résultat final dans la fenêtre histogramme.\n Histogramme de C,s,M avant/après si la cas à cocher "Données CIECAM" est activée.\n (C,s,M) ne sont pas affichés dans le panneau histogramme
TP_COLORAPP_DATACIE;Histogrammes post CIECAM
TP_COLORAPP_DATACIE_TOOLTIP;Quand activé, les histogrammes de fond des courbes CIECAM montrent des valeurs/amplitudes approximatives de J/Q, ou de C:s/M après les ajustements CIECAM.\nCette sélection n'a pas d'incidence sur l'histogramme général.\n\nQuand désactivé, les histogrammes de fond des courbes CIECAM affichent les valeurs Lab avant les ajustements CIECAM
TP_COLORAPP_DEGREE_TOOLTIP;Niveau d'adaptation chromatique CIE CAT 2002\nSi vous sélectionnez " <i>Automatic</i> ", RT essaiera de trouver la meilleure valeur
TP_COLORAPP_DATACIE_TOOLTIP;Quand activé, les histogrammes de fond des courbes CIECAM02 montrent des valeurs/amplitudes approximatives de J/Q, ou de C:s/M après les ajustements CIECAM.\nCette sélection n'a pas d'incidence sur l'histogramme général.\n\nQuand désactivé, les histogrammes de fond des courbes CIECAM affichent les valeurs Lab avant les ajustements CIECAM
TP_COLORAPP_DEGREE_TOOLTIP;Niveau d'adaptation chromatique CIE CAT 2002
TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Si la case est cochée (recommandé), RT calcule une valeur optimale, qui est utilisé par CAT02, mais aussi pour l'ensemble de CIECAM02.\nVous pouvez décocher la case et changer la valeur du curseur; (les valeurs supérieures à 65 sont recommandées)
TP_COLORAPP_EQUAL;Préservé
TP_COLORAPP_GAMUT;Contrôle du gamut (Lab)
TP_COLORAPP_GAMUT_TOOLTIP;Permet le controle du gamut en mode Lab

View File

@ -925,7 +925,8 @@ TP_COLORAPP_CURVEEDITOR3;Color curve
TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (Lab) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel
TP_COLORAPP_DATACIE;Show CIECAM02 output histograms in curves
TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show Lab values before CIECAM02 adjustments
TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002\nIf you check the "Automatic" box (to the right), RT will try to find the best value
TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002
TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RT calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended)
TP_COLORAPP_EQUAL;Equal
TP_COLORAPP_GAMUT;Gamut control (Lab)
TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab mode

View File

@ -192,7 +192,58 @@ namespace rtengine {
//now we have tile dimensions, overlaps
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//adding omp here slows it down
// According to FFTW-Doc 'it is safe to execute the same plan in parallel by multiple threads', so we now create 4 plans
// outside the parallel region and use them inside the parallel region.
// calculate max size of numblox_W.
int max_numblox_W = ceil(((float)(MIN(imwidth,tilewidth)))/(offset))+2*blkrad;
// calculate min size of numblox_W.
int min_numblox_W = ceil(((float)((MIN(imwidth,((numtiles_W - 1) * tileWskip) + tilewidth) ) - ((numtiles_W - 1) * tileWskip)))/(offset))+2*blkrad;
// these are needed only for creation of the plans and will be freed before entering the parallel loop
float * Lbloxtmp;
float * fLbloxtmp;
Lbloxtmp = fftwf_alloc_real(max_numblox_W*TS*TS);
fLbloxtmp = fftwf_alloc_real(max_numblox_W*TS*TS);
int nfwd[2]={TS,TS};
//for DCT:
const fftw_r2r_kind fwdkind[2] = {FFTW_REDFT10, FFTW_REDFT10};
const fftw_r2r_kind bwdkind[2] = {FFTW_REDFT01, FFTW_REDFT01};
fftwf_plan plan_forward_blox[2];
fftwf_plan plan_backward_blox[2];
// Creating the plans with FFTW_MEASURE instead of FFTW_ESTIMATE speeds up the execute a bit
plan_forward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, Lbloxtmp, NULL, 1, TS*TS, fLbloxtmp, NULL, 1, TS*TS, fwdkind, FFTW_MEASURE );
plan_backward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, fLbloxtmp, NULL, 1, TS*TS, Lbloxtmp, NULL, 1, TS*TS, bwdkind, FFTW_MEASURE );
plan_forward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, Lbloxtmp, NULL, 1, TS*TS, fLbloxtmp, NULL, 1, TS*TS, fwdkind, FFTW_MEASURE );
plan_backward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, fLbloxtmp, NULL, 1, TS*TS, Lbloxtmp, NULL, 1, TS*TS, bwdkind, FFTW_MEASURE );
fftwf_free ( Lbloxtmp );
fftwf_free ( fLbloxtmp );
#ifdef _OPENMP
// Calculate number of tiles. If less than omp_get_max_threads(), then limit num_threads to number of tiles
int numtiles = numtiles_W * numtiles_H;
int numthreads = MIN(numtiles,omp_get_max_threads());
//if(options.RgbDenoiseThreadLimit > 0) numthreads = MIN(numthreads,options.RgbDenoiseThreadLimit);
#pragma omp parallel num_threads(numthreads)
#endif
{
//DCT block data storage
float * Lblox;
float * fLblox;
#ifdef _OPENMP
#pragma omp critical
#endif
{
Lblox = fftwf_alloc_real(max_numblox_W*TS*TS);
fLblox = fftwf_alloc_real(max_numblox_W*TS*TS);
}
#ifdef _OPENMP
#pragma omp for schedule(dynamic) collapse(2)
#endif
for (int tiletop=0; tiletop<imheight; tiletop+=tileHskip) {
for (int tileleft=0; tileleft<imwidth; tileleft+=tileWskip) {
@ -202,13 +253,14 @@ namespace rtengine {
int height = tilebottom-tiletop;
//input L channel
array2D<float> Lin(width,height,ARRAY2D_CLEAR_DATA);
array2D<float> Lin(width,height);
//wavelet denoised image
LabImage * labdn = new LabImage(width,height);
//residual between input and denoised L channel
array2D<float> Ldetail(width,height,ARRAY2D_CLEAR_DATA);
//pixel weight
array2D<float> totwt(width,height,ARRAY2D_CLEAR_DATA);//weight for combining DCT blocks
//
//#ifdef _OPENMP
//#pragma omp parallel for
@ -233,9 +285,9 @@ namespace rtengine {
labdn->a[i1][j1] = (X-Y);
labdn->b[i1][j1] = (Y-Z);
Ldetail[i1][j1] = 0;
// Ldetail[i1][j1] = 0;
Lin[i1][j1] = Y;
totwt[i1][j1] = 0;
// totwt[i1][j1] = 0;
}
}
} else {//image is not raw; use Lab parametrization
@ -262,9 +314,9 @@ namespace rtengine {
labdn->a[i1][j1] = (X-Y);
labdn->b[i1][j1] = (Y-Z);
Ldetail[i1][j1] = 0;
// Ldetail[i1][j1] = 0;
Lin[i1][j1] = Y;
totwt[i1][j1] = 0;
// totwt[i1][j1] = 0;
}
}
}
@ -282,21 +334,32 @@ namespace rtengine {
//and whether to subsample the image after wavelet filtering. Subsampling is coded as
//binary 1 or 0 for each level, eg subsampling = 0 means no subsampling, 1 means subsample
//the first level only, 7 means subsample the first three levels, etc.
wavelet_decomposition Ldecomp(labdn->data, labdn->W, labdn->H, 5/*maxlevels*/, 0/*subsampling*/ );
wavelet_decomposition adecomp(labdn->data+datalen, labdn->W, labdn->H, 5, 1 );
wavelet_decomposition bdecomp(labdn->data+2*datalen, labdn->W, labdn->H, 5, 1 );
float noisevarL = SQR((dnparams.luma/125.0f)*(1+ dnparams.luma/25.0f));
float noisevarab = SQR(dnparams.chroma/10.0f);
{ // enclosing this code in a block frees about 120 MB before allocating 20 MB after this block (measured with D700 NEF)
wavelet_decomposition* Ldecomp;
wavelet_decomposition* adecomp;
wavelet_decomposition* bdecomp;
Ldecomp = new wavelet_decomposition (labdn->data, labdn->W, labdn->H, 5/*maxlevels*/, 0/*subsampling*/ );
adecomp = new wavelet_decomposition (labdn->data+datalen, labdn->W, labdn->H, 5, 1 );
bdecomp = new wavelet_decomposition (labdn->data+2*datalen, labdn->W, labdn->H, 5, 1 );
//WaveletDenoiseAll_BiShrink(Ldecomp, adecomp, bdecomp, noisevarL, noisevarab);
WaveletDenoiseAll(Ldecomp, adecomp, bdecomp, noisevarL, noisevarab);
WaveletDenoiseAll(*Ldecomp, *adecomp, *bdecomp, noisevarL, noisevarab);
Ldecomp.reconstruct(labdn->data);
adecomp.reconstruct(labdn->data+datalen);
bdecomp.reconstruct(labdn->data+2*datalen);
Ldecomp->reconstruct(labdn->data);
delete Ldecomp;
adecomp->reconstruct(labdn->data+datalen);
delete adecomp;
bdecomp->reconstruct(labdn->data+2*datalen);
delete bdecomp;
}
//TODO: at this point wavelet coefficients storage can be freed
//Issue 1680: Done now
//second impulse denoise
if (dnparams.luma>0.01) {
@ -316,49 +379,35 @@ namespace rtengine {
// blocks are not the same thing as tiles!
// allocate DCT data structures
// calculation for detail recovery blocks
const int numblox_W = ceil(((float)(width))/(offset))+2*blkrad;
const int numblox_H = ceil(((float)(height))/(offset))+2*blkrad;
//const int nrtiles = numblox_W*numblox_H;
// end of tiling calc
//DCT block data storage
float * Lblox = (float *) fftwf_malloc (numblox_W*TS*TS * sizeof (float));
float * fLblox = (float *) fftwf_malloc (numblox_W*TS*TS * sizeof (float));
//make a plan for FFTW
fftwf_plan plan_forward_blox, plan_backward_blox;
int nfwd[2]={TS,TS};
//for DCT:
const fftw_r2r_kind fwdkind[2] = {FFTW_REDFT10, FFTW_REDFT10};
const fftw_r2r_kind bwdkind[2] = {FFTW_REDFT01, FFTW_REDFT01};
plan_forward_blox = fftwf_plan_many_r2r(2, nfwd, numblox_W, Lblox, NULL, 1, TS*TS, fLblox, NULL, 1, TS*TS, fwdkind, FFTW_ESTIMATE );
plan_backward_blox = fftwf_plan_many_r2r(2, nfwd, numblox_W, fLblox, NULL, 1, TS*TS, Lblox, NULL, 1, TS*TS, bwdkind, FFTW_ESTIMATE );
{
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Main detail recovery algorithm: Block loop
//OpenMP here
//adding omp here leads to artifacts
AlignedBufferMP<float> buffer(width + TS + 2*blkrad*offset);
for (int vblk=0; vblk<numblox_H; vblk++) {
//printf("vblock=%d",vblk);
int vblkmod = vblk%8;
int top = (vblk-blkrad)*offset;
float * buffer = new float [width + TS + 2*blkrad*offset];
float * datarow = buffer+blkrad*offset;
AlignedBuffer<float>* pBuf = buffer.acquire();
// float * buffer = new float [width + TS + 2*blkrad*offset];
float * datarow = (float*)pBuf->data +blkrad*offset;
//#ifdef _OPENMP
//#pragma omp parallel for
//#endif
//TODO: implement using AlignedBufferMP
// #pragma omp parallel for
for (int i=0/*, row=top*/; i<TS; i++/*, row++*/) {
int row = top + i;
int rr = row;
@ -393,13 +442,14 @@ namespace rtengine {
}
}
}//end of filling block row
delete[] buffer;
buffer.release(pBuf);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//fftwf_print_plan (plan_forward_blox);
fftwf_execute_r2r(plan_forward_blox,Lblox,fLblox); // DCT an entire row of tiles
if(numblox_W == max_numblox_W)
fftwf_execute_r2r(plan_forward_blox[0],Lblox,fLblox); // DCT an entire row of tiles
else
fftwf_execute_r2r(plan_forward_blox[1],Lblox,fLblox); // DCT an entire row of tiles
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// now process the vblk row of blocks for noise reduction
for (int hblk=0; hblk<numblox_W; hblk++) {
@ -411,7 +461,10 @@ namespace rtengine {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//now perform inverse FT of an entire row of blocks
fftwf_execute_r2r(plan_backward_blox,fLblox,Lblox); //for DCT
if(numblox_W == max_numblox_W)
fftwf_execute_r2r(plan_backward_blox[0],fLblox,Lblox); //for DCT
else
fftwf_execute_r2r(plan_backward_blox[1],fLblox,Lblox); //for DCT
int topproc = (vblk-blkrad)*offset;
@ -421,20 +474,9 @@ namespace rtengine {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
}//end of vertical block loop
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// clean up
//#pragma omp single nowait
fftwf_destroy_plan( plan_forward_blox );
//#pragma omp single nowait
fftwf_destroy_plan( plan_backward_blox );
fftwf_free ( Lblox);
fftwf_free ( fLblox);
fftwf_cleanup();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for (int i=0; i<height; i++) {
for (int j=0; j<width; j++) {
@ -470,7 +512,7 @@ namespace rtengine {
//convert back to RGB and write to destination array
if (isRAW) {
#ifdef _OPENMP
#pragma omp parallel for
//#pragma omp parallel for
#endif
for (int i=tiletop; i<tilebottom; i++){
int i1 = i-tiletop;
@ -496,7 +538,7 @@ namespace rtengine {
}
} else {
#ifdef _OPENMP
#pragma omp parallel for
//#pragma omp parallel for
#endif
for (int i=tiletop; i<tilebottom; i++){
int i1 = i-tiletop;
@ -534,7 +576,15 @@ namespace rtengine {
}//end of tile row
}//end of tile loop
#ifdef _OPENMP
#pragma omp critical
#endif
{
fftwf_free ( Lblox);
fftwf_free ( fLblox);
}
}
//copy denoised image to output
memcpy (dst->data, dsttmp->data, 3*dst->width*dst->height*sizeof(float));
@ -549,6 +599,13 @@ namespace rtengine {
delete dsttmp;
// destroy the plans
fftwf_destroy_plan( plan_forward_blox[0] );
fftwf_destroy_plan( plan_backward_blox[0] );
fftwf_destroy_plan( plan_forward_blox[1] );
fftwf_destroy_plan( plan_backward_blox[1] );
fftwf_cleanup();
}//end of main RGB_denoise
@ -561,11 +618,10 @@ namespace rtengine {
void ImProcFunctions::RGBtile_denoise (float * fLblox, int vblproc, int hblproc, int numblox_H, int numblox_W, float noisevar_Ldetail ) //for DCT
{
float * nbrwt = new float[TS*TS]; //for DCT
int blkstart = hblproc*TS*TS;
boxabsblur(fLblox+blkstart, nbrwt, 3, 3, TS, TS);//blur neighbor weights for more robust estimation //for DCT
#pragma omp parallel for
for (int n=0; n<TS*TS; n++) { //for DCT
fLblox[blkstart+n] *= (1-expf(-SQR(nbrwt[n])/noisevar_Ldetail));
}//output neighbor averaged result
@ -586,19 +642,19 @@ namespace rtengine {
const int numblox_W = ceil(((float)(width))/(offset));
const float DCTnorm = 1.0f/(4*TS*TS); //for DCT
int imin = MAX(0,-top);
int bottom = MIN( top+TS,height);
int imax = bottom - top;
#ifdef _OPENMP
#pragma omp parallel for
#endif
//add row of tiles to output image
for (int hblk=0; hblk < numblox_W; hblk++) {
int left = (hblk-blkrad)*offset;
int bottom = MIN( top+TS,height);
int right = MIN(left+TS, width);
int imin = MAX(0,-top);
int jmin = MAX(0,-left);
int imax = bottom - top;
int jmax = right - left;
int indx = hblk*TS;
for (int i=imin; i<imax; i++)
@ -719,7 +775,7 @@ namespace rtengine {
//simple wavelet shrinkage
float * sfave = new float[Wlvl_L*Hlvl_L];
array2D<float> edge(Wlvl_L,Hlvl_L);
AlignedBuffer<double>* buffer = new AlignedBuffer<double> (MAX(Wlvl_L,Hlvl_L));
AlignedBufferMP<double>* buffer = new AlignedBufferMP<double> (MAX(Wlvl_L,Hlvl_L));
//printf("\n level=%d \n",lvl);
@ -829,7 +885,8 @@ namespace rtengine {
wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_ab )
{
int maxlvl = WaveletCoeffs_L.maxlevel();
// printf("maxlevel = %d\n",maxlvl);
//omp_set_nested(true);
#ifdef _OPENMP
#pragma omp parallel for
#endif
@ -847,11 +904,12 @@ namespace rtengine {
float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl);
float ** WavCoeffs_a = WaveletCoeffs_a.level_coeffs(lvl);
float ** WavCoeffs_b = WaveletCoeffs_b.level_coeffs(lvl);
// printf("Hab : %d\n", Hlvl_ab);
// printf("Wab : %d\n", Wlvl_ab);
ShrinkAll(WavCoeffs_L, WavCoeffs_a, WavCoeffs_b, lvl, Wlvl_L, Hlvl_L, Wlvl_ab, Hlvl_ab,
skip_L, skip_ab, noisevar_L, noisevar_ab);
}
//omp_set_nested(false);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View File

@ -63,14 +63,14 @@ void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radiu
gaussVertical<float> (tmp1->a, tmp1->a, buffer, src->W, src->H, radius);
gaussVertical<float> (tmp1->b, tmp1->b, buffer, src->W, src->H, radius);
gaussHorizontal<float> (src->L, tmp1->L, buffer, src->W, src->H, radius);
gaussVertical<float> (tmp1->L, tmp1->L, buffer, src->W, src->H, radius);
// gaussHorizontal<float> (src->L, tmp1->L, buffer, src->W, src->H, radius);
// gaussVertical<float> (tmp1->L, tmp1->L, buffer, src->W, src->H, radius);
}
//#ifdef _OPENMP
//#pragma omp parallel for
//#endif
float chromave=0;
float chromave=0;
#ifdef _OPENMP
#pragma omp parallel for reduction(+:chromave)
#endif
for(int i = 0; i < height; i++ ) {
for(int j = 0; j < width; j++) {
float chroma = SQR(src->a[i][j]-tmp1->a[i][j])+SQR(src->b[i][j]-tmp1->b[i][j]);
@ -79,11 +79,17 @@ void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radiu
}
}
chromave /= (height*width);
float threshfactor = (thresh*chromave)/33.f; // Calculated once to eliminate mult inside the next loop
// printf("Chro %f \n",chromave);
#ifdef _OPENMP
#pragma omp parallel for
#endif
// Issue 1674:
// often, CA isn't evenly distributed, e.g. a lot in contrasty regions and none in the sky.
// so it's better to schedule dynamic and let every thread only process 16 rows, to avoid running big threads out of work
// Measured it and in fact gives better performance than without schedule(dynamic,16). Of course, there could be a better
// choice for the chunk_size than 16
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16)
#endif
for(int i = 0; i < height; i++ ) {
for(int j = 0; j < width; j++) {
tmp1->a[i][j] = src->a[i][j];
@ -91,7 +97,7 @@ void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radiu
//test for pixel darker than some fraction of neighborhood ave, near an edge, more saturated than average
/*if (100*tmp1->L[i][j]>50*src->L[i][j] && \*/
/*1000*abs(tmp1->L[i][j]-src->L[i][j])>thresh*(tmp1->L[i][j]+src->L[i][j]) && \*/
if (33.f*fringe[i*width+j]>thresh*chromave) {
if (fringe[i*width+j]>threshfactor) {
float atot=0.f;
float btot=0.f;
float norm=0.f;
@ -142,7 +148,9 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double ra
for (int i=0; i<height; i++)
sraa[i] = new float[width];
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int i=0; i<height; i++)
for (int j=0; j<width; j++) {
sraa[i][j]=src->C_p[i][j]*cos(piid*src->h_p[i][j]);
@ -157,7 +165,9 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double ra
for (int i=0; i<height; i++)
srbb[i] = new float[width];
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int i=0; i<height; i++)
for (int j=0; j<width; j++) {
srbb[i][j]=src->C_p[i][j]*sin(piid*src->h_p[i][j]);
@ -187,10 +197,10 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double ra
}
//#ifdef _OPENMP
//#pragma omp parallel for
//#endif
float chromave=0;
float chromave=0;
#ifdef _OPENMP
#pragma omp parallel for reduction(+:chromave)
#endif
for(int i = 0; i < height; i++ ) {
for(int j = 0; j < width; j++) {
float chroma =SQR(sraa[i][j]-tmaa[i][j])+SQR(srbb[i][j]-tmbb[i][j]);
@ -199,12 +209,17 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double ra
}
}
chromave /= (height*width);
float threshfactor = (thresh*chromave)/33.f; // Calculated once to eliminate mult inside the next loop
// printf("Chromave CAM %f \n",chromave);
// Issue 1674:
// often, CA isn't evenly distributed, e.g. a lot in contrasty regions and none in the sky.
// so it's better to schedule dynamic and let every thread only process 16 rows, to avoid running big threads out of work
// Measured it and in fact gives better performance than without schedule(dynamic,16). Of course, there could be a better
// choice for the chunk_size than 16
#ifdef _OPENMP
#pragma omp parallel for
#pragma omp parallel for schedule(dynamic,16)
#endif
for(int i = 0; i < height; i++ ) {
for(int j = 0; j < width; j++) {
tmaa[i][j] = sraa[i][j];
@ -213,7 +228,7 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double ra
//test for pixel darker than some fraction of neighborhood ave, near an edge, more saturated than average
/*if (100*tmp1->L[i][j]>50*src->L[i][j] && \*/
/*1000*abs(tmp1->L[i][j]-src->L[i][j])>thresh*(tmp1->L[i][j]+src->L[i][j]) && \*/
if (33.f*fringe[i*width+j]>thresh*chromave) {
if (fringe[i*width+j]>threshfactor) {
float atot=0.f;
float btot=0.f;
float norm=0.f;

View File

@ -70,6 +70,14 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
volatile double progress = 0.0;
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Issue 1676
// Moved from inside the parallel section
if (plistener) {
plistener->setProgressStr ("AMaZE Demosaicing...");
plistener->setProgress (0.0);
}
#pragma omp parallel
{
//position of top/left corner of the tile
@ -194,10 +202,6 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (plistener) {
plistener->setProgressStr ("AMaZE Demosaicing...");
plistener->setProgress (0.0);
}
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -212,7 +216,10 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
// Main algorithm: Tile loop
//#pragma omp parallel for shared(rawData,height,width,red,green,blue) private(top,left) schedule(dynamic)
//code is openmp ready; just have to pull local tile variable declarations inside the tile loop
#pragma omp for schedule(dynamic) nowait
// Issue 1676
// use collapse(2) to collapse the 2 loops to one large loop, so there is better scaling
#pragma omp for schedule(dynamic) collapse(2) nowait
for (top=winy-16; top < winy+height; top += TS-32)
for (left=winx-16; left < winx+width; left += TS-32) {
//location of tile bottom edge

View File

@ -1905,28 +1905,9 @@ void ColorTemp::calculate_abfloat( float &aa, float &bb, float h, float e, floa
}
void ColorTemp::xyz2jchqms_ciecam02( double &J, double &C, double &h, double &Q, double &M, double &s,double &aw, double &fl, double &wh,
double x, double y, double z, double xw, double yw, double zw,
double yb, double la, double f, double c, double nc, double pilotd, bool doneinit, int gamu)
void ColorTemp::initcam1(double gamu, double yb, double pilotd, double f, double la, double xw, double yw, double zw, double &n, double &d, double &nbb, double &ncb,
double &cz, double &aw, double &wh, double &pfl, double &fl, double &c)
{
double r, g, b;
double rw, gw, bw;
double rc, gc, bc;
double rp, gp, bp;
double rpa, gpa, bpa;
double a, ca, cb;
double d;
double n, nbb, ncb;
double e, t;
double cz;
double myh, myj, myc, myq, mym, mys;
double pfl;
gamu=1;
xyz_to_cat02( r, g, b, x, y, z, gamu );
xyz_to_cat02( rw, gw, bw, xw, yw, zw, gamu );
if(doneinit){//if one day, we have a pipette...
n = yb / yw;
if(pilotd==2.0) d = d_factor( f, la );else d=pilotd;
fl = calculate_fl_from_la_ciecam02( la );
@ -1935,9 +1916,74 @@ void ColorTemp::xyz2jchqms_ciecam02( double &J, double &C, double &h, double &Q,
aw = achromatic_response_to_white( xw, yw, zw, d, fl, nbb, gamu );
wh =( 4.0 / c ) * ( aw + 4.0 ) * pow( fl, 0.25 );
pfl = pow( fl, 0.25 );
doneinit=false;
}
#ifdef _DEBUG
if (settings->verbose) printf("Source double d=%f aw=%f fl=%f wh=%f\n",d,aw,fl,wh);
#endif
}
void ColorTemp::initcam1float(float gamu, float yb, float pilotd, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb,
float &cz, float &aw, float &wh, float &pfl, float &fl, float &c)
{
n = yb / yw;
if(pilotd==2.0) d = d_factorfloat( f, la );else d=pilotd;
fl = calculate_fl_from_la_ciecam02float( la );
nbb = ncb = 0.725f * pow_F( 1.0f / n, 0.2f );
cz = 1.48f + sqrt( n );
aw = achromatic_response_to_whitefloat( xw, yw, zw, d, fl, nbb, gamu );
wh =( 4.0f / c ) * ( aw + 4.0f ) * pow_F( fl, 0.25f );
pfl = pow_F( fl, 0.25f );
#ifdef _DEBUG
if (settings->verbose) printf("Source float d=%f aw=%f fl=%f wh=%f\n",d,aw,fl,wh);
#endif
}
void ColorTemp::initcam2(double gamu, double yb, double f, double la, double xw, double yw, double zw, double &n, double &d, double &nbb, double &ncb,
double &cz, double &aw, double &fl)
{
n = yb / yw;
d = d_factor( f, la );
fl = calculate_fl_from_la_ciecam02( la );
nbb = ncb = 0.725 * pow( 1.0 / n, 0.2 );
cz = 1.48 + sqrt( n );
aw = achromatic_response_to_white( xw, yw, zw, d, fl, nbb, gamu );
#ifdef _DEBUG
if (settings->verbose) printf("Viewing double d=%f aw=%f fl=%f n=%f\n",d,aw,fl,n);
#endif
}
void ColorTemp::initcam2float(float gamu, float yb, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb,
float &cz, float &aw, float &fl)
{
n = yb / yw;
d = d_factorfloat( f, la );
fl = calculate_fl_from_la_ciecam02float( la );
nbb = ncb = 0.725f * pow_F( 1.0f / n, 0.2f );
cz = 1.48f + sqrt( n );
aw = achromatic_response_to_whitefloat( xw, yw, zw, d, fl, nbb, gamu );
#ifdef _DEBUG
if (settings->verbose) printf("Viewing float d=%f aw=%f fl=%f n=%f\n",d,aw,fl,n);
#endif
}
void ColorTemp::xyz2jchqms_ciecam02( double &J, double &C, double &h, double &Q, double &M, double &s,double &aw, double &fl, double &wh,
double x, double y, double z, double xw, double yw, double zw,
double yb, double la, double f, double c, double nc, double pilotd, int gamu , double n, double nbb, double ncb, double pfl, double cz, double d)
{
double r, g, b;
double rw, gw, bw;
double rc, gc, bc;
double rp, gp, bp;
double rpa, gpa, bpa;
double a, ca, cb;
double e, t;
double myh, myj, myc, myq, mym, mys;
gamu=1;
xyz_to_cat02( r, g, b, x, y, z, gamu );
xyz_to_cat02( rw, gw, bw, xw, yw, zw, gamu );
rc = r * (((yw * d) / rw) + (1.0 - d));
gc = g * (((yw * d) / gw) + (1.0 - d));
bc = b * (((yw * d) / bw) + (1.0 - d));
@ -1997,38 +2043,23 @@ void ColorTemp::xyz2jchqms_ciecam02( double &J, double &C, double &h, double &Q,
}
void ColorTemp::xyz2jchqms_ciecam02float( float &J, float &C, float &h, float &Q, float &M, float &s,float &aw, float &fl, float &wh,
float x, float y, float z, float xw, float yw, float zw,
float yb, float la, float f, float c, float nc, float pilotd, bool doneinit, int gamu)
{
float yb, float la, float f, float c, float nc, float pilotd, int gamu, float n, float nbb, float ncb, float pfl, float cz, float d)
{
float r, g, b;
float rw, gw, bw;
float rc, gc, bc;
float rp, gp, bp;
float rpa, gpa, bpa;
float a, ca, cb;
float d;
float n, nbb, ncb;
float e, t;
float cz;
float myh, myj, myc, myq, mym, mys;
float pfl;
gamu=1;
xyz_to_cat02float( r, g, b, x, y, z, gamu );
xyz_to_cat02float( rw, gw, bw, xw, yw, zw, gamu );
if(doneinit){//if one day, we have a pipette...
n = yb / yw;
if(pilotd==2.0) d = d_factorfloat( f, la );else d=pilotd;
fl = calculate_fl_from_la_ciecam02float( la );
nbb = ncb = 0.725f * pow_F( 1.0f / n, 0.2f );
cz = 1.48f + sqrt( n );
aw = achromatic_response_to_whitefloat( xw, yw, zw, d, fl, nbb, gamu );
wh =( 4.0f / c ) * ( aw + 4.0f ) * pow_F( fl, 0.25f );
pfl = pow_F( fl, 0.25f );
doneinit=false;
}
rc = r * (((yw * d) / rw) + (1.0 - d));
gc = g * (((yw * d) / gw) + (1.0 - d));
bc = b * (((yw * d) / bw) + (1.0 - d));
@ -2089,33 +2120,19 @@ void ColorTemp::xyz2jchqms_ciecam02float( float &J, float &C, float &h, float &Q
}
void ColorTemp::jch2xyz_ciecam02( double &x, double &y, double &z, double J, double C, double h,
double xw, double yw, double zw, double yb, double la,
double f, double c, double nc , bool doneinit2, int gamu)
double f, double c, double nc , int gamu, double n, double nbb, double ncb, double fl, double cz, double d, double aw )
{
double r, g, b;
double rc, gc, bc;
double rp, gp, bp;
double rpa, gpa, bpa;
double rw, gw, bw;
double fl, d;
double n, nbb, ncb;
double a, ca, cb;
double aw;
double e, t;
double cz;
gamu=1;
ColorTemp::xyz_to_cat02( rw, gw, bw, xw, yw, zw, gamu );
if(doneinit2){
n = yb / yw;
d = d_factor( f, la );
fl = calculate_fl_from_la_ciecam02( la );
nbb = ncb = 0.725 * pow( 1.0 / n, 0.2 );
cz = 1.48 + sqrt( n );
aw = achromatic_response_to_white( xw, yw, zw, d, fl, nbb, gamu );
doneinit2=false;
}
e = ((12500.0 / 13.0) * nc * ncb) * (cos( ((h * M_PI) / 180.0) + 2.0 ) + 3.8);
a = pow( J / 100.0, 1.0 / (c * cz) ) * aw;
t = pow( C / (sqrt( J / 100) * pow( 1.64 - pow( 0.29, n ), 0.73 )), 10.0 / 9.0 );
@ -2139,30 +2156,18 @@ void ColorTemp::jch2xyz_ciecam02( double &x, double &y, double &z, double J, dou
void ColorTemp::jch2xyz_ciecam02float( float &x, float &y, float &z, float J, float C, float h,
float xw, float yw, float zw, float yb, float la,
float f, float c, float nc , bool doneinit2, int gamu)
float f, float c, float nc , int gamu, float n, float nbb, float ncb, float fl, float cz, float d, float aw)
{
float r, g, b;
float rc, gc, bc;
float rp, gp, bp;
float rpa, gpa, bpa;
float rw, gw, bw;
float fl, d;
float n, nbb, ncb;
float a, ca, cb;
float aw;
float e, t;
float cz;
gamu=1;
ColorTemp::xyz_to_cat02float( rw, gw, bw, xw, yw, zw, gamu );
if(doneinit2){
n = yb / yw;
d = d_factorfloat( f, la );
fl = calculate_fl_from_la_ciecam02float( la );
nbb = ncb = 0.725f * pow_F( 1.0f / n, 0.2f );
cz = 1.48f + sqrt( n );
aw = achromatic_response_to_whitefloat( xw, yw, zw, d, fl, nbb, gamu );
doneinit2=false;
}
e = ((12500.0f / 13.0f) * nc * ncb) * (cos( ((h * M_PI) / 180.0f) + 2.0f ) + 3.8f);
a = pow_F( J / 100.0f, 1.0f / (c * cz) ) * aw;
t = pow_F( C / (sqrt( J / 100.f) * pow_F( 1.64f - pow_F( 0.29f, n ), 0.73f )), 10.0f / 9.0f );

View File

@ -298,30 +298,42 @@ class ColorTemp {
double J, double C, double h,
double xw, double yw, double zw,
double yb, double la,
double f, double c, double nc, bool doneinit2, int gamu );
double f, double c, double nc, int gamu, double n, double nbb, double ncb, double fl, double cz, double d, double aw);
static void jch2xyz_ciecam02float( float &x, float &y, float &z,
float J, float C, float h,
float xw, float yw, float zw,
float yb, float la,
float f, float c, float nc, bool doneinit2, int gamu );
float f, float c, float nc,int gamu,float n, float nbb, float ncb, float fl, float cz, float d, float aw );
/**
* Forward transform from XYZ to CIECAM02 JCh.
*/
static void initcam1(double gamu, double yb, double pilotd, double f, double la, double xw, double yw, double zw, double &n, double &d, double &nbb, double &ncb,
double &cz, double &aw, double &wh, double &pfl, double &fl, double &c);
static void initcam2(double gamu, double yb, double f, double la, double xw, double yw, double zw, double &n, double &d, double &nbb, double &ncb,
double &cz, double &aw, double &fl);
static void initcam1float(float gamu, float yb, float pilotd, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb,
float &cz, float &aw, float &wh, float &pfl, float &fl, float &c);
static void initcam2float(float gamu, float yb, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb,
float &cz, float &aw, float &fl);
static void xyz2jchqms_ciecam02( double &J, double &C, double &h,
double &Q, double &M, double &s,double &aw, double &fl, double &wh,
double x, double y, double z,
double xw, double yw, double zw,
double yb, double la,
double f, double c, double nc, double pilotd, bool doneinit1, int gamu );
double f, double c, double nc, double pilotd,int gamu , double n, double nbb, double ncb, double pfl, double cz, double d );
static void xyz2jchqms_ciecam02float( float &J, float &C, float &h,
float &Q, float &M, float &s,float &aw, float &fl, float &wh,
float x, float y, float z,
float xw, float yw, float zw,
float yb, float la,
float f, float c, float nc, float pilotd, bool doneinit1, int gamu );
float f, float c, float nc, float pilotd, int gamu, float n, float nbb, float ncb, float pfl, float cz, float d );
};

View File

@ -202,9 +202,12 @@ void Crop::update (int todo) {
}
int begh = 0, endh = labnCrop->H;
bool execsharp=false;
float d;
double dd;
if(skip==1) execsharp=true;
if(settings->ciecamfloat) parent->ipf.ciecam_02float (cieCrop,begh, endh, 1,labnCrop, &params,parent->customColCurve1,parent->customColCurve2,parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp);
else parent->ipf.ciecam_02 (cieCrop,begh, endh, 1,labnCrop, &params,parent->customColCurve1,parent->customColCurve2,parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp);
if(settings->ciecamfloat) {parent->ipf.ciecam_02float (cieCrop,begh, endh, 1,labnCrop, &params,parent->customColCurve1,parent->customColCurve2,parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp, d);
}
else {parent->ipf.ciecam_02 (cieCrop,begh, endh, 1,labnCrop, &params,parent->customColCurve1,parent->customColCurve2,parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp, dd);}
}
// switch back to rgb
parent->ipf.lab2monitorRgb (labnCrop, cropImg);

View File

@ -55,6 +55,7 @@ class Crop : public DetailedCrop {
bool cropAllocated;
DetailedCropListener* cropImageListener;
Glib::Mutex cropMutex;
ImProcCoordinator* parent;

View File

@ -70,7 +70,7 @@ ImProcCoordinator::ImProcCoordinator ()
bcurvehist(256), bcurvehistCropped(256), bbeforehist(256),
pW(-1), pH(-1),
plistener(NULL), imageListener(NULL), aeListener(NULL), hListener(NULL),
plistener(NULL), imageListener(NULL), aeListener(NULL), hListener(NULL),acListener(NULL),
resultValid(false), changeSinceLast(0), updaterRunning(false), destroying(false)
{}
@ -423,12 +423,18 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
int Iterates=0;
int begh=0;
int endh=pH;
float d;
double dd;
float **buffer = new float*[pH];
for (int i=0; i<pH; i++)
buffer[i] = new float[pW];
if(settings->ciecamfloat) ipf.ciecam_02float (ncie, begh, endh, pW, nprevl, &params, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, true);
else ipf.ciecam_02 (ncie, begh, endh, pW, nprevl, &params, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, true);
if(settings->ciecamfloat){ipf.ciecam_02float (ncie, begh, endh, pW, nprevl, &params, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, true, d);
if(params.colorappearance.autodegree && acListener && params.colorappearance.enabled) acListener->autoCamChanged(100.*(double)d);
}
else {ipf.ciecam_02 (ncie, begh, endh, pW, nprevl, &params, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, true, dd);
if(params.colorappearance.autodegree && acListener && params.colorappearance.enabled) acListener->autoCamChanged(100.*dd);
}
for (int i=0; i<pH; i++)
delete [] buffer[i];
delete [] buffer;

View File

@ -115,6 +115,7 @@ class ImProcCoordinator : public StagedImageProcessor {
ProgressListener* plistener;
PreviewImageListener* imageListener;
AutoExpListener* aeListener;
AutoCamListener* acListener;
HistogramListener* hListener;
std::vector<SizeListener*> sizeListeners;
@ -184,6 +185,7 @@ class ImProcCoordinator : public StagedImageProcessor {
void delSizeListener (SizeListener* il) {std::vector<SizeListener*>::iterator it = std::find (sizeListeners.begin(), sizeListeners.end(), il); if (it!=sizeListeners.end()) sizeListeners.erase (it); }
void setAutoExpListener (AutoExpListener* ael) {aeListener = ael; }
void setHistogramListener(HistogramListener *h) {hListener = h; }
void setAutoCamListener (AutoCamListener* acl) {acListener = acl; }
void saveInputICCReference (const Glib::ustring& fname);

View File

@ -40,6 +40,8 @@
#include "boxblur.h"
#include "rt_math.h"
#include "EdgePreservingDecomposition.h"
#include "improccoordinator.h"
#ifdef _OPENMP
#include <omp.h>
#endif
@ -62,10 +64,8 @@ namespace rtengine {
extern const Settings* settings;
LUTf ImProcFunctions::cachef ;
LUTf ImProcFunctions::gamma2curve = 0;
void ImProcFunctions::initCache () {
int maxindex = 65536;
@ -237,7 +237,7 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par
}
// Copyright (c) 2012 Jacques Desmis <jdesmis@gmail.com>
void ImProcFunctions::ciecam_02 (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve2,const ColorAppearance & customColCurve3, LUTu & histLCAM, LUTu & histCCAM, int Iterates, int scale, float** buffer, bool execsharp)
void ImProcFunctions::ciecam_02 (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve2,const ColorAppearance & customColCurve3, LUTu & histLCAM, LUTu & histCCAM, int Iterates, int scale, float** buffer, bool execsharp, double &d)
{
if(params->colorappearance.enabled) {
@ -283,7 +283,7 @@ if(params->colorappearance.enabled) {
Yw=1.0;
double Xw, Zw;
double f,c,nc,yb,la,xw,yw,zw,f2,c2,nc2,yb2,la2;
double z,fl,n,nbb,ncb,d,aw;
double z,fl,n,nbb,ncb,aw;
double xwd,ywd,zwd;
int alg=0;
float sum=0.f;
@ -409,10 +409,16 @@ if(params->colorappearance.enabled) {
// settings of WB: scene and viewing
if(params->colorappearance.wbmodel=="RawT") {xw1=96.46;yw1=100.0;zw1=82.445;xw2=xwd;yw2=ywd;zw2=zwd;} //use RT WB; CAT 02 is used for output device (see prefreneces)
else if(params->colorappearance.wbmodel=="RawTCAT02") {xw1=xw;yw1=yw;zw1=zw;xw2=xwd;yw2=ywd;zw2=zwd;} // Settings RT WB are used for CAT02 => mix , CAT02 is use for output device (screen: D50 D65, projector: lamp, LED) see preferences
bool doneinit=true;
bool doneinit2=true;
double cz,wh, pfl;
ColorTemp::initcam1(gamu, yb, pilot, f, la,xw, yw, zw, n, d, nbb, ncb,cz, aw, wh, pfl, fl, c);
double nj,dj,nbbj,ncbj,czj,awj,flj;
ColorTemp::initcam2(gamu,yb2, f2, la2, xw2, yw2, zw2, nj, dj, nbbj, ncbj,czj, awj, flj);
#ifndef _DEBUG
#pragma omp parallel default(shared) firstprivate(lab,xw1,xw2,yw1,yw2,zw1,zw2,pilot,jli,chr,yb,la,yb2,la2,fl,nc,f,c, height,width,begh, endh, doneinit,doneinit2, nc2,f2,c2, alg, gamu, highlight, rstprotection, pW)
#pragma omp parallel default(shared) firstprivate(lab,xw1,xw2,yw1,yw2,zw1,zw2,pilot,jli,chr,yb,la,yb2,la2,fl,nc,f,c, height,width,begh, endh,nc2,f2,c2, alg, gamu, highlight, rstprotection, pW)
#endif
{ //matrix for current working space
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working);
@ -437,7 +443,9 @@ if(params->colorappearance.enabled) {
double epsil=0.0001;
//convert Lab => XYZ
Color::Lab2XYZ(L, a, b, x1, y1, z1);
double J, C, h, Q, M, s, aw, fl, wh;
// double J, C, h, Q, M, s, aw, fl, wh;
double J, C, h, Q, M, s;
double Jp,Cpr;
double Jpro,Cpro, hpro, Qpro, Mpro, spro;
bool t1L=false;
@ -447,7 +455,7 @@ if(params->colorappearance.enabled) {
int c1C=0;
int c1s=0;
int c1co=0;
//double n,nbb,ncb,pfl,cz,d;
x=(double)x1/655.35;
y=(double)y1/655.35;
z=(double)z1/655.35;
@ -457,7 +465,7 @@ if(params->colorappearance.enabled) {
x, y, z,
xw1, yw1, zw1,
yb, la,
f, c, nc, pilot, doneinit, gamu );
f, c, nc, pilot, gamu , n, nbb, ncb, pfl, cz, d );
Jpro=J;
Cpro=C;
hpro=h;
@ -698,12 +706,13 @@ if(params->colorappearance.enabled) {
}
}
double xx,yy,zz;
//double nj, nbbj, ncbj, flj, czj, dj, awj;
//process normal==> viewing
ColorTemp::jch2xyz_ciecam02( xx, yy, zz,
J, C, h,
xw2, yw2, zw2,
yb2, la2,
f2, c2, nc2, doneinit2, gamu);
f2, c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj);
x=(float)xx*655.35;
y=(float)yy*655.35;
z=(float)zz*655.35;
@ -814,7 +823,7 @@ if((params->colorappearance.tonecie || (params->colorappearance.tonecie && param
#ifndef _DEBUG
#pragma omp parallel default(shared) firstprivate(lab,xw2,yw2,zw2,chr,yb,la2,yb2, height,width,begh, endh,doneinit2, nc2,f2,c2, gamu, highlight,pW)
#pragma omp parallel default(shared) firstprivate(lab,xw2,yw2,zw2,chr,yb,la2,yb2, height,width,begh, endh, nc2,f2,c2, gamu, highlight,pW)
#endif
{
TMatrix wiprofa = iccStore->workingSpaceInverseMatrix (params->icm.working);
@ -867,11 +876,12 @@ if((params->colorappearance.tonecie || (params->colorappearance.tonecie && param
}
}
//end histograms
// double nd, nbbd, ncbd, fld, czd, dd, awd;
ColorTemp::jch2xyz_ciecam02( xx, yy, zz,
ncie->J_p[i][j], ncie->C_p[i][j], ncie->h_p[i][j],
xw2, yw2, zw2,
yb2, la2,
f2, c2, nc2, doneinit2, gamu);
f2, c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj);
x=(float)xx*655.35;
y=(float)yy*655.35;
z=(float)zz*655.35;
@ -941,11 +951,10 @@ if((params->colorappearance.tonecie || (params->colorappearance.tonecie && param
// Copyright (c) 2012 Jacques Desmis <jdesmis@gmail.com>
void ImProcFunctions::ciecam_02float (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve2,const ColorAppearance & customColCurve3, LUTu & histLCAM, LUTu & histCCAM, int Iterates, int scale, float** buffer, bool execsharp)
void ImProcFunctions::ciecam_02float (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve2,const ColorAppearance & customColCurve3, LUTu & histLCAM, LUTu & histCCAM, int Iterates, int scale, float** buffer, bool execsharp, float &d)
{
if(params->colorappearance.enabled) {
//printf("ciecam float\n");
#ifdef _DEBUG
MyTime t1e,t2e;
t1e.set();
@ -987,8 +996,8 @@ if(params->colorappearance.enabled) {
float Yw;
Yw=1.0;
double Xw, Zw;
float f,c,nc,yb,la,xw,yw,zw,f2,c2,nc2,yb2,la2;
float z,fl,n,nbb,ncb,d,aw;
float f,nc,yb,la,c,xw,yw,zw,f2,c2,nc2,yb2,la2;
float z,fl,n,nbb,ncb,aw;//d
float xwd,ywd,zwd;
int alg=0;
float sum=0.f;
@ -1114,10 +1123,14 @@ if(params->colorappearance.enabled) {
// settings of WB: scene and viewing
if(params->colorappearance.wbmodel=="RawT") {xw1=96.46;yw1=100.0;zw1=82.445;xw2=xwd;yw2=ywd;zw2=zwd;} //use RT WB; CAT 02 is used for output device (see prefreneces)
else if(params->colorappearance.wbmodel=="RawTCAT02") {xw1=xw;yw1=yw;zw1=zw;xw2=xwd;yw2=ywd;zw2=zwd;} // Settings RT WB are used for CAT02 => mix , CAT02 is use for output device (screen: D50 D65, projector: lamp, LED) see preferences
bool doneinit=true;
bool doneinit2=true;
float cz,wh, pfl;
ColorTemp::initcam1float(gamu, yb, pilot, f, la,xw, yw, zw, n, d, nbb, ncb,cz, aw, wh, pfl, fl, c);
float nj,dj,nbbj,ncbj,czj,awj,flj;
ColorTemp::initcam2float(gamu,yb2, f2, la2, xw2, yw2, zw2, nj, dj, nbbj, ncbj,czj, awj, flj);
#ifndef _DEBUG
#pragma omp parallel default(shared) firstprivate(lab,xw1,xw2,yw1,yw2,zw1,zw2,pilot,jli,chr,yb,la,yb2,la2,fl,nc,f,c, height,width,begh, endh, doneinit,doneinit2, nc2,f2,c2, alg, gamu, highlight, rstprotection, pW)
#pragma omp parallel default(shared) firstprivate(lab,xw1,xw2,yw1,yw2,zw1,zw2,pilot,jli,chr,yb,la,yb2,la2,fl,nc,f,c, height,width,begh, endh,nc2,f2,c2, alg, gamu, highlight, rstprotection, pW,nj, nbbj, ncbj, flj, czj, dj, awj, n, nbb, ncb, pfl, cz)
#endif
{ //matrix for current working space
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working);
@ -1142,7 +1155,8 @@ if(params->colorappearance.enabled) {
float epsil=0.0001;
//convert Lab => XYZ
Color::Lab2XYZ(L, a, b, x1, y1, z1);
float J, C, h, Q, M, s, aw, fl, wh;
// float J, C, h, Q, M, s, aw, fl, wh;
float J, C, h, Q, M, s;
float Jp,Cpr;
float Jpro,Cpro, hpro, Qpro, Mpro, spro;
bool t1L=false;
@ -1152,6 +1166,7 @@ if(params->colorappearance.enabled) {
int c1C=0;
int c1s=0;
int c1co=0;
// float n,nbb,ncb,pfl,cz,d;
x=(float)x1/655.35f;
y=(float)y1/655.35f;
@ -1162,7 +1177,7 @@ if(params->colorappearance.enabled) {
x, y, z,
xw1, yw1, zw1,
yb, la,
f, c, nc, pilot, doneinit, gamu );
f, c, nc, pilot, gamu, n, nbb, ncb, pfl, cz, d);
Jpro=J;
Cpro=C;
hpro=h;
@ -1404,11 +1419,13 @@ if(params->colorappearance.enabled) {
}
float xx,yy,zz;
//process normal==> viewing
//float nj, nbbj, ncbj, flj, czj, dj, awj;
ColorTemp::jch2xyz_ciecam02float( xx, yy, zz,
J, C, h,
xw2, yw2, zw2,
yb2, la2,
f2, c2, nc2, doneinit2, gamu);
f2, c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj);
x=(float)xx*655.35f;
y=(float)yy*655.35f;
z=(float)zz*655.35f;
@ -1521,7 +1538,7 @@ if((params->colorappearance.tonecie && (params->edgePreservingDecompositionUI.en
#ifndef _DEBUG
#pragma omp parallel default(shared) firstprivate(lab,xw2,yw2,zw2,chr,yb,la2,yb2, height,width,begh, endh,doneinit2, nc2,f2,c2, gamu, highlight,pW)
#pragma omp parallel default(shared) firstprivate(lab,xw2,yw2,zw2,chr,yb,la2,yb2, height,width,begh, endh, nc2,f2,c2, gamu, highlight,pW,nj, nbbj, ncbj, flj, czj, dj, awj)
#endif
{
TMatrix wiprofa = iccStore->workingSpaceInverseMatrix (params->icm.working);
@ -1574,11 +1591,12 @@ if((params->colorappearance.tonecie && (params->edgePreservingDecompositionUI.en
}
}
//end histograms
ColorTemp::jch2xyz_ciecam02float( xx, yy, zz,
ncie->J_p[i][j], ncie->C_p[i][j], ncie->h_p[i][j],
xw2, yw2, zw2,
yb2, la2,
f2, c2, nc2, doneinit2, gamu);
f2, c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj);
x=(float)xx*655.35f;
y=(float)yy*655.35f;
z=(float)zz*655.35f;

View File

@ -69,6 +69,7 @@ class ImProcFunctions {
public:
bool iGamma; // true if inverse gamma has to be applied in rgbProc
double g;
@ -94,8 +95,8 @@ class ImProcFunctions {
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2,
double expcomp, int hlcompr, int hlcomprthresh);
void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve);
void ciecam_02float (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, LUTu &histLCAM, LUTu &histCCAM,int Iterates, int scale, float** buffer, bool execsharp );
void ciecam_02 (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, LUTu &histLCAM, LUTu &histCCAM,int Iterates, int scale, float** buffer, bool execsharp );
void ciecam_02float (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, LUTu &histLCAM, LUTu &histCCAM,int Iterates, int scale, float** buffer, bool execsharp, float &d);
void ciecam_02 (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, LUTu &histLCAM, LUTu &histCCAM,int Iterates, int scale, float** buffer, bool execsharp, double &d);
void chromiLuminanceCurve (int pW, LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve,LUTf & satclcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, LUTu &histCCurve);
void vibrance (LabImage* lab);//Jacques' vibrance
void colorCurve (LabImage* lold, LabImage* lnew);

View File

@ -62,9 +62,9 @@ void ImProcFunctions::impulse_nr (LabImage* lab, double thresh) {
int i1, j1;
//rangeblur<unsigned short, unsigned int> (lab->L, lpf, impish /*used as buffer here*/, width, height, thresh, false);
#ifdef _OPENMP
#pragma omp parallel
#endif
#ifdef _OPENMP
#pragma omp parallel
#endif
{
AlignedBufferMP<double> buffer(max(width,height));
@ -75,7 +75,11 @@ void ImProcFunctions::impulse_nr (LabImage* lab, double thresh) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
float impthr = max(1.0,5.5-thresh);
float impthrDiv24 = impthr / 24.0f; //Issue 1671: moved the Division outside the loop, impthr can be optimized out too, but I let in the code at the moment
#ifdef _OPENMP
#pragma omp parallel for private(hpfabs, hfnbrave,i1,j1)
#endif
for (int i=0; i < height; i++)
for (int j=0; j < width; j++) {
@ -85,11 +89,19 @@ void ImProcFunctions::impulse_nr (LabImage* lab, double thresh) {
for (j1=max(0,j-2); j1<=min(j+2,width-1); j1++ ) {
hfnbrave += fabs(lab->L[i1][j1]-lpf[i1][j1]);
}
hfnbrave = (hfnbrave-hpfabs)/24;
hpfabs>(hfnbrave*impthr) ? impish[i][j]=1 : impish[i][j]=0;
impish[i][j] = (hpfabs>((hfnbrave-hpfabs)*impthrDiv24));
}//now impulsive values have been identified
// Issue 1671:
// often, noise isn't evenly distributed, e.g. only a few noisy pixels in the bright sky, but many in the dark foreground,
// so it's better to schedule dynamic and let every thread only process 16 rows, to avoid running big threads out of work
// Measured it and in fact gives better performance than without schedule(dynamic,16). Of course, there could be a better
// choice for the chunk_size than 16
// race conditions are avoided by the array impish
#ifdef _OPENMP
#pragma omp parallel for private(wtdsum,norm,dirwt,i1,j1) schedule(dynamic,16)
#endif
for (int i=0; i < height; i++)
for (int j=0; j < width; j++) {
if (!impish[i][j]) continue;

View File

@ -249,6 +249,10 @@ namespace rtengine {
virtual void autoExpChanged (double brightness, int bright, int contrast, int black, int hlcompr, int hlcomprthresh) {}
};
class AutoCamListener {
public :
virtual void autoCamChanged (double ccam) {}
};
/** This class represents a detailed part of the image (looking through a kind of window).
* It can be created and destroyed with the appropriate members of StagedImageProcessor.
* Several crops can be assigned to the same image. */
@ -328,6 +332,7 @@ namespace rtengine {
virtual void setAutoExpListener (AutoExpListener* l) =0;
virtual void setHistogramListener (HistogramListener *l) =0;
virtual void setPreviewImageListener (PreviewImageListener* l) =0;
virtual void setAutoCamListener (AutoCamListener* l) =0;
virtual ~StagedImageProcessor () {}

View File

@ -798,7 +798,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
for (int i=0; i<fh; i++)
buffer[i] = new float[fw];
bool execsharp=false;
ipf.ciecam_02float (cieView, begh, endh, 1, labView, &params,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 6, (float**)buffer, execsharp);
float d;
ipf.ciecam_02float (cieView, begh, endh, 1, labView, &params,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 6, (float**)buffer, execsharp, d);
for (int i=0; i<fh; i++)
delete [] buffer[i];
delete [] buffer; buffer=NULL;
@ -812,7 +813,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
delete labView;
delete baseImg;
delete cieView;
/* // calculate scale
// calculate scale
if (params.coarse.rotate==90 || params.coarse.rotate==270)
myscale = scale * thumbImg->width / fh;
else
@ -820,7 +821,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
myscale = 1.0 / myscale;
// apply crop
/* // apply crop
if (params.crop.enabled) {
int ix = 0;
for (int i=0; i<fh; i++)

View File

@ -290,11 +290,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
customColCurve3,
1);
if (params.sharpening.enabled) {
float d;
double dd;
float** buffer = new float*[fh];
for (int i=0; i<fh; i++)
buffer[i] = new float[fw];
if(settings->ciecamfloat) ipf.ciecam_02float (cieView, begh, endh,1, labView, &params,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true);
else ipf.ciecam_02 (cieView, begh, endh,1, labView, &params,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true);
if(settings->ciecamfloat) ipf.ciecam_02float (cieView, begh, endh,1, labView, &params,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true, d);
else ipf.ciecam_02 (cieView, begh, endh,1, labView, &params,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true, dd);
for (int i=0; i<fh; i++)
delete [] buffer[i];
@ -302,11 +304,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
}
else {
int f_h=2,f_w=2;
float d;
double dd;
float** buffer = new float*[f_h];
for (int i=0; i<f_h; i++)
buffer[i] = new float[f_w];
if(settings->ciecamfloat) ipf.ciecam_02float (cieView, begh, endh,1, labView, &params,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true);
else ipf.ciecam_02 (cieView, begh, endh,1, labView, &params,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true);
if(settings->ciecamfloat) ipf.ciecam_02float (cieView, begh, endh,1, labView, &params,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true, d);
else ipf.ciecam_02 (cieView, begh, endh,1, labView, &params,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true, dd);
for (int i=0; i<f_h; i++)
delete [] buffer[i];

View File

@ -185,12 +185,12 @@ Adjuster::~Adjuster () {
if (automatic) delete automatic;
}
void Adjuster::addAutoButton () {
void Adjuster::addAutoButton (Glib::ustring tooltip) {
if (!automatic) {
automatic = new Gtk::CheckButton ();
//automatic->add (*Gtk::manage (new RTImage ("processing.png")));
automatic->set_border_width (0);
automatic->set_tooltip_text (M("GENERAL_AUTO"));
automatic->set_tooltip_markup(tooltip.length() ? Glib::ustring::compose("<b>%1</b>\n\n%2", M("GENERAL_AUTO"), tooltip) : M("GENERAL_AUTO"));
autoChange = automatic->signal_toggled().connect( sigc::mem_fun(*this, &Adjuster::autoToggled) );
hbox->pack_end (*automatic, Gtk::PACK_SHRINK, 0);

View File

@ -80,7 +80,7 @@ class Adjuster : public Gtk::VBox {
virtual ~Adjuster ();
// Add an "Automatic" checkbox next to the reset button.
void addAutoButton();
void addAutoButton(Glib::ustring tooltip="");
// Remove the "Automatic" checkbox next to the reset button.
void delAutoButton();
// Send back the value of og the Auto checkbox

View File

@ -57,7 +57,7 @@ ColorAppearance::ColorAppearance () : Gtk::VBox(), FoldableToolPanel(this) {
degree = Gtk::manage (new Adjuster (M("TP_COLORAPP_CIECAT_DEGREE"), 0., 100., 1., 100.));
if (degree->delay < 1000) degree->delay = 1000;
degree->throwOnButtonRelease();
degree->addAutoButton();
degree->addAutoButton(M("TP_COLORAPP_DEGREE_AUTO_TOOLTIP"));
degree->set_tooltip_markup (M("TP_COLORAPP_DEGREE_TOOLTIP"));
p1VBox->pack_start (*degree);
@ -78,7 +78,7 @@ ColorAppearance::ColorAppearance () : Gtk::VBox(), FoldableToolPanel(this) {
wbmHBox->pack_start (*wbmodel);
p1VBox->pack_start (*wbmHBox);
adapscen = Gtk::manage (new Adjuster (M("TP_COLORAPP_ADAPTSCENE"), 1, 4000., 1., 2000.));
adapscen = Gtk::manage (new Adjuster (M("TP_COLORAPP_ADAPTSCENE"), 0.1, 4000., 0.1, 2000.));
if (adapscen->delay < 1000) adapscen->delay = 1000;
adapscen->throwOnButtonRelease();
adapscen->set_tooltip_markup (M("TP_COLORAPP_ADAPTSCENE_TOOLTIP"));
@ -830,6 +830,27 @@ void ColorAppearance::setDefaults (const ProcParams* defParams, const ParamsEdit
}
}
int autoCamChangedUI (void* data) {
(static_cast<ColorAppearance*>(data))->autoCamComputed_ ();
return 0;
}
void ColorAppearance::autoCamChanged (double ccam)
{
nextCcam = ccam;
g_idle_add (autoCamChangedUI, this);
// Glib::signal_idle().connect (sigc::mem_fun(*this, &ColorAppearance::autoCamComputed_));
}
bool ColorAppearance::autoCamComputed_ () {
disableListener ();
// degree->setEnabled (true);
degree->setValue (nextCcam);
enableListener ();
return false;
}
void ColorAppearance::colorForValue (double valX, double valY, int callerId, ColorCaller *caller) {
@ -891,6 +912,7 @@ void ColorAppearance::adjusterAutoToggled (Adjuster* a, bool newval) {
}
if (listener && (multiImage||enabled->get_active()) ) {
if(a==degree) {
if (degree->getAutoInconsistent())
listener->panelChanged (EvCATAutoDegree, M("GENERAL_UNCHANGED"));
@ -926,7 +948,8 @@ void ColorAppearance::enabledChanged () {
toneCurveMode->set_sensitive (true);
}
else
listener->panelChanged (EvCATEnabled, M("GENERAL_DISABLED"));
{listener->panelChanged (EvCATEnabled, M("GENERAL_DISABLED"));
}
}
}

View File

@ -28,7 +28,7 @@
#include "guiutils.h"
#include "colorprovider.h"
class ColorAppearance : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel, public CurveListener, public ColorProvider {
class ColorAppearance : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoCamListener, public CurveListener, public ColorProvider {
protected:
Glib::RefPtr<Gtk::Tooltip> bgTTips;
@ -76,7 +76,7 @@ class ColorAppearance : public Gtk::VBox, public AdjusterListener, public Foldab
DiagonalCurveEditor* shape;
DiagonalCurveEditor* shape2;
DiagonalCurveEditor* shape3;
double nextCcam;
bool lastEnabled;
bool lastAutoDegree;
sigc::connection enaConn;
@ -109,6 +109,8 @@ class ColorAppearance : public Gtk::VBox, public AdjusterListener, public Foldab
void datacie_toggled ();
void tonecie_toggled ();
// void sharpcie_toggled ();
void autoCamChanged (double ccam);
bool autoCamComputed_ ();
void curveChanged (CurveEditor* ce);
void curveMode1Changed ();

View File

@ -102,6 +102,8 @@ bool MultiLangMgr::isOSLanguageDetectSupported() {
#else
return false;
#endif
#elif __linux__ || __APPLE__
return true;
#else
return false;
#endif
@ -114,7 +116,6 @@ Glib::ustring MultiLangMgr::getOSUserLanguage() {
if (isOSLanguageDetectSupported()) {
// TODO: Add support for other OS here
#ifdef WIN32
// When using old versions of MINGW this is not defined
#ifdef __MINGW64_VERSION_MAJOR
@ -128,8 +129,10 @@ Glib::ustring MultiLangMgr::getOSUserLanguage() {
langName=TranslateRFC2Language(localRFC);
}
#endif
#elif __linux__ || __APPLE__
langName = TranslateRFC2Language(std::setlocale(LC_CTYPE,""));
#endif
} else printf("Automatic language detection not supported on your OS\n");
}
return langName;
}

View File

@ -357,6 +357,8 @@ void ToolPanelCoordinator::initImage (rtengine::StagedImageProcessor* ipc_, bool
if (ipc) {
ipc->setAutoExpListener (toneCurve);
ipc->setAutoCamListener (colorappearance);
ipc->setSizeListener (crop);
ipc->setSizeListener (resize);
}

View File

@ -5,9 +5,10 @@ if [[ ! "$1" ]]; then
exit
fi
hg update "$1"
tools/generateReleaseInfo
hg archive -X ".hg*" -X "rtgui/config.h" -X "rtgui/version.h" -X "rtdata/rawtherapee.desktop" rawtherapee-"$1".tar
mkdir rawtherapee-"$1"
mv ReleaseInfo.cmake rawtherapee-"$1"
hg archive -r "$1" -X ".hg*" -X "rtgui/config.h" -X "rtgui/version.h" -X "rtdata/rawtherapee.desktop" rawtherapee-"$1".tar
tar -rf rawtherapee-"$1".tar rawtherapee-"$1"/ReleaseInfo.cmake
xz -z -9e rawtherapee-"$1".tar
hg update
rm ReleaseInfo.cmake
rm -r rawtherapee-"$1"