Merge with 572a875474cb7c02682801dc30daab16a0d3c20b
This commit is contained in:
parent
f3e0647a32
commit
ee33ca0b7d
50
COMPILE.txt
50
COMPILE.txt
@ -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
|
||||
-----
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
@ -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 );
|
||||
|
||||
|
||||
};
|
||||
|
@ -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, ¶ms,parent->customColCurve1,parent->customColCurve2,parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp);
|
||||
else parent->ipf.ciecam_02 (cieCrop,begh, endh, 1,labnCrop, ¶ms,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, ¶ms,parent->customColCurve1,parent->customColCurve2,parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp, d);
|
||||
}
|
||||
else {parent->ipf.ciecam_02 (cieCrop,begh, endh, 1,labnCrop, ¶ms,parent->customColCurve1,parent->customColCurve2,parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp, dd);}
|
||||
}
|
||||
// switch back to rgb
|
||||
parent->ipf.lab2monitorRgb (labnCrop, cropImg);
|
||||
|
@ -55,6 +55,7 @@ class Crop : public DetailedCrop {
|
||||
|
||||
bool cropAllocated;
|
||||
DetailedCropListener* cropImageListener;
|
||||
|
||||
Glib::Mutex cropMutex;
|
||||
ImProcCoordinator* parent;
|
||||
|
||||
|
@ -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, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, true);
|
||||
else ipf.ciecam_02 (ncie, begh, endh, pW, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, true);
|
||||
|
||||
if(settings->ciecamfloat){ipf.ciecam_02float (ncie, begh, endh, pW, nprevl, ¶ms, 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, ¶ms, 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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 () {}
|
||||
|
||||
|
@ -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, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 6, (float**)buffer, execsharp);
|
||||
float d;
|
||||
ipf.ciecam_02float (cieView, begh, endh, 1, labView, ¶ms,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++)
|
||||
|
@ -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, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true);
|
||||
else ipf.ciecam_02 (cieView, begh, endh,1, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true);
|
||||
if(settings->ciecamfloat) ipf.ciecam_02float (cieView, begh, endh,1, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true, d);
|
||||
else ipf.ciecam_02 (cieView, begh, endh,1, labView, ¶ms,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, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true);
|
||||
else ipf.ciecam_02 (cieView, begh, endh,1, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true);
|
||||
if(settings->ciecamfloat) ipf.ciecam_02float (cieView, begh, endh,1, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true, d);
|
||||
else ipf.ciecam_02 (cieView, begh, endh,1, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true, dd);
|
||||
|
||||
for (int i=0; i<f_h; i++)
|
||||
delete [] buffer[i];
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 ();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user