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: FFTW:
- Instructions: http://www.fftw.org/install/windows.html - 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: IMPORTANT:
@ -356,6 +388,24 @@ WINDOWS
- You'll find the compiled program in the subdirectory named like the - You'll find the compiled program in the subdirectory named like the
value of CMAKE_BUILD_TYPE ("Release" in this example). 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 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_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_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;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;Courbe tonale 2
TP_COLORAPP_CURVEEDITOR2_TOOLTIP;usage similaire aux courbes tonales exposition TP_COLORAPP_CURVEEDITOR2_TOOLTIP;usage similaire aux courbes tonales exposition
TP_COLORAPP_CURVEEDITOR3;Courbes chroma 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_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;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_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\nSi vous sélectionnez " <i>Automatic</i> ", RT essaiera de trouver la meilleure valeur 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_EQUAL;Préservé
TP_COLORAPP_GAMUT;Contrôle du gamut (Lab) TP_COLORAPP_GAMUT;Contrôle du gamut (Lab)
TP_COLORAPP_GAMUT_TOOLTIP;Permet le controle du gamut en mode 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_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;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_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_EQUAL;Equal
TP_COLORAPP_GAMUT;Gamut control (Lab) TP_COLORAPP_GAMUT;Gamut control (Lab)
TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab mode TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in Lab mode

File diff suppressed because it is too large Load Diff

View File

@ -38,20 +38,20 @@ using namespace std;
namespace rtengine { namespace rtengine {
void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radius, int thresh) { void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radius, int thresh) {
int halfwin = ceil(2*radius)+1; int halfwin = ceil(2*radius)+1;
#include "rt_math.h" #include "rt_math.h"
// local variables // local variables
int width=src->W, height=src->H; int width=src->W, height=src->H;
//temporary array to store chromaticity //temporary array to store chromaticity
int (*fringe); int (*fringe);
fringe = (int (*)) calloc ((height)*(width), sizeof *fringe); fringe = (int (*)) calloc ((height)*(width), sizeof *fringe);
LabImage * tmp1; LabImage * tmp1;
tmp1 = new LabImage(width, height); tmp1 = new LabImage(width, height);
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel #pragma omp parallel
#endif #endif
@ -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->a, tmp1->a, buffer, src->W, src->H, radius);
gaussVertical<float> (tmp1->b, tmp1->b, 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); // gaussHorizontal<float> (src->L, tmp1->L, buffer, src->W, src->H, radius);
gaussVertical<float> (tmp1->L, tmp1->L, buffer, src->W, src->H, radius); // gaussVertical<float> (tmp1->L, tmp1->L, buffer, src->W, src->H, radius);
} }
//#ifdef _OPENMP float chromave=0;
//#pragma omp parallel for #ifdef _OPENMP
//#endif #pragma omp parallel for reduction(+:chromave)
float chromave=0; #endif
for(int i = 0; i < height; i++ ) { for(int i = 0; i < height; i++ ) {
for(int j = 0; j < width; j++) { 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]); float chroma = SQR(src->a[i][j]-tmp1->a[i][j])+SQR(src->b[i][j]-tmp1->b[i][j]);
@ -78,12 +78,18 @@ void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radiu
fringe[i*width+j]=chroma; fringe[i*width+j]=chroma;
} }
} }
chromave /= (height*width); chromave /= (height*width);
// printf("Chro %f \n",chromave); float threshfactor = (thresh*chromave)/33.f; // Calculated once to eliminate mult inside the next loop
// printf("Chro %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 #ifdef _OPENMP
#pragma omp parallel for #pragma omp parallel for schedule(dynamic,16)
#endif #endif
for(int i = 0; i < height; i++ ) { for(int i = 0; i < height; i++ ) {
for(int j = 0; j < width; j++) { for(int j = 0; j < width; j++) {
tmp1->a[i][j] = src->a[i][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 //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] && \*/ /*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]) && \*/ /*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 atot=0.f;
float btot=0.f; float btot=0.f;
float norm=0.f; float norm=0.f;
@ -113,7 +119,7 @@ void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radiu
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for #pragma omp parallel for
#endif #endif
for(int i = 0; i < height; i++ ) { for(int i = 0; i < height; i++ ) {
for(int j = 0; j < width; j++) { for(int j = 0; j < width; j++) {
dst->L[i][j] = src->L[i][j]; dst->L[i][j] = src->L[i][j];
@ -121,28 +127,30 @@ void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radiu
dst->b[i][j] = tmp1->b[i][j]; dst->b[i][j] = tmp1->b[i][j];
} }
} }
delete tmp1; delete tmp1;
free(fringe); free(fringe);
} }
void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double radius, int thresh) { void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double radius, int thresh) {
int halfwin = ceil(2*radius)+1; int halfwin = ceil(2*radius)+1;
#include "rt_math.h" #include "rt_math.h"
// local variables // local variables
int width=src->W, height=src->H; int width=src->W, height=src->H;
float piid=3.14159265f/180.f; float piid=3.14159265f/180.f;
//temporary array to store chromaticity //temporary array to store chromaticity
int (*fringe); int (*fringe);
fringe = (int (*)) calloc ((height)*(width), sizeof *fringe); fringe = (int (*)) calloc ((height)*(width), sizeof *fringe);
float** sraa; float** sraa;
sraa = new float*[height]; sraa = new float*[height];
for (int i=0; i<height; i++) for (int i=0; i<height; i++)
sraa[i] = new float[width]; sraa[i] = new float[width];
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int i=0; i<height; i++) for (int i=0; i<height; i++)
for (int j=0; j<width; j++) { for (int j=0; j<width; j++) {
sraa[i][j]=src->C_p[i][j]*cos(piid*src->h_p[i][j]); sraa[i][j]=src->C_p[i][j]*cos(piid*src->h_p[i][j]);
@ -156,8 +164,10 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double ra
srbb = new float*[height]; srbb = new float*[height];
for (int i=0; i<height; i++) for (int i=0; i<height; i++)
srbb[i] = new float[width]; srbb[i] = new float[width];
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int i=0; i<height; i++) for (int i=0; i<height; i++)
for (int j=0; j<width; j++) { for (int j=0; j<width; j++) {
srbb[i][j]=src->C_p[i][j]*sin(piid*src->h_p[i][j]); srbb[i][j]=src->C_p[i][j]*sin(piid*src->h_p[i][j]);
@ -172,7 +182,7 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double ra
for (int i=0; i<height; i++) for (int i=0; i<height; i++)
tmL[i] = new float[width]; tmL[i] = new float[width];
*/ */
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel #pragma omp parallel
#endif #endif
@ -184,13 +194,13 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double ra
gaussVertical<float> (tmbb, tmbb, buffer, src->W, src->H, radius); gaussVertical<float> (tmbb, tmbb, buffer, src->W, src->H, radius);
// gaussHorizontal<float> (src->sh_p, tmL, buffer, src->W, src->H, radius); // gaussHorizontal<float> (src->sh_p, tmL, buffer, src->W, src->H, radius);
// gaussVertical<float> (tmL, tmL, buffer, src->W, src->H, radius); // gaussVertical<float> (tmL, tmL, buffer, src->W, src->H, radius);
} }
//#ifdef _OPENMP float chromave=0;
//#pragma omp parallel for #ifdef _OPENMP
//#endif #pragma omp parallel for reduction(+:chromave)
float chromave=0; #endif
for(int i = 0; i < height; i++ ) { for(int i = 0; i < height; i++ ) {
for(int j = 0; j < width; j++) { for(int j = 0; j < width; j++) {
float chroma =SQR(sraa[i][j]-tmaa[i][j])+SQR(srbb[i][j]-tmbb[i][j]); float chroma =SQR(sraa[i][j]-tmaa[i][j])+SQR(srbb[i][j]-tmbb[i][j]);
@ -198,22 +208,27 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double ra
fringe[i*width+j]=chroma; fringe[i*width+j]=chroma;
} }
} }
chromave /= (height*width); chromave /= (height*width);
float threshfactor = (thresh*chromave)/33.f; // Calculated once to eliminate mult inside the next loop
// printf("Chromave CAM %f \n",chromave); // 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 #ifdef _OPENMP
#pragma omp parallel for #pragma omp parallel for schedule(dynamic,16)
#endif #endif
for(int i = 0; i < height; i++ ) { for(int i = 0; i < height; i++ ) {
for(int j = 0; j < width; j++) { for(int j = 0; j < width; j++) {
tmaa[i][j] = sraa[i][j]; tmaa[i][j] = sraa[i][j];
tmbb[i][j] = srbb[i][j]; tmbb[i][j] = srbb[i][j];
//test for pixel darker than some fraction of neighborhood ave, near an edge, more saturated than average //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] && \*/ /*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]) && \*/ /*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 atot=0.f;
float btot=0.f; float btot=0.f;
float norm=0.f; float norm=0.f;
@ -235,7 +250,7 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double ra
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for #pragma omp parallel for
#endif #endif
for(int i = 0; i < height; i++ ) { for(int i = 0; i < height; i++ ) {
for(int j = 0; j < width; j++) { for(int j = 0; j < width; j++) {
dst->sh_p[i][j] = src->sh_p[i][j]; dst->sh_p[i][j] = src->sh_p[i][j];

View File

@ -30,17 +30,17 @@
using namespace rtengine; using namespace rtengine;
void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) { void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
#define HCLIP(x) x //is this still necessary??? #define HCLIP(x) x //is this still necessary???
//min(clip_pt,x) //min(clip_pt,x)
int width=winw, height=winh; int width=winw, height=winh;
const float clip_pt = 1/initialGain; const float clip_pt = 1/initialGain;
#define TS 512 // Tile size; the image is processed in square tiles to lower memory requirements and facilitate multi-threading #define TS 512 // Tile size; the image is processed in square tiles to lower memory requirements and facilitate multi-threading
// local variables // local variables
@ -69,7 +69,15 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
static const float gquinc[4] = {0.169917f, 0.108947f, 0.069855f, 0.0287182f}; static const float gquinc[4] = {0.169917f, 0.108947f, 0.069855f, 0.0287182f};
volatile double progress = 0.0; 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 #pragma omp parallel
{ {
//position of top/left corner of the tile //position of top/left corner of the tile
@ -159,7 +167,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
delm = (float (*)) (buffer + 18*sizeof(float)*TS*TS); delm = (float (*)) (buffer + 18*sizeof(float)*TS*TS);
rbint = (float (*)) (buffer + 19*sizeof(float)*TS*TS); rbint = (float (*)) (buffer + 19*sizeof(float)*TS*TS);
Dgrbh2 = (float (*)) (buffer + 20*sizeof(float)*TS*TS); Dgrbh2 = (float (*)) (buffer + 20*sizeof(float)*TS*TS);
Dgrbv2 = (float (*)) (buffer + 21*sizeof(float)*TS*TS); Dgrbv2 = (float (*)) (buffer + 21*sizeof(float)*TS*TS);
dgintv = (float (*)) (buffer + 22*sizeof(float)*TS*TS); dgintv = (float (*)) (buffer + 22*sizeof(float)*TS*TS);
dginth = (float (*)) (buffer + 23*sizeof(float)*TS*TS); dginth = (float (*)) (buffer + 23*sizeof(float)*TS*TS);
Dgrbp1 = (float (*)) (buffer + 24*sizeof(float)*TS*TS); Dgrbp1 = (float (*)) (buffer + 24*sizeof(float)*TS*TS);
@ -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);
}
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -211,8 +215,11 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
// Main algorithm: Tile loop // Main algorithm: Tile loop
//#pragma omp parallel for shared(rawData,height,width,red,green,blue) private(top,left) schedule(dynamic) //#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 //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 (top=winy-16; top < winy+height; top += TS-32)
for (left=winx-16; left < winx+width; left += TS-32) { for (left=winx-16; left < winx+width; left += TS-32) {
//location of tile bottom edge //location of tile bottom edge
@ -224,7 +231,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
//tile height (=TS except for bottom edge of image) //tile height (=TS except for bottom edge of image)
int cc1 = right - left; int cc1 = right - left;
//tile vars //tile vars
//counters for pixel location in the image //counters for pixel location in the image
int row, col; int row, col;
//min and max row/column in the tile //min and max row/column in the tile
@ -286,13 +293,13 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
float rbvarp, rbvarm; float rbvarp, rbvarm;
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// rgb from input CFA data // rgb from input CFA data
// rgb values should be floating point number between 0 and 1 // rgb values should be floating point number between 0 and 1
// after white balance multipliers are applied // after white balance multipliers are applied
// a 16 pixel border is added to each side of the image // a 16 pixel border is added to each side of the image
// bookkeeping for borders // bookkeeping for borders
@ -300,7 +307,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
if (left<winx) {ccmin=16;} else {ccmin=0;} if (left<winx) {ccmin=16;} else {ccmin=0;}
if (bottom>(winy+height)) {rrmax=winy+height-top;} else {rrmax=rr1;} if (bottom>(winy+height)) {rrmax=winy+height-top;} else {rrmax=rr1;}
if (right>(winx+width)) {ccmax=winx+width-left;} else {ccmax=cc1;} if (right>(winx+width)) {ccmax=winx+width-left;} else {ccmax=cc1;}
for (rr=rrmin; rr < rrmax; rr++) for (rr=rrmin; rr < rrmax; rr++)
for (row=rr+top, cc=ccmin; cc < ccmax; cc++) { for (row=rr+top, cc=ccmin; cc < ccmax; cc++) {
col = cc+left; col = cc+left;
@ -315,7 +322,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//fill borders //fill borders
if (rrmin>0) { if (rrmin>0) {
for (rr=0; rr<16; rr++) for (rr=0; rr<16; rr++)
for (cc=ccmin; cc<ccmax; cc++) { for (cc=ccmin; cc<ccmax; cc++) {
c = FC(rr,cc); c = FC(rr,cc);
rgb[rr*TS+cc][c] = rgb[(32-rr)*TS+cc][c]; rgb[rr*TS+cc][c] = rgb[(32-rr)*TS+cc][c];
@ -323,7 +330,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
} }
} }
if (rrmax<rr1) { if (rrmax<rr1) {
for (rr=0; rr<16; rr++) for (rr=0; rr<16; rr++)
for (cc=ccmin; cc<ccmax; cc++) { for (cc=ccmin; cc<ccmax; cc++) {
c=FC(rr,cc); c=FC(rr,cc);
rgb[(rrmax+rr)*TS+cc][c] = (rawData[(winy+height-rr-2)][left+cc])/65535.0f; rgb[(rrmax+rr)*TS+cc][c] = (rawData[(winy+height-rr-2)][left+cc])/65535.0f;
@ -332,10 +339,10 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
} }
} }
if (ccmin>0) { if (ccmin>0) {
for (rr=rrmin; rr<rrmax; rr++) for (rr=rrmin; rr<rrmax; rr++)
for (cc=0; cc<16; cc++) { for (cc=0; cc<16; cc++) {
c=FC(rr,cc); c=FC(rr,cc);
rgb[rr*TS+cc][c] = rgb[rr*TS+32-cc][c]; rgb[rr*TS+cc][c] = rgb[rr*TS+32-cc][c];
cfa[rr*TS+cc] = rgb[rr*TS+cc][c]; cfa[rr*TS+cc] = rgb[rr*TS+cc][c];
} }
} }
@ -348,10 +355,10 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
cfa[rr*TS+ccmax+cc] = rgb[rr*TS+ccmax+cc][c]; cfa[rr*TS+ccmax+cc] = rgb[rr*TS+ccmax+cc][c];
} }
} }
//also, fill the image corners //also, fill the image corners
if (rrmin>0 && ccmin>0) { if (rrmin>0 && ccmin>0) {
for (rr=0; rr<16; rr++) for (rr=0; rr<16; rr++)
for (cc=0; cc<16; cc++) { for (cc=0; cc<16; cc++) {
c=FC(rr,cc); c=FC(rr,cc);
rgb[(rr)*TS+cc][c] = (rawData[winy+32-rr][winx+32-cc])/65535.0f; rgb[(rr)*TS+cc][c] = (rawData[winy+32-rr][winx+32-cc])/65535.0f;
@ -360,7 +367,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
} }
} }
if (rrmax<rr1 && ccmax<cc1) { if (rrmax<rr1 && ccmax<cc1) {
for (rr=0; rr<16; rr++) for (rr=0; rr<16; rr++)
for (cc=0; cc<16; cc++) { for (cc=0; cc<16; cc++) {
c=FC(rr,cc); c=FC(rr,cc);
rgb[(rrmax+rr)*TS+ccmax+cc][c] = (rawData[(winy+height-rr-2)][(winx+width-cc-2)])/65535.0f; rgb[(rrmax+rr)*TS+ccmax+cc][c] = (rawData[(winy+height-rr-2)][(winx+width-cc-2)])/65535.0f;
@ -369,7 +376,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
} }
} }
if (rrmin>0 && ccmax<cc1) { if (rrmin>0 && ccmax<cc1) {
for (rr=0; rr<16; rr++) for (rr=0; rr<16; rr++)
for (cc=0; cc<16; cc++) { for (cc=0; cc<16; cc++) {
c=FC(rr,cc); c=FC(rr,cc);
rgb[(rr)*TS+ccmax+cc][c] = (rawData[(winy+32-rr)][(winx+width-cc-2)])/65535.0f; rgb[(rr)*TS+ccmax+cc][c] = (rawData[(winy+32-rr)][(winx+width-cc-2)])/65535.0f;
@ -378,7 +385,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
} }
} }
if (rrmax<rr1 && ccmin>0) { if (rrmax<rr1 && ccmin>0) {
for (rr=0; rr<16; rr++) for (rr=0; rr<16; rr++)
for (cc=0; cc<16; cc++) { for (cc=0; cc<16; cc++) {
c=FC(rr,cc); c=FC(rr,cc);
rgb[(rrmax+rr)*TS+cc][c] = (rawData[(winy+height-rr-2)][(winx+32-cc)])/65535.0f; rgb[(rrmax+rr)*TS+cc][c] = (rawData[(winy+height-rr-2)][(winx+32-cc)])/65535.0f;
@ -392,31 +399,31 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
for (rr=1; rr < rr1-1; rr++) for (rr=1; rr < rr1-1; rr++)
for (cc=1, indx=(rr)*TS+cc; cc < cc1-1; cc++, indx++) { for (cc=1, indx=(rr)*TS+cc; cc < cc1-1; cc++, indx++) {
delh[indx] = fabs(cfa[indx+1]-cfa[indx-1]); delh[indx] = fabs(cfa[indx+1]-cfa[indx-1]);
delv[indx] = fabs(cfa[indx+v1]-cfa[indx-v1]); delv[indx] = fabs(cfa[indx+v1]-cfa[indx-v1]);
delhsq[indx] = SQR(delh[indx]); delhsq[indx] = SQR(delh[indx]);
delvsq[indx] = SQR(delv[indx]); delvsq[indx] = SQR(delv[indx]);
delp[indx] = fabs(cfa[indx+p1]-cfa[indx-p1]); delp[indx] = fabs(cfa[indx+p1]-cfa[indx-p1]);
delm[indx] = fabs(cfa[indx+m1]-cfa[indx-m1]); delm[indx] = fabs(cfa[indx+m1]-cfa[indx-m1]);
} }
for (rr=2; rr < rr1-2; rr++) for (rr=2; rr < rr1-2; rr++)
for (cc=2,indx=(rr)*TS+cc; cc < cc1-2; cc++, indx++) { for (cc=2,indx=(rr)*TS+cc; cc < cc1-2; cc++, indx++) {
dirwts[indx][0] = eps+delv[indx+v1]+delv[indx-v1]+delv[indx];//+fabs(cfa[indx+v2]-cfa[indx-v2]); dirwts[indx][0] = eps+delv[indx+v1]+delv[indx-v1]+delv[indx];//+fabs(cfa[indx+v2]-cfa[indx-v2]);
//vert directional averaging weights //vert directional averaging weights
dirwts[indx][1] = eps+delh[indx+1]+delh[indx-1]+delh[indx];//+fabs(cfa[indx+2]-cfa[indx-2]); dirwts[indx][1] = eps+delh[indx+1]+delh[indx-1]+delh[indx];//+fabs(cfa[indx+2]-cfa[indx-2]);
//horizontal weights //horizontal weights
if (FC(rr,cc)&1) { if (FC(rr,cc)&1) {
//for later use in diagonal interpolation //for later use in diagonal interpolation
//Dgrbp1[indx]=2*cfa[indx]-(cfa[indx-p1]+cfa[indx+p1]); //Dgrbp1[indx]=2*cfa[indx]-(cfa[indx-p1]+cfa[indx+p1]);
//Dgrbm1[indx]=2*cfa[indx]-(cfa[indx-m1]+cfa[indx+m1]); //Dgrbm1[indx]=2*cfa[indx]-(cfa[indx-m1]+cfa[indx+m1]);
Dgrbpsq1[indx]=(SQR(cfa[indx]-cfa[indx-p1])+SQR(cfa[indx]-cfa[indx+p1])); Dgrbpsq1[indx]=(SQR(cfa[indx]-cfa[indx-p1])+SQR(cfa[indx]-cfa[indx+p1]));
Dgrbmsq1[indx]=(SQR(cfa[indx]-cfa[indx-m1])+SQR(cfa[indx]-cfa[indx+m1])); Dgrbmsq1[indx]=(SQR(cfa[indx]-cfa[indx-m1])+SQR(cfa[indx]-cfa[indx+m1]));
} }
} }
//t2_init += clock()-t1_init; //t2_init += clock()-t1_init;
@ -452,7 +459,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
if (fabs(1.0f-crd)<arthresh) {gdar=cfa[indx]*crd;} else {gdar=gdha;} if (fabs(1.0f-crd)<arthresh) {gdar=cfa[indx]*crd;} else {gdar=gdha;}
if (fabs(1.0f-crl)<arthresh) {glar=cfa[indx]*crl;} else {glar=glha;} if (fabs(1.0f-crl)<arthresh) {glar=cfa[indx]*crl;} else {glar=glha;}
if (fabs(1.0f-crr)<arthresh) {grar=cfa[indx]*crr;} else {grar=grha;} if (fabs(1.0f-crr)<arthresh) {grar=cfa[indx]*crr;} else {grar=grha;}
hwt = dirwts[indx-1][1]/(dirwts[indx-1][1]+dirwts[indx+1][1]); hwt = dirwts[indx-1][1]/(dirwts[indx-1][1]+dirwts[indx+1][1]);
vwt = dirwts[indx-v1][0]/(dirwts[indx+v1][0]+dirwts[indx-v1][0]); vwt = dirwts[indx-v1][0]/(dirwts[indx+v1][0]+dirwts[indx-v1][0]);
@ -466,7 +473,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
hcd[indx] = sgn*(Ginthar-cfa[indx]); hcd[indx] = sgn*(Ginthar-cfa[indx]);
vcdalt[indx] = sgn*(Gintvha-cfa[indx]); vcdalt[indx] = sgn*(Gintvha-cfa[indx]);
hcdalt[indx] = sgn*(Ginthha-cfa[indx]); hcdalt[indx] = sgn*(Ginthha-cfa[indx]);
if (cfa[indx] > 0.8*clip_pt || Gintvha > 0.8*clip_pt || Ginthha > 0.8*clip_pt) { if (cfa[indx] > 0.8*clip_pt || Gintvha > 0.8*clip_pt || Ginthha > 0.8*clip_pt) {
//use HA if highlights are (nearly) clipped //use HA if highlights are (nearly) clipped
guar=guha; gdar=gdha; glar=glha; grar=grha; guar=guha; gdar=gdha; glar=glha; grar=grha;
@ -476,7 +483,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
//differences of interpolations in opposite directions //differences of interpolations in opposite directions
dgintv[indx]=min(SQR(guha-gdha),SQR(guar-gdar)); dgintv[indx]=min(SQR(guha-gdha),SQR(guar-gdar));
dginth[indx]=min(SQR(glha-grha),SQR(glar-grar)); dginth[indx]=min(SQR(glha-grha),SQR(glar-grar));
} }
//t2_vcdhcd += clock() - t1_vcdhcd; //t2_vcdhcd += clock() - t1_vcdhcd;
@ -493,7 +500,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
//choose the smallest variance; this yields a smoother interpolation //choose the smallest variance; this yields a smoother interpolation
if (hcdaltvar<hcdvar) hcd[indx]=hcdalt[indx]; if (hcdaltvar<hcdvar) hcd[indx]=hcdalt[indx];
if (vcdaltvar<vcdvar) vcd[indx]=vcdalt[indx]; if (vcdaltvar<vcdvar) vcd[indx]=vcdalt[indx];
//bound the interpolation in regions of high saturation //bound the interpolation in regions of high saturation
if (c&1) {//G site if (c&1) {//G site
Ginth = -hcd[indx]+cfa[indx];//R or B Ginth = -hcd[indx]+cfa[indx];//R or B
@ -515,7 +522,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
vcd[indx]=vwt*vcd[indx] + (1.0f-vwt)*(-ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])+cfa[indx]); vcd[indx]=vwt*vcd[indx] + (1.0f-vwt)*(-ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])+cfa[indx]);
} }
} }
if (Ginth > clip_pt) hcd[indx]=-ULIM(Ginth,cfa[indx-1],cfa[indx+1])+cfa[indx];//for RT implementation if (Ginth > clip_pt) hcd[indx]=-ULIM(Ginth,cfa[indx-1],cfa[indx+1])+cfa[indx];//for RT implementation
if (Gintv > clip_pt) vcd[indx]=-ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])+cfa[indx]; if (Gintv > clip_pt) vcd[indx]=-ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])+cfa[indx];
//if (Ginth > pre_mul[c]) hcd[indx]=-ULIM(Ginth,cfa[indx-1],cfa[indx+1])+cfa[indx];//for dcraw implementation //if (Ginth > pre_mul[c]) hcd[indx]=-ULIM(Ginth,cfa[indx-1],cfa[indx+1])+cfa[indx];//for dcraw implementation
@ -548,7 +555,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
//if (Ginth > pre_mul[c]) hcd[indx]=ULIM(Ginth,cfa[indx-1],cfa[indx+1])-cfa[indx];//for dcraw implementation //if (Ginth > pre_mul[c]) hcd[indx]=ULIM(Ginth,cfa[indx-1],cfa[indx+1])-cfa[indx];//for dcraw implementation
//if (Gintv > pre_mul[c]) vcd[indx]=ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])-cfa[indx]; //if (Gintv > pre_mul[c]) vcd[indx]=ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])-cfa[indx];
} }
cddiffsq[indx] = SQR(vcd[indx]-hcd[indx]); cddiffsq[indx] = SQR(vcd[indx]-hcd[indx]);
} }
@ -556,20 +563,20 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
for (cc=6+(FC(rr,2)&1),indx=rr*TS+cc; cc<cc1-6; cc+=2,indx+=2) { for (cc=6+(FC(rr,2)&1),indx=rr*TS+cc; cc<cc1-6; cc+=2,indx+=2) {
//compute color difference variances in cardinal directions //compute color difference variances in cardinal directions
float uave = vcd[indx]+vcd[indx-v1]+vcd[indx-v2]+vcd[indx-v3]; float uave = vcd[indx]+vcd[indx-v1]+vcd[indx-v2]+vcd[indx-v3];
float dave = vcd[indx]+vcd[indx+v1]+vcd[indx+v2]+vcd[indx+v3]; float dave = vcd[indx]+vcd[indx+v1]+vcd[indx+v2]+vcd[indx+v3];
float lave = (hcd[indx]+hcd[indx-1]+hcd[indx-2]+hcd[indx-3]); float lave = (hcd[indx]+hcd[indx-1]+hcd[indx-2]+hcd[indx-3]);
float rave = (hcd[indx]+hcd[indx+1]+hcd[indx+2]+hcd[indx+3]); float rave = (hcd[indx]+hcd[indx+1]+hcd[indx+2]+hcd[indx+3]);
Dgrbvvaru = SQR(vcd[indx]-uave)+SQR(vcd[indx-v1]-uave)+SQR(vcd[indx-v2]-uave)+SQR(vcd[indx-v3]-uave); Dgrbvvaru = SQR(vcd[indx]-uave)+SQR(vcd[indx-v1]-uave)+SQR(vcd[indx-v2]-uave)+SQR(vcd[indx-v3]-uave);
Dgrbvvard = SQR(vcd[indx]-dave)+SQR(vcd[indx+v1]-dave)+SQR(vcd[indx+v2]-dave)+SQR(vcd[indx+v3]-dave); Dgrbvvard = SQR(vcd[indx]-dave)+SQR(vcd[indx+v1]-dave)+SQR(vcd[indx+v2]-dave)+SQR(vcd[indx+v3]-dave);
Dgrbhvarl = SQR(hcd[indx]-lave)+SQR(hcd[indx-1]-lave)+SQR(hcd[indx-2]-lave)+SQR(hcd[indx-3]-lave); Dgrbhvarl = SQR(hcd[indx]-lave)+SQR(hcd[indx-1]-lave)+SQR(hcd[indx-2]-lave)+SQR(hcd[indx-3]-lave);
Dgrbhvarr = SQR(hcd[indx]-rave)+SQR(hcd[indx+1]-rave)+SQR(hcd[indx+2]-rave)+SQR(hcd[indx+3]-rave); Dgrbhvarr = SQR(hcd[indx]-rave)+SQR(hcd[indx+1]-rave)+SQR(hcd[indx+2]-rave)+SQR(hcd[indx+3]-rave);
hwt = dirwts[indx-1][1]/(dirwts[indx-1][1]+dirwts[indx+1][1]); hwt = dirwts[indx-1][1]/(dirwts[indx-1][1]+dirwts[indx+1][1]);
vwt = dirwts[indx-v1][0]/(dirwts[indx+v1][0]+dirwts[indx-v1][0]); vwt = dirwts[indx-v1][0]/(dirwts[indx+v1][0]+dirwts[indx-v1][0]);
vcdvar = epssq+vwt*Dgrbvvard+(1.0f-vwt)*Dgrbvvaru; vcdvar = epssq+vwt*Dgrbvvard+(1.0f-vwt)*Dgrbvvaru;
hcdvar = epssq+hwt*Dgrbhvarr+(1.0f-hwt)*Dgrbhvarl; hcdvar = epssq+hwt*Dgrbhvarr+(1.0f-hwt)*Dgrbhvarl;
@ -589,13 +596,13 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
//if both agree on interpolation direction, choose the one with strongest directional discrimination; //if both agree on interpolation direction, choose the one with strongest directional discrimination;
//otherwise, choose the u/d and l/r difference fluctuation weights //otherwise, choose the u/d and l/r difference fluctuation weights
if ((0.5-varwt)*(0.5-diffwt)>0 && fabs(0.5-diffwt)<fabs(0.5-varwt)) {hvwt[indx]=varwt;} else {hvwt[indx]=diffwt;} if ((0.5-varwt)*(0.5-diffwt)>0 && fabs(0.5-diffwt)<fabs(0.5-varwt)) {hvwt[indx]=varwt;} else {hvwt[indx]=diffwt;}
//hvwt[indx]=varwt; //hvwt[indx]=varwt;
} }
//t2_cdvar += clock() - t1_cdvar; //t2_cdvar += clock() - t1_cdvar;
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Nyquist test // Nyquist test
//t1_nyqtest = clock(); //t1_nyqtest = clock();
for (rr=6; rr<rr1-6; rr++) for (rr=6; rr<rr1-6; rr++)
@ -630,7 +637,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
for (rr=8; rr<rr1-8; rr++) for (rr=8; rr<rr1-8; rr++)
for (cc=8+(FC(rr,2)&1),indx=rr*TS+cc; cc<cc1-8; cc+=2,indx+=2) { for (cc=8+(FC(rr,2)&1),indx=rr*TS+cc; cc<cc1-8; cc+=2,indx+=2) {
areawt=(nyquist[indx-v2]+nyquist[indx-m1]+nyquist[indx+p1]+ areawt=(nyquist[indx-v2]+nyquist[indx-m1]+nyquist[indx+p1]+
nyquist[indx-2]+nyquist[indx]+nyquist[indx+2]+ nyquist[indx-2]+nyquist[indx]+nyquist[indx+2]+
nyquist[indx-p1]+nyquist[indx+m1]+nyquist[indx+v2]); nyquist[indx-p1]+nyquist[indx+m1]+nyquist[indx+v2]);
@ -693,9 +700,9 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
vo=fabs(0.5-hvwt[indx]); vo=fabs(0.5-hvwt[indx]);
ve=fabs(0.5-hvwtalt); ve=fabs(0.5-hvwtalt);
if (vo<ve) {hvwt[indx]=hvwtalt;}//a better result was obtained from the neighbors if (vo<ve) {hvwt[indx]=hvwtalt;}//a better result was obtained from the neighbors
Dgrb[indx][0] = (hcd[indx]*(1.0f-hvwt[indx]) + vcd[indx]*hvwt[indx]);//evaluate color differences Dgrb[indx][0] = (hcd[indx]*(1.0f-hvwt[indx]) + vcd[indx]*hvwt[indx]);//evaluate color differences
//if (hvwt[indx]<0.5) Dgrb[indx][0]=hcd[indx]; //if (hvwt[indx]<0.5) Dgrb[indx][0]=hcd[indx];
//if (hvwt[indx]>0.5) Dgrb[indx][0]=vcd[indx]; //if (hvwt[indx]>0.5) Dgrb[indx][0]=vcd[indx];
@ -722,7 +729,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
for (cc=8+(FC(rr,2)&1),indx=rr*TS+cc; cc<cc1-8; cc+=2,indx+=2) { for (cc=8+(FC(rr,2)&1),indx=rr*TS+cc; cc<cc1-8; cc+=2,indx+=2) {
if (nyquist[indx]) { if (nyquist[indx]) {
//local averages (over Nyquist pixels only) of G curvature squared //local averages (over Nyquist pixels only) of G curvature squared
gvarh = epssq + (gquinc[0]*Dgrbh2[indx]+ gvarh = epssq + (gquinc[0]*Dgrbh2[indx]+
gquinc[1]*(Dgrbh2[indx-m1]+Dgrbh2[indx+p1]+Dgrbh2[indx-p1]+Dgrbh2[indx+m1])+ gquinc[1]*(Dgrbh2[indx-m1]+Dgrbh2[indx+p1]+Dgrbh2[indx-p1]+Dgrbh2[indx+m1])+
gquinc[2]*(Dgrbh2[indx-v2]+Dgrbh2[indx-2]+Dgrbh2[indx+2]+Dgrbh2[indx+v2])+ gquinc[2]*(Dgrbh2[indx-v2]+Dgrbh2[indx-2]+Dgrbh2[indx+2]+Dgrbh2[indx+v2])+
@ -827,8 +834,8 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
} }
for (rr=12; rr<rr1-12; rr++) for (rr=12; rr<rr1-12; rr++)
for (cc=12+(FC(rr,2)&1),indx=rr*TS+cc; cc<cc1-12; cc+=2,indx+=2) { for (cc=12+(FC(rr,2)&1),indx=rr*TS+cc; cc<cc1-12; cc+=2,indx+=2) {
if (fabs(0.5-pmwt[indx])<fabs(0.5-hvwt[indx]) ) continue; if (fabs(0.5-pmwt[indx])<fabs(0.5-hvwt[indx]) ) continue;
//now interpolate G vertically/horizontally using R+B values //now interpolate G vertically/horizontally using R+B values
@ -888,7 +895,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
rgb[indx][1] = Ginth*(1.0f-hvwt[indx]) + Gintv*hvwt[indx]; rgb[indx][1] = Ginth*(1.0f-hvwt[indx]) + Gintv*hvwt[indx];
//rgb[indx][1] = 0.5*(rgb[indx][1]+0.25*(rgb[indx-v1][1]+rgb[indx+v1][1]+rgb[indx-1][1]+rgb[indx+1][1])); //rgb[indx][1] = 0.5*(rgb[indx][1]+0.25*(rgb[indx-v1][1]+rgb[indx+v1][1]+rgb[indx-1][1]+rgb[indx+1][1]));
Dgrb[indx][0] = rgb[indx][1]-cfa[indx]; Dgrb[indx][0] = rgb[indx][1]-cfa[indx];
//rgb[indx][2-FC(rr,cc)]=2*rbint[indx]-cfa[indx]; //rgb[indx][2-FC(rr,cc)]=2*rbint[indx]-cfa[indx];
} }
//end of diagonal interpolation correction //end of diagonal interpolation correction
@ -949,8 +956,8 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
//for dcraw implementation //for dcraw implementation
//for (c=0; c<3; c++){ //for (c=0; c<3; c++){
// image[indx][c] = CLIP((int)(65535.0f*rgb[rr*TS+cc][c] + 0.5f)); // image[indx][c] = CLIP((int)(65535.0f*rgb[rr*TS+cc][c] + 0.5f));
//} //}
} }
@ -976,5 +983,5 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) {
// done // done
#undef TS #undef TS
} }

View File

@ -1905,28 +1905,9 @@ void ColorTemp::calculate_abfloat( float &aa, float &bb, float h, float e, floa
} }
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,
void ColorTemp::xyz2jchqms_ciecam02( double &J, double &C, double &h, double &Q, double &M, double &s,double &aw, double &fl, double &wh, double &cz, double &aw, double &wh, double &pfl, double &fl, double &c)
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)
{
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; n = yb / yw;
if(pilotd==2.0) d = d_factor( f, la );else d=pilotd; if(pilotd==2.0) d = d_factor( f, la );else d=pilotd;
fl = calculate_fl_from_la_ciecam02( la ); 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 ); aw = achromatic_response_to_white( xw, yw, zw, d, fl, nbb, gamu );
wh =( 4.0 / c ) * ( aw + 4.0 ) * pow( fl, 0.25 ); wh =( 4.0 / c ) * ( aw + 4.0 ) * pow( fl, 0.25 );
pfl = 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)); rc = r * (((yw * d) / rw) + (1.0 - d));
gc = g * (((yw * d) / gw) + (1.0 - d)); gc = g * (((yw * d) / gw) + (1.0 - d));
bc = b * (((yw * d) / bw) + (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, 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 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 r, g, b;
float rw, gw, bw; float rw, gw, bw;
float rc, gc, bc; float rc, gc, bc;
float rp, gp, bp; float rp, gp, bp;
float rpa, gpa, bpa; float rpa, gpa, bpa;
float a, ca, cb; float a, ca, cb;
float d;
float n, nbb, ncb;
float e, t; float e, t;
float cz;
float myh, myj, myc, myq, mym, mys; float myh, myj, myc, myq, mym, mys;
float pfl;
gamu=1; gamu=1;
xyz_to_cat02float( r, g, b, x, y, z, gamu ); xyz_to_cat02float( r, g, b, x, y, z, gamu );
xyz_to_cat02float( rw, gw, bw, xw, yw, zw, 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)); rc = r * (((yw * d) / rw) + (1.0 - d));
gc = g * (((yw * d) / gw) + (1.0 - d)); gc = g * (((yw * d) / gw) + (1.0 - d));
bc = b * (((yw * d) / bw) + (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, 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 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 r, g, b;
double rc, gc, bc; double rc, gc, bc;
double rp, gp, bp; double rp, gp, bp;
double rpa, gpa, bpa; double rpa, gpa, bpa;
double rw, gw, bw; double rw, gw, bw;
double fl, d;
double n, nbb, ncb;
double a, ca, cb; double a, ca, cb;
double aw;
double e, t; double e, t;
double cz;
gamu=1; gamu=1;
ColorTemp::xyz_to_cat02( rw, gw, bw, xw, yw, zw, gamu ); 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); 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; 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 ); 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, 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 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 r, g, b;
float rc, gc, bc; float rc, gc, bc;
float rp, gp, bp; float rp, gp, bp;
float rpa, gpa, bpa; float rpa, gpa, bpa;
float rw, gw, bw; float rw, gw, bw;
float fl, d;
float n, nbb, ncb;
float a, ca, cb; float a, ca, cb;
float aw;
float e, t; float e, t;
float cz;
gamu=1; gamu=1;
ColorTemp::xyz_to_cat02float( rw, gw, bw, xw, yw, zw, gamu ); 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); 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; 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 ); 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 J, double C, double h,
double xw, double yw, double zw, double xw, double yw, double zw,
double yb, double la, 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, static void jch2xyz_ciecam02float( float &x, float &y, float &z,
float J, float C, float h, float J, float C, float h,
float xw, float yw, float zw, float xw, float yw, float zw,
float yb, float la, 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. * 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, static void xyz2jchqms_ciecam02( double &J, double &C, double &h,
double &Q, double &M, double &s,double &aw, double &fl, double &wh, double &Q, double &M, double &s,double &aw, double &fl, double &wh,
double x, double y, double z, double x, double y, double z,
double xw, double yw, double zw, double xw, double yw, double zw,
double yb, double la, 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, static void xyz2jchqms_ciecam02float( float &J, float &C, float &h,
float &Q, float &M, float &s,float &aw, float &fl, float &wh, float &Q, float &M, float &s,float &aw, float &fl, float &wh,
float x, float y, float z, float x, float y, float z,
float xw, float yw, float zw, float xw, float yw, float zw,
float yb, float la, 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; int begh = 0, endh = labnCrop->H;
bool execsharp=false; bool execsharp=false;
float d;
double dd;
if(skip==1) execsharp=true; 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); 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); }
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 // switch back to rgb
parent->ipf.lab2monitorRgb (labnCrop, cropImg); parent->ipf.lab2monitorRgb (labnCrop, cropImg);

View File

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

View File

@ -70,7 +70,7 @@ ImProcCoordinator::ImProcCoordinator ()
bcurvehist(256), bcurvehistCropped(256), bbeforehist(256), bcurvehist(256), bcurvehistCropped(256), bbeforehist(256),
pW(-1), pH(-1), 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) resultValid(false), changeSinceLast(0), updaterRunning(false), destroying(false)
{} {}
@ -423,12 +423,18 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
int Iterates=0; int Iterates=0;
int begh=0; int begh=0;
int endh=pH; int endh=pH;
float d;
double dd;
float **buffer = new float*[pH]; float **buffer = new float*[pH];
for (int i=0; i<pH; i++) for (int i=0; i<pH; i++)
buffer[i] = new float[pW]; 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++) for (int i=0; i<pH; i++)
delete [] buffer[i]; delete [] buffer[i];
delete [] buffer; delete [] buffer;

View File

@ -115,6 +115,7 @@ class ImProcCoordinator : public StagedImageProcessor {
ProgressListener* plistener; ProgressListener* plistener;
PreviewImageListener* imageListener; PreviewImageListener* imageListener;
AutoExpListener* aeListener; AutoExpListener* aeListener;
AutoCamListener* acListener;
HistogramListener* hListener; HistogramListener* hListener;
std::vector<SizeListener*> sizeListeners; 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 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 setAutoExpListener (AutoExpListener* ael) {aeListener = ael; }
void setHistogramListener(HistogramListener *h) {hListener = h; } void setHistogramListener(HistogramListener *h) {hListener = h; }
void setAutoCamListener (AutoCamListener* acl) {acListener = acl; }
void saveInputICCReference (const Glib::ustring& fname); void saveInputICCReference (const Glib::ustring& fname);

View File

@ -40,6 +40,8 @@
#include "boxblur.h" #include "boxblur.h"
#include "rt_math.h" #include "rt_math.h"
#include "EdgePreservingDecomposition.h" #include "EdgePreservingDecomposition.h"
#include "improccoordinator.h"
#ifdef _OPENMP #ifdef _OPENMP
#include <omp.h> #include <omp.h>
#endif #endif
@ -62,10 +64,8 @@ namespace rtengine {
extern const Settings* settings; extern const Settings* settings;
LUTf ImProcFunctions::cachef ; LUTf ImProcFunctions::cachef ;
LUTf ImProcFunctions::gamma2curve = 0; LUTf ImProcFunctions::gamma2curve = 0;
void ImProcFunctions::initCache () { void ImProcFunctions::initCache () {
int maxindex = 65536; int maxindex = 65536;
@ -237,7 +237,7 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par
} }
// Copyright (c) 2012 Jacques Desmis <jdesmis@gmail.com> // 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) { if(params->colorappearance.enabled) {
@ -283,7 +283,7 @@ if(params->colorappearance.enabled) {
Yw=1.0; Yw=1.0;
double Xw, Zw; double Xw, Zw;
double f,c,nc,yb,la,xw,yw,zw,f2,c2,nc2,yb2,la2; 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; double xwd,ywd,zwd;
int alg=0; int alg=0;
float sum=0.f; float sum=0.f;
@ -409,10 +409,16 @@ if(params->colorappearance.enabled) {
// settings of WB: scene and viewing // 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) 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 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; double cz,wh, pfl;
bool doneinit2=true; 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 #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 #endif
{ //matrix for current working space { //matrix for current working space
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working);
@ -437,7 +443,9 @@ if(params->colorappearance.enabled) {
double epsil=0.0001; double epsil=0.0001;
//convert Lab => XYZ //convert Lab => XYZ
Color::Lab2XYZ(L, a, b, x1, y1, z1); 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 Jp,Cpr;
double Jpro,Cpro, hpro, Qpro, Mpro, spro; double Jpro,Cpro, hpro, Qpro, Mpro, spro;
bool t1L=false; bool t1L=false;
@ -447,7 +455,7 @@ if(params->colorappearance.enabled) {
int c1C=0; int c1C=0;
int c1s=0; int c1s=0;
int c1co=0; int c1co=0;
//double n,nbb,ncb,pfl,cz,d;
x=(double)x1/655.35; x=(double)x1/655.35;
y=(double)y1/655.35; y=(double)y1/655.35;
z=(double)z1/655.35; z=(double)z1/655.35;
@ -457,7 +465,7 @@ if(params->colorappearance.enabled) {
x, y, z, x, y, z,
xw1, yw1, zw1, xw1, yw1, zw1,
yb, la, yb, la,
f, c, nc, pilot, doneinit, gamu ); f, c, nc, pilot, gamu , n, nbb, ncb, pfl, cz, d );
Jpro=J; Jpro=J;
Cpro=C; Cpro=C;
hpro=h; hpro=h;
@ -698,12 +706,13 @@ if(params->colorappearance.enabled) {
} }
} }
double xx,yy,zz; double xx,yy,zz;
//double nj, nbbj, ncbj, flj, czj, dj, awj;
//process normal==> viewing //process normal==> viewing
ColorTemp::jch2xyz_ciecam02( xx, yy, zz, ColorTemp::jch2xyz_ciecam02( xx, yy, zz,
J, C, h, J, C, h,
xw2, yw2, zw2, xw2, yw2, zw2,
yb2, la2, yb2, la2,
f2, c2, nc2, doneinit2, gamu); f2, c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj);
x=(float)xx*655.35; x=(float)xx*655.35;
y=(float)yy*655.35; y=(float)yy*655.35;
z=(float)zz*655.35; z=(float)zz*655.35;
@ -814,7 +823,7 @@ if((params->colorappearance.tonecie || (params->colorappearance.tonecie && param
#ifndef _DEBUG #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 #endif
{ {
TMatrix wiprofa = iccStore->workingSpaceInverseMatrix (params->icm.working); TMatrix wiprofa = iccStore->workingSpaceInverseMatrix (params->icm.working);
@ -867,11 +876,12 @@ if((params->colorappearance.tonecie || (params->colorappearance.tonecie && param
} }
} }
//end histograms //end histograms
// double nd, nbbd, ncbd, fld, czd, dd, awd;
ColorTemp::jch2xyz_ciecam02( xx, yy, zz, ColorTemp::jch2xyz_ciecam02( xx, yy, zz,
ncie->J_p[i][j], ncie->C_p[i][j], ncie->h_p[i][j], ncie->J_p[i][j], ncie->C_p[i][j], ncie->h_p[i][j],
xw2, yw2, zw2, xw2, yw2, zw2,
yb2, la2, yb2, la2,
f2, c2, nc2, doneinit2, gamu); f2, c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj);
x=(float)xx*655.35; x=(float)xx*655.35;
y=(float)yy*655.35; y=(float)yy*655.35;
z=(float)zz*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> // 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) { if(params->colorappearance.enabled) {
//printf("ciecam float\n"); //printf("ciecam float\n");
#ifdef _DEBUG #ifdef _DEBUG
MyTime t1e,t2e; MyTime t1e,t2e;
t1e.set(); t1e.set();
@ -987,8 +996,8 @@ if(params->colorappearance.enabled) {
float Yw; float Yw;
Yw=1.0; Yw=1.0;
double Xw, Zw; double Xw, Zw;
float f,c,nc,yb,la,xw,yw,zw,f2,c2,nc2,yb2,la2; float f,nc,yb,la,c,xw,yw,zw,f2,c2,nc2,yb2,la2;
float z,fl,n,nbb,ncb,d,aw; float z,fl,n,nbb,ncb,aw;//d
float xwd,ywd,zwd; float xwd,ywd,zwd;
int alg=0; int alg=0;
float sum=0.f; float sum=0.f;
@ -1114,10 +1123,14 @@ if(params->colorappearance.enabled) {
// settings of WB: scene and viewing // 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) 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 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; float cz,wh, pfl;
bool doneinit2=true; 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 #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 #endif
{ //matrix for current working space { //matrix for current working space
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working);
@ -1142,7 +1155,8 @@ if(params->colorappearance.enabled) {
float epsil=0.0001; float epsil=0.0001;
//convert Lab => XYZ //convert Lab => XYZ
Color::Lab2XYZ(L, a, b, x1, y1, z1); 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 Jp,Cpr;
float Jpro,Cpro, hpro, Qpro, Mpro, spro; float Jpro,Cpro, hpro, Qpro, Mpro, spro;
bool t1L=false; bool t1L=false;
@ -1152,7 +1166,8 @@ if(params->colorappearance.enabled) {
int c1C=0; int c1C=0;
int c1s=0; int c1s=0;
int c1co=0; int c1co=0;
// float n,nbb,ncb,pfl,cz,d;
x=(float)x1/655.35f; x=(float)x1/655.35f;
y=(float)y1/655.35f; y=(float)y1/655.35f;
z=(float)z1/655.35f; z=(float)z1/655.35f;
@ -1162,7 +1177,7 @@ if(params->colorappearance.enabled) {
x, y, z, x, y, z,
xw1, yw1, zw1, xw1, yw1, zw1,
yb, la, yb, la,
f, c, nc, pilot, doneinit, gamu ); f, c, nc, pilot, gamu, n, nbb, ncb, pfl, cz, d);
Jpro=J; Jpro=J;
Cpro=C; Cpro=C;
hpro=h; hpro=h;
@ -1404,11 +1419,13 @@ if(params->colorappearance.enabled) {
} }
float xx,yy,zz; float xx,yy,zz;
//process normal==> viewing //process normal==> viewing
//float nj, nbbj, ncbj, flj, czj, dj, awj;
ColorTemp::jch2xyz_ciecam02float( xx, yy, zz, ColorTemp::jch2xyz_ciecam02float( xx, yy, zz,
J, C, h, J, C, h,
xw2, yw2, zw2, xw2, yw2, zw2,
yb2, la2, yb2, la2,
f2, c2, nc2, doneinit2, gamu); f2, c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj);
x=(float)xx*655.35f; x=(float)xx*655.35f;
y=(float)yy*655.35f; y=(float)yy*655.35f;
z=(float)zz*655.35f; z=(float)zz*655.35f;
@ -1521,7 +1538,7 @@ if((params->colorappearance.tonecie && (params->edgePreservingDecompositionUI.en
#ifndef _DEBUG #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 #endif
{ {
TMatrix wiprofa = iccStore->workingSpaceInverseMatrix (params->icm.working); TMatrix wiprofa = iccStore->workingSpaceInverseMatrix (params->icm.working);
@ -1574,11 +1591,12 @@ if((params->colorappearance.tonecie && (params->edgePreservingDecompositionUI.en
} }
} }
//end histograms //end histograms
ColorTemp::jch2xyz_ciecam02float( xx, yy, zz, ColorTemp::jch2xyz_ciecam02float( xx, yy, zz,
ncie->J_p[i][j], ncie->C_p[i][j], ncie->h_p[i][j], ncie->J_p[i][j], ncie->C_p[i][j], ncie->h_p[i][j],
xw2, yw2, zw2, xw2, yw2, zw2,
yb2, la2, yb2, la2,
f2, c2, nc2, doneinit2, gamu); f2, c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj);
x=(float)xx*655.35f; x=(float)xx*655.35f;
y=(float)yy*655.35f; y=(float)yy*655.35f;
z=(float)zz*655.35f; z=(float)zz*655.35f;

View File

@ -69,6 +69,7 @@ class ImProcFunctions {
public: public:
bool iGamma; // true if inverse gamma has to be applied in rgbProc bool iGamma; // true if inverse gamma has to be applied in rgbProc
double g; double g;
@ -82,7 +83,7 @@ class ImProcFunctions {
ImProcFunctions (const ProcParams* iparams, bool imultiThread=true) ImProcFunctions (const ProcParams* iparams, bool imultiThread=true)
: monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread), iGamma(true), g(0.0) {} : monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread), iGamma(true), g(0.0) {}
~ImProcFunctions (); ~ImProcFunctions ();
void setScale (double iscale); void setScale (double iscale);
bool needsTransform (); bool needsTransform ();
@ -94,8 +95,8 @@ class ImProcFunctions {
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2,
double expcomp, int hlcompr, int hlcomprthresh); double expcomp, int hlcompr, int hlcomprthresh);
void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve); 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_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 ); 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 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 vibrance (LabImage* lab);//Jacques' vibrance
void colorCurve (LabImage* lold, LabImage* lnew); void colorCurve (LabImage* lold, LabImage* lnew);

View File

@ -5,7 +5,7 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* RawTherapee is distributed in the hope that it will be useful, * RawTherapee is distributed in the hope that it will be useful,
* but widthITheightOUT ANY widthARRANTY; without even the implied warranty of * but widthITheightOUT ANY widthARRANTY; without even the implied warranty of
* MERCheightANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCheightANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -15,7 +15,7 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
* *
* 2010 Emil Martinec <ejmartin@uchicago.edu> * 2010 Emil Martinec <ejmartin@uchicago.edu>
* *
*/ */
#include <cstddef> #include <cstddef>
#include "rt_math.h" #include "rt_math.h"
@ -29,17 +29,17 @@ using namespace std;
namespace rtengine { namespace rtengine {
void ImProcFunctions::impulse_nr (LabImage* lab, double thresh) { void ImProcFunctions::impulse_nr (LabImage* lab, double thresh) {
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// impulse noise removal // impulse noise removal
// local variables // local variables
int width = lab->W; int width = lab->W;
int height = lab->H; int height = lab->H;
float hpfabs, hfnbrave; float hpfabs, hfnbrave;
// buffer for the lowpass image // buffer for the lowpass image
float ** lpf = new float *[height]; float ** lpf = new float *[height];
// buffer for the highpass image // buffer for the highpass image
@ -51,45 +51,57 @@ void ImProcFunctions::impulse_nr (LabImage* lab, double thresh) {
//memset (impish[i], 0, width*sizeof(unsigned short)); //memset (impish[i], 0, width*sizeof(unsigned short));
} }
//The cleaning algorithm starts here //The cleaning algorithm starts here
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// modified bilateral filter for lowpass image, omitting input pixel; or Gaussian blur // modified bilateral filter for lowpass image, omitting input pixel; or Gaussian blur
static float eps = 1.0; static float eps = 1.0;
float wtdsum[3], dirwt, norm; float wtdsum[3], dirwt, norm;
int i1, j1; int i1, j1;
//rangeblur<unsigned short, unsigned int> (lab->L, lpf, impish /*used as buffer here*/, width, height, thresh, false); //rangeblur<unsigned short, unsigned int> (lab->L, lpf, impish /*used as buffer here*/, width, height, thresh, false);
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel #pragma omp parallel
#endif #endif
{ {
AlignedBufferMP<double> buffer(max(width,height)); AlignedBufferMP<double> buffer(max(width,height));
gaussHorizontal<float> (lab->L, lpf, buffer, width, height, max(2.0,thresh-1.0)); gaussHorizontal<float> (lab->L, lpf, buffer, width, height, max(2.0,thresh-1.0));
gaussVertical<float> (lpf, lpf, buffer, width, height, max(2.0,thresh-1.0)); gaussVertical<float> (lpf, lpf, buffer, width, height, max(2.0,thresh-1.0));
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
float impthr = max(1.0,5.5-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 i=0; i < height; i++)
for (int j=0; j < width; j++) { for (int j=0; j < width; j++) {
hpfabs = fabs(lab->L[i][j]-lpf[i][j]); hpfabs = fabs(lab->L[i][j]-lpf[i][j]);
//block average of high pass data //block average of high pass data
for (i1=max(0,i-2), hfnbrave=0; i1<=min(i+2,height-1); i1++ ) for (i1=max(0,i-2), hfnbrave=0; i1<=min(i+2,height-1); i1++ )
for (j1=max(0,j-2); j1<=min(j+2,width-1); j1++ ) { for (j1=max(0,j-2); j1<=min(j+2,width-1); j1++ ) {
hfnbrave += fabs(lab->L[i1][j1]-lpf[i1][j1]); hfnbrave += fabs(lab->L[i1][j1]-lpf[i1][j1]);
} }
hfnbrave = (hfnbrave-hpfabs)/24; impish[i][j] = (hpfabs>((hfnbrave-hpfabs)*impthrDiv24));
hpfabs>(hfnbrave*impthr) ? impish[i][j]=1 : impish[i][j]=0;
}//now impulsive values have been identified }//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 i=0; i < height; i++)
for (int j=0; j < width; j++) { for (int j=0; j < width; j++) {
if (!impish[i][j]) continue; if (!impish[i][j]) continue;
@ -110,17 +122,17 @@ void ImProcFunctions::impulse_nr (LabImage* lab, double thresh) {
lab->L[i][j]=wtdsum[0]/norm;//low pass filter lab->L[i][j]=wtdsum[0]/norm;//low pass filter
lab->a[i][j]=wtdsum[1]/norm;//low pass filter lab->a[i][j]=wtdsum[1]/norm;//low pass filter
lab->b[i][j]=wtdsum[2]/norm;//low pass filter lab->b[i][j]=wtdsum[2]/norm;//low pass filter
} }
}//now impulsive values have been corrected }//now impulsive values have been corrected
for (int i=0; i<height; i++) { for (int i=0; i<height; i++) {
delete [] lpf[i]; delete [] lpf[i];
delete [] impish[i]; delete [] impish[i];
} }
delete [] lpf; delete [] lpf;
delete [] impish; delete [] impish;
} }
} }

View File

@ -249,6 +249,10 @@ namespace rtengine {
virtual void autoExpChanged (double brightness, int bright, int contrast, int black, int hlcompr, int hlcomprthresh) {} 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). /** 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. * It can be created and destroyed with the appropriate members of StagedImageProcessor.
* Several crops can be assigned to the same image. */ * Several crops can be assigned to the same image. */
@ -328,6 +332,7 @@ namespace rtengine {
virtual void setAutoExpListener (AutoExpListener* l) =0; virtual void setAutoExpListener (AutoExpListener* l) =0;
virtual void setHistogramListener (HistogramListener *l) =0; virtual void setHistogramListener (HistogramListener *l) =0;
virtual void setPreviewImageListener (PreviewImageListener* l) =0; virtual void setPreviewImageListener (PreviewImageListener* l) =0;
virtual void setAutoCamListener (AutoCamListener* l) =0;
virtual ~StagedImageProcessor () {} virtual ~StagedImageProcessor () {}

View File

@ -797,8 +797,9 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
float** buffer = new float*[fh]; float** buffer = new float*[fh];
for (int i=0; i<fh; i++) for (int i=0; i<fh; i++)
buffer[i] = new float[fw]; buffer[i] = new float[fw];
bool execsharp=false; 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++) for (int i=0; i<fh; i++)
delete [] buffer[i]; delete [] buffer[i];
delete [] buffer; buffer=NULL; delete [] buffer; buffer=NULL;
@ -812,7 +813,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
delete labView; delete labView;
delete baseImg; delete baseImg;
delete cieView; delete cieView;
/* // calculate scale // calculate scale
if (params.coarse.rotate==90 || params.coarse.rotate==270) if (params.coarse.rotate==90 || params.coarse.rotate==270)
myscale = scale * thumbImg->width / fh; myscale = scale * thumbImg->width / fh;
else else
@ -820,7 +821,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
myscale = 1.0 / myscale; myscale = 1.0 / myscale;
// apply crop /* // apply crop
if (params.crop.enabled) { if (params.crop.enabled) {
int ix = 0; int ix = 0;
for (int i=0; i<fh; i++) for (int i=0; i<fh; i++)

View File

@ -290,11 +290,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
customColCurve3, customColCurve3,
1); 1);
if (params.sharpening.enabled) { if (params.sharpening.enabled) {
float d;
double dd;
float** buffer = new float*[fh]; float** buffer = new float*[fh];
for (int i=0; i<fh; i++) for (int i=0; i<fh; i++)
buffer[i] = new float[fw]; 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); 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); 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++) for (int i=0; i<fh; i++)
delete [] buffer[i]; delete [] buffer[i];
@ -302,11 +304,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
} }
else { else {
int f_h=2,f_w=2; int f_h=2,f_w=2;
float d;
double dd;
float** buffer = new float*[f_h]; float** buffer = new float*[f_h];
for (int i=0; i<f_h; i++) for (int i=0; i<f_h; i++)
buffer[i] = new float[f_w]; 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); 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); 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++) for (int i=0; i<f_h; i++)
delete [] buffer[i]; delete [] buffer[i];

View File

@ -185,12 +185,12 @@ Adjuster::~Adjuster () {
if (automatic) delete automatic; if (automatic) delete automatic;
} }
void Adjuster::addAutoButton () { void Adjuster::addAutoButton (Glib::ustring tooltip) {
if (!automatic) { if (!automatic) {
automatic = new Gtk::CheckButton (); automatic = new Gtk::CheckButton ();
//automatic->add (*Gtk::manage (new RTImage ("processing.png"))); //automatic->add (*Gtk::manage (new RTImage ("processing.png")));
automatic->set_border_width (0); 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) ); autoChange = automatic->signal_toggled().connect( sigc::mem_fun(*this, &Adjuster::autoToggled) );
hbox->pack_end (*automatic, Gtk::PACK_SHRINK, 0); hbox->pack_end (*automatic, Gtk::PACK_SHRINK, 0);

View File

@ -80,7 +80,7 @@ class Adjuster : public Gtk::VBox {
virtual ~Adjuster (); virtual ~Adjuster ();
// Add an "Automatic" checkbox next to the reset button. // 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. // Remove the "Automatic" checkbox next to the reset button.
void delAutoButton(); void delAutoButton();
// Send back the value of og the Auto checkbox // 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.)); degree = Gtk::manage (new Adjuster (M("TP_COLORAPP_CIECAT_DEGREE"), 0., 100., 1., 100.));
if (degree->delay < 1000) degree->delay = 1000; if (degree->delay < 1000) degree->delay = 1000;
degree->throwOnButtonRelease(); degree->throwOnButtonRelease();
degree->addAutoButton(); degree->addAutoButton(M("TP_COLORAPP_DEGREE_AUTO_TOOLTIP"));
degree->set_tooltip_markup (M("TP_COLORAPP_DEGREE_TOOLTIP")); degree->set_tooltip_markup (M("TP_COLORAPP_DEGREE_TOOLTIP"));
p1VBox->pack_start (*degree); p1VBox->pack_start (*degree);
@ -78,7 +78,7 @@ ColorAppearance::ColorAppearance () : Gtk::VBox(), FoldableToolPanel(this) {
wbmHBox->pack_start (*wbmodel); wbmHBox->pack_start (*wbmodel);
p1VBox->pack_start (*wbmHBox); 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; if (adapscen->delay < 1000) adapscen->delay = 1000;
adapscen->throwOnButtonRelease(); adapscen->throwOnButtonRelease();
adapscen->set_tooltip_markup (M("TP_COLORAPP_ADAPTSCENE_TOOLTIP")); 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) { 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 (listener && (multiImage||enabled->get_active()) ) {
if(a==degree) { if(a==degree) {
if (degree->getAutoInconsistent()) if (degree->getAutoInconsistent())
listener->panelChanged (EvCATAutoDegree, M("GENERAL_UNCHANGED")); listener->panelChanged (EvCATAutoDegree, M("GENERAL_UNCHANGED"));
@ -926,7 +948,8 @@ void ColorAppearance::enabledChanged () {
toneCurveMode->set_sensitive (true); toneCurveMode->set_sensitive (true);
} }
else else
listener->panelChanged (EvCATEnabled, M("GENERAL_DISABLED")); {listener->panelChanged (EvCATEnabled, M("GENERAL_DISABLED"));
}
} }
} }

View File

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

View File

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

View File

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

View File

@ -5,9 +5,10 @@ if [[ ! "$1" ]]; then
exit exit
fi fi
hg update "$1"
tools/generateReleaseInfo 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 xz -z -9e rawtherapee-"$1".tar
hg update rm -r rawtherapee-"$1"
rm ReleaseInfo.cmake