From 55541cff12a84f7c729ffc736a6a59c3f1f1f30a Mon Sep 17 00:00:00 2001 From: Hombre Date: Thu, 27 Oct 2011 21:23:37 +0200 Subject: [PATCH] New Vibrance tool from Jacques Desmis ; see issue 1065, and it's attached HTML document describing how to use it --- CMakeLists.txt | 9 +- rtdata/languages/Francais | 15 + rtdata/languages/default | 15 + rtengine/CMakeLists.txt | 2 +- rtengine/dcrop.cc | 2 +- rtengine/improccoordinator.cc | 15 +- rtengine/improcfun.cc | 2 +- rtengine/improcfun.h | 65 +- rtengine/init.cc | 1 + rtengine/ipvibrance.cc | 2336 +++++++++++++++++++++++++++++++++ rtengine/procevents.h | 13 +- rtengine/procparams.cc | 39 +- rtengine/procparams.h | 17 + rtengine/rawimagesource.cc | 83 +- rtengine/refreshmap.cc | 7 + rtengine/rtthumbnail.cc | 1 + rtengine/settings.h | 1 + rtengine/simpleprocess.cc | 2 + rtgui/CMakeLists.txt | 2 +- rtgui/addsetids.h | 6 +- rtgui/batchtoolpanelcoord.cc | 5 + rtgui/options.cc | 13 +- rtgui/paramsedited.cc | 121 +- rtgui/paramsedited.h | 13 + rtgui/partialpastedlg.cc | 13 +- rtgui/partialpastedlg.h | 3 +- rtgui/preferences.cc | 6 + rtgui/toolpanelcoord.cc | 2 + rtgui/toolpanelcoord.h | 2 + rtgui/vibrance.cc | 294 +++++ rtgui/vibrance.h | 66 + 31 files changed, 3077 insertions(+), 94 deletions(-) create mode 100644 rtengine/ipvibrance.cc create mode 100644 rtgui/vibrance.cc create mode 100644 rtgui/vibrance.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 485da6528..cbf53dec3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,13 @@ endif (WIN32) if (CMAKE_BUILD_TYPE STREQUAL "") set (CMAKE_BUILD_TYPE Debug CACHE STRING "One of: None Debug Release RelWithDebInfo MinSizeRel." FORCE) endif () + +string (TOUPPER ${CMAKE_BUILD_TYPE} UPPER_CMAKE_BUILD_TYPE) + +if (UPPER_CMAKE_BUILD_TYPE STREQUAL "DEBUG") + add_definitions (-D_DEBUG) +endif () + message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") set (CACHE_NAME_SUFFIX "" CACHE STRING "RawTherapee's cache folder suffix (leave empty to use the default suffix, i.e. latesttag)") @@ -203,8 +210,6 @@ else (AUTOMATED_BUILD_SYSTEM) set(PROC_BIT_DEPTH 64 bits) endif (CMAKE_SIZEOF_VOID_P EQUAL 4) - string (TOUPPER ${CMAKE_BUILD_TYPE} UPPER_CMAKE_BUILD_TYPE) - #generating AboutThisBuild.txt if (WIN32) diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index 8d5b6b572..83180d497 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -247,6 +247,13 @@ HISTORY_MSG_148;Microcontraste HISTORY_MSG_149;Microcontraste - Matrice 3x3 HISTORY_MSG_14;Luminance - Luminosité HISTORY_MSG_150;Réduction du bruit/artefact post-dématriçage +HISTORY_MSG_151;Vibrance +HISTORY_MSG_152;Vibrance - Tons pastels +HISTORY_MSG_153;Vibrance - Tons saturés +HISTORY_MSG_154;Vibrance - Protéger les tons chairs +HISTORY_MSG_155;Vibrance - Éviter les dérives de teinte +HISTORY_MSG_156;Vibrance - Lier Pastels et Saturés +HISTORY_MSG_157;Vibrance - Seuil entre Pastels/Saturés HISTORY_MSG_15;Luminance - Contraste HISTORY_MSG_16;Luminance - Noir HISTORY_MSG_17;Luminance - Compression Hautes lumières @@ -549,6 +556,7 @@ PARTIALPASTE_SHADOWSHIGHLIGHTS;Ombres/Hautes lumières PARTIALPASTE_SHARPENEDGE;Bords PARTIALPASTE_SHARPENING;Netteté PARTIALPASTE_SHARPENMICRO;Microcontraste +PARTIALPASTE_VIBRANCE;Vibrance PARTIALPASTE_VIGNETTING;Correction du vignettage PARTIALPASTE_WAVELETEQUALIZER;Égaliseur d'ondelette PARTIALPASTE_WHITEBALANCE;Balance des blancs @@ -973,6 +981,13 @@ TP_SHARPENMICRO_AMOUNT;Quantité TP_SHARPENMICRO_LABEL;Microcontraste TP_SHARPENMICRO_MATRIX;Matrice 3×3 au lieu de 5×5 TP_SHARPENMICRO_UNIFORMITY;Uniformité +TP_VIBRANCE_AVOIDCOLORSHIFT;Éviter les dérives de teinte +TP_VIBRANCE_LABEL;Vibrance +TP_VIBRANCE_PASTELS;Tons pastels +TP_VIBRANCE_PASTSATTOG;Lier Pastels et Saturés +TP_VIBRANCE_PROTECTSKINS;Protéger les tons chairs +TP_VIBRANCE_SATURATED;Tons saturés +TP_VIBRANCE_PSTHRESHOLD;Seuil entre Pastels/Saturés TP_VIGNETTING_AMOUNT;Quantité TP_VIGNETTING_CENTER;Centre TP_VIGNETTING_CENTER_X;Centre X diff --git a/rtdata/languages/default b/rtdata/languages/default index 48cbefef5..bfded1fee 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -246,6 +246,13 @@ HISTORY_MSG_148;Microcontrast HISTORY_MSG_149;Microcontrast - 3x3 matrix HISTORY_MSG_14;Luminance Brightness HISTORY_MSG_150;Post demosaic artifact/noise reduction +HISTORY_MSG_151;Vibrance +HISTORY_MSG_152;Vibrance - Pastels tones +HISTORY_MSG_153;Vibrance - Saturated tones +HISTORY_MSG_154;Vibrance - Protect skin tones +HISTORY_MSG_155;Vibrance - Avoid color drift +HISTORY_MSG_156;Vibrance - Link Pastels & Saturated +HISTORY_MSG_157;Vibrance - Pastels/Saturated threshold HISTORY_MSG_15;Luminance Contrast HISTORY_MSG_16;Luminance Black HISTORY_MSG_17;Luminance Highlight Compr. @@ -549,6 +556,7 @@ PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights PARTIALPASTE_SHARPENEDGE;Edges PARTIALPASTE_SHARPENING;Sharpening (USM/RL) PARTIALPASTE_SHARPENMICRO;Microcontrast +PARTIALPASTE_VIBRANCE;Vibrance PARTIALPASTE_VIGNETTING;Vignetting correction PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer PARTIALPASTE_WHITEBALANCE;White balance @@ -973,6 +981,13 @@ TP_SHARPENMICRO_AMOUNT;Quantity TP_SHARPENMICRO_LABEL;Microcontrast TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 TP_SHARPENMICRO_UNIFORMITY;Uniformity +TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +TP_VIBRANCE_LABEL;Vibrance +TP_VIBRANCE_PASTELS;Pastels tones +TP_VIBRANCE_PASTSATTOG;Link Pastels & Saturated +TP_VIBRANCE_PROTECTSKINS;Protect skin tones +TP_VIBRANCE_SATURATED;Saturated tones +TP_VIBRANCE_PSTHRESHOLD;Pastels/Saturated threshold TP_VIGNETTING_AMOUNT;Amount TP_VIGNETTING_CENTER;Center TP_VIGNETTING_CENTER_X;Center X diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 4a103ae10..7b4500e0a 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -12,7 +12,7 @@ set (RTENGINESOURCEFILES safegtk.cc colortemp.cc curves.cc flatcurves.cc diagona loadinitial.cc procparams.cc rawimagesource.cc demosaic_algos.cc shmap.cc simpleprocess.cc refreshmap.cc stdimagesource.cc myfile.cc iccjpeg.c hlmultipliers.cc improccoordinator.cc processingjob.cc rtthumbnail.cc utils.cc labimage.cc slicer.cc - iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc + iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc ipvibrance.cc jpeg_memsrc.c jdatasrc.c PF_correct_RT.cc wavelet_dec.cc dirpyrLab_denoise.cc dirpyrLab_equalizer.cc dirpyr_equalizer.cc diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 4e89bbc1d..a99f5bf76 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -163,8 +163,8 @@ void Crop::update (int todo) { if (todo & (M_LUMINANCE+M_COLOR)) { parent->ipf.luminanceCurve (laboCrop, labnCrop, parent->lumacurve); parent->ipf.chrominanceCurve (laboCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve); - //parent->ipf.colorCurve (labnCrop, labnCrop); + parent->ipf.vibrance (labnCrop); if (skip==1) { parent->ipf.impulsedenoise (labnCrop); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 164033c17..b3247a811 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -90,7 +90,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { mProcessing.lock (); - int numofphases = 10; + int numofphases = 14; int readyphase = 0; ipf.setScale (scale); @@ -115,7 +115,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { rp.all_enhance = false; } - progress ("Applying white balance, color correction & sRBG conversion...",100*readyphase/numofphases); + progress ("Applying white balance, color correction & sRGB conversion...",100*readyphase/numofphases); if ( todo & M_PREPROC) { imgsrc->preprocess( rp ); imgsrc->getRAWHistogram( histRedRaw, histGreenRaw, histBlueRaw ); @@ -245,6 +245,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { readyphase++; if ((todo & M_LUMACURVE) || todo==CROP) { + CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lhist16Cropped, lumacurve, histLCurve, scale==1 ? 1 : 16); } @@ -256,28 +257,34 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { if (todo & (M_LUMINANCE+M_COLOR) ) { progress ("Applying Luminance Curve...",100*readyphase/numofphases); + ipf.luminanceCurve (oprevl, nprevl, lumacurve); readyphase++; progress ("Applying Color Boost...",100*readyphase/numofphases); ipf.chrominanceCurve (oprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve/*, params.labCurve.saturation*/); //ipf.colorCurve (nprevl, nprevl); - + ipf.vibrance(nprevl); readyphase++; if (scale==1) { progress ("Denoising luminance impulse...",100*readyphase/numofphases); ipf.impulsedenoise (nprevl); + readyphase++; progress ("Defringing...",100*readyphase/numofphases); ipf.defringe (nprevl); + readyphase++; progress ("Denoising luma/chroma...",100*readyphase/numofphases); ipf.dirpyrdenoise (nprevl); + readyphase++; if (params.sharpenEdge.enabled) { progress ("Edge sharpening...",100*readyphase/numofphases); ipf.MLsharpen (nprevl); + readyphase++; } if (params.sharpenMicro.enabled) { progress ("Microcontrast...",100*readyphase/numofphases); ipf.MLmicrocontrast (nprevl); + readyphase++; } if (params.sharpening.enabled) { progress ("Sharpening...",100*readyphase/numofphases); @@ -291,10 +298,12 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { for (int i=0; ia[i][j]+32768.0f]-32768.0f; float btmp = bcurve[lold->b[i][j]+32768.0f]-32768.0f; - if (params->labCurve.saturation && fabs(atmp)<32768.0f && fabs(btmp)<32768.0f) { + if (params->labCurve.saturation) { float chroma = sqrt(SQR(atmp)+SQR(btmp)+0.001); float satfactor = (satcurve[chroma+32768.0f]-32768.0f)/chroma; atmp *= satfactor; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index db1b542db..0fabde5df 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -61,11 +61,47 @@ class ImProcFunctions { public: static LUTf cachef; + // 195 LUTf for Munsell Lch correction + static LUTf _4P10,_4P20,_4P30,_4P40,_4P50,_4P60; + static LUTf _1P10,_1P20,_1P30,_1P40,_1P50,_1P60; + static LUTf _5B40,_5B50,_5B60, _5B70,_5B80; + static LUTf _7B40,_7B50,_7B60, _7B70,_7B80; + static LUTf _9B40,_9B50,_9B60, _9B70,_9B80; + static LUTf _10B40,_10B50,_10B60, _10B70,_10B80; + static LUTf _05PB40,_05PB50,_05PB60, _05PB70,_05PB80; + static LUTf _10PB10,_10PB20,_10PB30,_10PB40,_10PB50,_10PB60; + static LUTf _9PB10,_9PB20,_9PB30,_9PB40,_9PB50,_9PB60,_9PB70,_9PB80; + static LUTf _75PB10,_75PB20,_75PB30,_75PB40,_75PB50,_75PB60,_75PB70,_75PB80; + static LUTf _6PB10,_6PB20,_6PB30,_6PB40,_6PB50,_6PB60,_6PB70,_6PB80; + static LUTf _45PB10,_45PB20,_45PB30,_45PB40,_45PB50,_45PB60,_45PB70,_45PB80; + static LUTf _3PB10,_3PB20,_3PB30,_3PB40,_3PB50,_3PB60,_3PB70,_3PB80; + static LUTf _15PB10,_15PB20,_15PB30,_15PB40,_15PB50,_15PB60, _15PB70,_15PB80; + static LUTf _10YR20, _10YR30, _10YR40,_10YR50,_10YR60,_10YR70,_10YR80,_10YR90; + static LUTf _85YR20, _85YR30, _85YR40,_85YR50,_85YR60,_85YR70,_85YR80,_85YR90; + static LUTf _7YR30, _7YR40,_7YR50,_7YR60,_7YR70,_7YR80; + static LUTf _55YR30, _55YR40,_55YR50,_55YR60,_55YR70,_55YR80,_55YR90; + static LUTf _4YR30, _4YR40,_4YR50,_4YR60,_4YR70,_4YR80; + static LUTf _25YR30, _25YR40,_25YR50,_25YR60,_25YR70; + static LUTf _10R30, _10R40,_10R50,_10R60,_10R70; + static LUTf _9R30, _9R40,_9R50,_9R60,_9R70; + static LUTf _7R30, _7R40,_7R50,_7R60,_7R70; + static LUTf _5R10, _5R20,_5R30; + static LUTf _25R10, _25R20,_25R30; + static LUTf _10RP10, _10RP20,_10RP30; + static LUTf _7G30, _7G40,_7G50,_7G60,_7G70,_7G80; + static LUTf _5G30, _5G40,_5G50,_5G60,_5G70,_5G80; + static LUTf _25G30, _25G40,_25G50,_25G60,_25G70,_25G80; + static LUTf _1G30, _1G40,_1G50,_1G60,_1G70,_1G80; + static LUTf _10GY30, _10GY40,_10GY50,_10GY60,_10GY70,_10GY80; + static LUTf _75GY30, _75GY40,_75GY50,_75GY60,_75GY70,_75GY80; + static LUTf _5GY30, _5GY40,_5GY50,_5GY60,_5GY70,_5GY80; + double lumimul[3]; static void initCache (); static void cleanupCache (); - + static void initMunsell (); + ImProcFunctions (const ProcParams* iparams, bool imultiThread=true) : monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread) {} ~ImProcFunctions (); @@ -78,6 +114,9 @@ class ImProcFunctions { void rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat); void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve); void chrominanceCurve (LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve); + void vibrance (LabImage* lab);//Jacques' vibrance + void skinsat (float lum, float hue, float chrom, float &satreduc);//jacques Skin color + void MunsellLch (float lum, float hue, float chrom, float memChprov, float &correction, int zone);//jacques: Munsell correction void colorCurve (LabImage* lold, LabImage* lnew); void sharpening (LabImage* lab, float** buffer); void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH); @@ -124,21 +163,21 @@ class ImProcFunctions { void hsv2rgb (float h, float s, float v, float &r, float &g, float &b); void xyz2srgb (float x, float y, float z, float &r, float &g, float &b); void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, float rgb_xyz[3][3]); - void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z); - void XYZ2Lab(float X, float Y, float Z, float &L, float &a, float &b); - void Lab2Yuv(float L, float a, float b, float &Y, float &u, float &v); - void Yuv2Lab(float Y, float u, float v, float &L, float &a, float &b, double wp[3][3]); - void calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4,double &gamma5); + void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z); + void XYZ2Lab(float X, float Y, float Z, float &L, float &a, float &b); + void Lab2Yuv(float L, float a, float b, float &Y, float &u, float &v); + void Yuv2Lab(float Y, float u, float v, float &L, float &a, float &b, double wp[3][3]); + void calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4,double &gamma5); - //void gamutmap(LabImage* ); - void gamutmap(float &X, float &Y, float &Z, const double p[3][3]); + //void gamutmap(LabImage* ); + void gamutmap(float &X, float &Y, float &Z, const double p[3][3]); - static inline float f2xyz(float f) { - const float epsilonExpInv3 = 6.0/29.0; - const float kappaInv = 27.0/24389.0; // inverse of kappa + static inline float f2xyz(float f) { + const float epsilonExpInv3 = 6.0/29.0; + const float kappaInv = 27.0/24389.0; // inverse of kappa - return (f > epsilonExpInv3) ? f*f*f : (116 * f - 16) * kappaInv; - } + return (f > epsilonExpInv3) ? f*f*f : (116 * f - 16) * kappaInv; + } }; } #endif diff --git a/rtengine/init.cc b/rtengine/init.cc index f8ac24b11..b39756a13 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -38,6 +38,7 @@ int init (const Settings* s, Glib::ustring baseDir) { iccStore->findDefaultMonitorProfile(); CurveFactory::init (); + ImProcFunctions::initMunsell(); ImProcFunctions::initCache (); Thumbnail::initGamma (); delete lcmsMutex; diff --git a/rtengine/ipvibrance.cc b/rtengine/ipvibrance.cc new file mode 100644 index 000000000..04441dd50 --- /dev/null +++ b/rtengine/ipvibrance.cc @@ -0,0 +1,2336 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2011 Jacques Desmis + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include +#include +#include +#include + +#ifdef _OPENMP +#include +#endif + +namespace rtengine { + +using namespace procparams; + +#define MAXX3(a,b,c) MAX(a,MAX(b,c)) +#define MINN3(a,b,c) MIN(a,MIN(b,c)) + +#define SAT(a,b,c) ((float)MAXX3(a,b,c)-(float)MINN3(a,b,c))/(float)MAXX3(a,b,c) + +#define D50x 0.96422 +#define D50z 0.82521 + +extern const Settings* settings; + +//Munsell Lch LUTf : 195 LUT +LUTf ImProcFunctions::_4P10 ;//give hue in function of L and C : Munsell correction +LUTf ImProcFunctions::_4P20 ; +LUTf ImProcFunctions::_4P30 ; +LUTf ImProcFunctions::_4P40 ; +LUTf ImProcFunctions::_4P50 ; +LUTf ImProcFunctions::_4P60 ; + + +LUTf ImProcFunctions::_1P10 ; +LUTf ImProcFunctions::_1P20 ; +LUTf ImProcFunctions::_1P30 ; +LUTf ImProcFunctions::_1P40 ; +LUTf ImProcFunctions::_1P50 ; +LUTf ImProcFunctions::_1P60 ; + + +LUTf ImProcFunctions::_10PB10 ; +LUTf ImProcFunctions::_10PB20 ; +LUTf ImProcFunctions::_10PB30 ; +LUTf ImProcFunctions::_10PB40 ; +LUTf ImProcFunctions::_10PB50 ; +LUTf ImProcFunctions::_10PB60 ; + + +LUTf ImProcFunctions::_9PB10 ; +LUTf ImProcFunctions::_9PB20 ; +LUTf ImProcFunctions::_9PB30 ; +LUTf ImProcFunctions::_9PB40 ; +LUTf ImProcFunctions::_9PB50 ; +LUTf ImProcFunctions::_9PB60 ; +LUTf ImProcFunctions::_9PB70 ; +LUTf ImProcFunctions::_9PB80 ; + +LUTf ImProcFunctions::_75PB10 ; +LUTf ImProcFunctions::_75PB20 ; +LUTf ImProcFunctions::_75PB30 ; +LUTf ImProcFunctions::_75PB40 ; +LUTf ImProcFunctions::_75PB50 ; +LUTf ImProcFunctions::_75PB60 ; +LUTf ImProcFunctions::_75PB70 ; +LUTf ImProcFunctions::_75PB80 ; + +LUTf ImProcFunctions::_6PB10 ; +LUTf ImProcFunctions::_6PB20 ; +LUTf ImProcFunctions::_6PB30 ; +LUTf ImProcFunctions::_6PB40 ; +LUTf ImProcFunctions::_6PB50 ; +LUTf ImProcFunctions::_6PB60 ; +LUTf ImProcFunctions::_6PB70 ; +LUTf ImProcFunctions::_6PB80 ; + +LUTf ImProcFunctions::_45PB10 ; +LUTf ImProcFunctions::_45PB20 ; +LUTf ImProcFunctions::_45PB30 ; +LUTf ImProcFunctions::_45PB40 ; +LUTf ImProcFunctions::_45PB50 ; +LUTf ImProcFunctions::_45PB60 ; +LUTf ImProcFunctions::_45PB70 ; +LUTf ImProcFunctions::_45PB80 ; + +LUTf ImProcFunctions::_3PB10 ; +LUTf ImProcFunctions::_3PB20 ; +LUTf ImProcFunctions::_3PB30 ; +LUTf ImProcFunctions::_3PB40 ; +LUTf ImProcFunctions::_3PB50 ; +LUTf ImProcFunctions::_3PB60 ; +LUTf ImProcFunctions::_3PB70 ; +LUTf ImProcFunctions::_3PB80 ; + +LUTf ImProcFunctions::_15PB10 ; +LUTf ImProcFunctions::_15PB20 ; +LUTf ImProcFunctions::_15PB30 ; +LUTf ImProcFunctions::_15PB40 ; +LUTf ImProcFunctions::_15PB50 ; +LUTf ImProcFunctions::_15PB60 ; +LUTf ImProcFunctions::_15PB70 ; +LUTf ImProcFunctions::_15PB80 ; + +LUTf ImProcFunctions::_05PB40 ; +LUTf ImProcFunctions::_05PB50 ; +LUTf ImProcFunctions::_05PB60 ; +LUTf ImProcFunctions::_05PB70 ; +LUTf ImProcFunctions::_05PB80 ; + +LUTf ImProcFunctions::_10B40 ; +LUTf ImProcFunctions::_10B50 ; +LUTf ImProcFunctions::_10B60 ; +LUTf ImProcFunctions::_10B70 ; +LUTf ImProcFunctions::_10B80 ; + +LUTf ImProcFunctions::_9B40 ; +LUTf ImProcFunctions::_9B50 ; +LUTf ImProcFunctions::_9B60 ; +LUTf ImProcFunctions::_9B70 ; +LUTf ImProcFunctions::_9B80 ; + +LUTf ImProcFunctions::_7B40 ; +LUTf ImProcFunctions::_7B50 ; +LUTf ImProcFunctions::_7B60 ; +LUTf ImProcFunctions::_7B70 ; +LUTf ImProcFunctions::_7B80 ; + +LUTf ImProcFunctions::_5B40 ; +LUTf ImProcFunctions::_5B50 ; +LUTf ImProcFunctions::_5B60 ; +LUTf ImProcFunctions::_5B70 ; +LUTf ImProcFunctions::_5B80 ; + +LUTf ImProcFunctions::_10YR20; +LUTf ImProcFunctions::_10YR30; +LUTf ImProcFunctions::_10YR40; +LUTf ImProcFunctions::_10YR50; +LUTf ImProcFunctions::_10YR60; +LUTf ImProcFunctions::_10YR70; +LUTf ImProcFunctions::_10YR80; +LUTf ImProcFunctions::_10YR90; + +LUTf ImProcFunctions::_85YR20; +LUTf ImProcFunctions::_85YR30; +LUTf ImProcFunctions::_85YR40; +LUTf ImProcFunctions::_85YR50; +LUTf ImProcFunctions::_85YR60; +LUTf ImProcFunctions::_85YR70; +LUTf ImProcFunctions::_85YR80; +LUTf ImProcFunctions::_85YR90; + +LUTf ImProcFunctions::_7YR30; +LUTf ImProcFunctions::_7YR40; +LUTf ImProcFunctions::_7YR50; +LUTf ImProcFunctions::_7YR60; +LUTf ImProcFunctions::_7YR70; +LUTf ImProcFunctions::_7YR80; + +LUTf ImProcFunctions::_55YR30; +LUTf ImProcFunctions::_55YR40; +LUTf ImProcFunctions::_55YR50; +LUTf ImProcFunctions::_55YR60; +LUTf ImProcFunctions::_55YR70; +LUTf ImProcFunctions::_55YR80; +LUTf ImProcFunctions::_55YR90; + +LUTf ImProcFunctions::_4YR30; +LUTf ImProcFunctions::_4YR40; +LUTf ImProcFunctions::_4YR50; +LUTf ImProcFunctions::_4YR60; +LUTf ImProcFunctions::_4YR70; +LUTf ImProcFunctions::_4YR80; + +LUTf ImProcFunctions::_25YR30; +LUTf ImProcFunctions::_25YR40; +LUTf ImProcFunctions::_25YR50; +LUTf ImProcFunctions::_25YR60; +LUTf ImProcFunctions::_25YR70; + +LUTf ImProcFunctions::_10R30; +LUTf ImProcFunctions::_10R40; +LUTf ImProcFunctions::_10R50; +LUTf ImProcFunctions::_10R60; +LUTf ImProcFunctions::_10R70; + +LUTf ImProcFunctions::_9R30; +LUTf ImProcFunctions::_9R40; +LUTf ImProcFunctions::_9R50; +LUTf ImProcFunctions::_9R60; +LUTf ImProcFunctions::_9R70; + +LUTf ImProcFunctions::_7R30; +LUTf ImProcFunctions::_7R40; +LUTf ImProcFunctions::_7R50; +LUTf ImProcFunctions::_7R60; +LUTf ImProcFunctions::_7R70; + +LUTf ImProcFunctions::_5R10; +LUTf ImProcFunctions::_5R20; +LUTf ImProcFunctions::_5R30; + +LUTf ImProcFunctions::_25R10; +LUTf ImProcFunctions::_25R20; +LUTf ImProcFunctions::_25R30; + +LUTf ImProcFunctions::_10RP10; +LUTf ImProcFunctions::_10RP20; +LUTf ImProcFunctions::_10RP30; + +LUTf ImProcFunctions::_7G30; +LUTf ImProcFunctions::_7G40; +LUTf ImProcFunctions::_7G50; +LUTf ImProcFunctions::_7G60; +LUTf ImProcFunctions::_7G70; +LUTf ImProcFunctions::_7G80; + +LUTf ImProcFunctions::_5G30; +LUTf ImProcFunctions::_5G40; +LUTf ImProcFunctions::_5G50; +LUTf ImProcFunctions::_5G60; +LUTf ImProcFunctions::_5G70; +LUTf ImProcFunctions::_5G80; + +LUTf ImProcFunctions::_25G30; +LUTf ImProcFunctions::_25G40; +LUTf ImProcFunctions::_25G50; +LUTf ImProcFunctions::_25G60; +LUTf ImProcFunctions::_25G70; +LUTf ImProcFunctions::_25G80; + +LUTf ImProcFunctions::_1G30; +LUTf ImProcFunctions::_1G40; +LUTf ImProcFunctions::_1G50; +LUTf ImProcFunctions::_1G60; +LUTf ImProcFunctions::_1G70; +LUTf ImProcFunctions::_1G80; + +LUTf ImProcFunctions::_10GY30; +LUTf ImProcFunctions::_10GY40; +LUTf ImProcFunctions::_10GY50; +LUTf ImProcFunctions::_10GY60; +LUTf ImProcFunctions::_10GY70; +LUTf ImProcFunctions::_10GY80; + +LUTf ImProcFunctions::_75GY30; +LUTf ImProcFunctions::_75GY40; +LUTf ImProcFunctions::_75GY50; +LUTf ImProcFunctions::_75GY60; +LUTf ImProcFunctions::_75GY70; +LUTf ImProcFunctions::_75GY80; + +LUTf ImProcFunctions::_5GY30; +LUTf ImProcFunctions::_5GY40; +LUTf ImProcFunctions::_5GY50; +LUTf ImProcFunctions::_5GY60; +LUTf ImProcFunctions::_5GY70; +LUTf ImProcFunctions::_5GY80; + +/* + * Munsell Lch correction + * copyright (c) 2011 Jacques Desmis + * + * data (Munsell ==> Lab) obtained with WallKillcolor and http://www.cis.rit.edu/research/mcsl2/online/munsell.php + * each LUT give Hue in function of C, for each color Munsell and Luminance + * eg: _6PB20 : color Munsell 6PB for L=20 c=5 c=45 c=85 c=125..139 when possible: interpolation betwwen values + * no value for C<5 (gray) + * low memory usage -- maximum: 195 LUT * 140 values + * errors due to small number of point of LUT and linearization are very low (1 to 2%) + * errors due to a different illuminant "Daylight" than "C" are low in the order of 10%. For example, a theoretical correction of 0.1 radian will be made with a real correction of 0.09 or 0.11 depending on the color illuminant D50 + * errors due to the use of a very different illuminant "C", for example illuminant "A" (tungsten) are higher in the order of 20%. Theoretical correction of 0.52 radians will be made with a real correction of 0.42 + */ +void ImProcFunctions::initMunsell () { +#ifdef _DEBUG + MyTime t1e,t2e; + t1e.set(); +#endif + +int maxInd = 140; +int maxInd2 = 90; +int maxInd3 = 50; + +//blue for sky +_5B40(maxInd2); + for (int i=0; i5) _5B40[i] = -2.3 + 0.0025*(i-5); + else if (i<90 && i>=45) _5B40[i] = -2.2 + 0.00*(i-45); + } + //printf("5B %1.2f %1.2f\n",_5B40[44],_5B40[89]); +_5B50(maxInd2); + for (int i=0; i5) _5B50[i] = -2.34 + 0.0025*(i-5); + else if (i<90 && i>=45) _5B50[i] = -2.24+0.0003*(i-45); + } + //printf("5B %1.2f %1.2f\n",_5B50[44],_5B50[89]); +_5B60(maxInd2); + for (int i=0; i5) _5B60[i] = -2.4 + 0.003*(i-5); + else if (i<90 && i>=45) _5B60[i] = -2.28+0.0005*(i-45); + } + //printf("5B %1.2f %1.2f\n",_5B60[44],_5B60[89]); +_5B70(maxInd2); + for (int i=0; i5) _5B70[i] = -2.41 + 0.00275*(i-5); + else if (i<90 && i>=45) _5B70[i] = -2.30+0.00025*(i-45); + } + //printf("5B %1.2f %1.2f\n",_5B70[44],_5B70[89]); +_5B80(maxInd3); + for (int i=0; i5) _5B80[i] = -2.45 +0.003*(i-5); + } + //printf("5B %1.2f\n",_5B80[49]); + +_7B40(maxInd2); + for (int i=0; i5) _7B40[i] = -2.15 + 0.0027*(i-5); + else if (i<90 && i>=45) _7B40[i] = -2.04 + 0.00*(i-45); + } + //printf("7B %1.2f %1.2f\n",_7B40[44],_7B40[89]); +_7B50(maxInd2); + for (int i=0; i5) _7B50[i] = -2.20 + 0.003*(i-5); + else if (i<90 && i>=45) _7B50[i] = -2.08 + 0.001*(i-45); + } + //printf("7B %1.2f %1.2f\n",_7B50[44],_7B50[79]); +_7B60(maxInd2); + for (int i=0; i5) _7B60[i] = -2.26 + 0.0035*(i-5); + else if (i<90 && i>=45) _7B60[i] = -2.12 + 0.001*(i-45); + } + //printf("7B %1.2f %1.2f\n",_7B60[44],_7B60[79]); +_7B70(maxInd2); + for (int i=0; i5) _7B70[i] = -2.28 + 0.003*(i-5); + else if (i<90 && i>=45) _7B70[i] = -2.16 + 0.0015*(i-45); + } + //printf("7B %1.2f %1.2f\n",_7B70[44],_7B70[64]); +_7B80(maxInd3); + for (int i=0; i5) _7B80[i] = -2.30 +0.0028*(i-5); + } + //printf("5B %1.2f\n",_7B80[49]); + +_9B40(maxInd2); + for (int i=0; i5) _9B40[i] = -1.99 + 0.0022*(i-5); + else if (i<90 && i>=45) _9B40[i] = -1.90 + 0.0008*(i-45); + } + //printf("9B %1.2f %1.2f\n",_9B40[44],_9B40[69]); +_9B50(maxInd2); + for (int i=0; i5) _9B50[i] = -2.04 + 0.0025*(i-5); + else if (i<90 && i>=45) _9B50[i] = -1.94 + 0.0013*(i-45); + } + //printf("9B %1.2f %1.2f\n",_9B50[44],_9B50[77]); +_9B60(maxInd2); + for (int i=0; i5) _9B60[i] = -2.10 + 0.0033*(i-5); + else if (i<90 && i>=45) _9B60[i] = -1.97 + 0.001*(i-45); + } + //printf("9B %1.2f %1.2f\n",_9B60[44],_9B60[79]); +_9B70(maxInd2); + for (int i=0; i5) _9B70[i] = -2.12 + 0.003*(i-5); + else if (i<90 && i>=45) _9B70[i] = -2.00 + 0.001*(i-45); + } + //printf("9B %1.2f %1.2f\n",_9B70[44],_9B70[54]); +_9B80(maxInd3); + for (int i=0; i5) _9B80[i] = -2.16 +0.0025*(i-5); + } + //printf("9B %1.2f\n",_9B80[49]); + +_10B40(maxInd2); + for (int i=0; i5) _10B40[i] = -1.92 + 0.0022*(i-5); + else if (i<90 && i>=45) _10B40[i] = -1.83 + 0.0012*(i-45); + } + //printf("10B %1.2f %1.2f\n",_10B40[44],_10B40[76]); +_10B50(maxInd2); + for (int i=0; i5) _10B50[i] = -1.95 + 0.0022*(i-5); + else if (i<90 && i>=45) _10B50[i] = -1.86 + 0.0008*(i-45); + } + //printf("10B %1.2f %1.2f\n",_10B50[44],_10B50[85]); +_10B60(maxInd2); + for (int i=0; i5) _10B60[i] = -2.01 + 0.0027*(i-5); + else if (i<90 && i>=45) _10B60[i] = -1.90 + 0.0012*(i-45); + } + //printf("10B %1.2f %1.2f\n",_10B60[44],_10B60[70]); +_10B70(maxInd3); + for (int i=0; i5) _10B70[i] = -2.03 +0.0025*(i-5); + } + //printf("10B %1.2f\n",_10B70[49]); +_10B80(maxInd3); + for (int i=0; i5) _10B80[i] = -2.08 +0.0032*(i-5); + } + //printf("10B %1.2f\n",_10B80[39]); + +_05PB40(maxInd2); + for (int i=0; i5) _05PB40[i] = -1.87 + 0.0022*(i-5); + else if (i<90 && i>=45) _05PB40[i] = -1.78 + 0.0015*(i-45); + } + //printf("05PB %1.2f %1.2f\n",_05PB40[44],_05PB40[74]); +_05PB50(maxInd2); + for (int i=0; i5) _05PB50[i] = -1.91 + 0.0022*(i-5); + else if (i<90 && i>=45) _05PB50[i] = -1.82 + 0.001*(i-45); + } + //printf("05PB %1.2f %1.2f\n",_05PB50[44],_05PB50[85]); +_05PB60(maxInd2); + for (int i=0; i5) _05PB60[i] = -1.96 + 0.0027*(i-5); + else if (i<90 && i>=45) _05PB60[i] = -1.85 + 0.0013*(i-45); + } + //printf("05PB %1.2f %1.2f\n",_05PB60[44],_05PB60[70]); +_05PB70(maxInd2); + for (int i=0; i5) _05PB70[i] = -1.99 + 0.0027*(i-5); + else if (i<90 && i>=45) _05PB70[i] = -1.88 + 0.001*(i-45); + } + //printf("05PB %1.2f %1.2f\n",_05PB70[44],_05PB70[54]); +_05PB80(maxInd3); + for (int i=0; i5) _05PB80[i] = -2.03 +0.003*(i-5); + } + //printf("05PB %1.2f\n",_05PB80[39]); + + + +//blue purple correction +//between 15PB to 4P +//maximum deviation 75PB + +//15PB +_15PB10(maxInd3); + for (int i=0; i5) _15PB10[i] = -1.66 +0.0035*(i-5); + } + //printf("15 %1.2f\n",_15PB10[49]); +_15PB20(maxInd2); + for (int i=0; i5) _15PB20[i] = -1.71 +0.00275*(i-5); + else if (i<90 && i>=45) _15PB20[i] = -1.60+0.0012*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB20[44],_15PB20[89]); + +_15PB30(maxInd2); + for (int i=0; i5) _15PB30[i] = -1.75 +0.0025*(i-5); + else if (i<90 && i>=45) _15PB30[i] = -1.65+0.002*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB30[44],_15PB30[89]); + +_15PB40(maxInd2); + for (int i=0; i5) _15PB40[i] = -1.79 +0.002*(i-5); + else if (i<90 && i>=45) _15PB40[i] = -1.71+0.002*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB40[44],_15PB40[89]); + +_15PB50(maxInd2); + for (int i=0; i5) _15PB50[i] = -1.82 +0.002*(i-5); + else if (i<90 && i>=45) _15PB50[i] = -1.74+0.0011*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB50[44],_15PB50[89]); + +_15PB60(maxInd2); + for (int i=0; i5) _15PB60[i] = -1.87 +0.0025*(i-5); + else if (i<90 && i>=45) _15PB60[i] = -1.77+0.001*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB60[44],_15PB60[89]); +_15PB70(maxInd3); + for (int i=0; i5) _15PB70[i] = -1.90 +0.0027*(i-5); + } + // printf("15 %1.2f\n",_15PB70[49]); +_15PB80(maxInd3); + for (int i=0; i5) _15PB80[i] = -1.93 +0.0027*(i-5); + } + //printf("15 %1.2f %1.2f\n",_15PB80[38], _15PB80[49]); + +//3PB +_3PB10(maxInd2); + for (int i=0; i5) _3PB10[i] = -1.56 +0.005*(i-5); + else if (i<90 && i>=45) _3PB10[i] = -1.36+0.001*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB10[44],_3PB10[89]); + +_3PB20(maxInd2); + for (int i=0; i5) _3PB20[i] = -1.59 +0.00275*(i-5); + else if (i<90 && i>=45) _3PB20[i] = -1.48+0.003*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB20[44],_3PB20[89]); + +_3PB30(maxInd2); + for (int i=0; i5) _3PB30[i] = -1.62 +0.00225*(i-5); + else if (i<90 && i>=45) _3PB30[i] = -1.53+0.0032*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB30[44],_3PB30[89]); + +_3PB40(maxInd2); + for (int i=0; i5) _3PB40[i] = -1.64 +0.0015*(i-5); + else if (i<90 && i>=45) _3PB40[i] = -1.58+0.0025*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB40[44],_3PB40[89]); + +_3PB50(maxInd2); + for (int i=0; i5) _3PB50[i] = -1.69 +0.00175*(i-5); + else if (i<90 && i>=45) _3PB50[i] = -1.62+0.002*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB50[44],_3PB50[89]); + +_3PB60(maxInd2); + for (int i=0; i5) _3PB60[i] = -1.73 +0.002*(i-5); + else if (i<90 && i>=45) _3PB60[i] = -1.65+0.0012*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB60[44],_3PB60[89]); +_3PB70(maxInd3); + for (int i=0; i5) _3PB70[i] = -1.76 +0.002*(i-5); + } + //printf("30 %1.2f\n",_3PB70[49]); +_3PB80(maxInd3); + for (int i=0; i5) _3PB80[i] = -1.78 +0.0025*(i-5); + } + //printf("30 %1.2f %1.2f\n",_3PB80[38], _3PB80[49]); + +//45PB +_45PB10(maxInd2); + for (int i=0; i5) _45PB10[i] = -1.46 +0.0045*(i-5); + else if (i<90 && i>=45) _45PB10[i] = -1.28+0.0025*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB10[44],_45PB10[89]); + +_45PB20(maxInd2); + for (int i=0; i5) _45PB20[i] = -1.48 +0.00275*(i-5); + else if (i<90 && i>=45) _45PB20[i] = -1.37+0.0025*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB20[44],_45PB20[89]); + +_45PB30(maxInd2); + for (int i=0; i5) _45PB30[i] = -1.51 +0.00175*(i-5); + else if (i<90 && i>=45) _45PB30[i] = -1.44+0.0035*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB30[44],_45PB30[89]); + +_45PB40(maxInd2); + for (int i=0; i5) _45PB40[i] = -1.52 +0.001*(i-5); + else if (i<90 && i>=45) _45PB40[i] = -1.48+0.003*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB40[44],_45PB40[89]); + +_45PB50(maxInd2); + for (int i=0; i5) _45PB50[i] = -1.55 +0.001*(i-5); + else if (i<90 && i>=45) _45PB50[i] = -1.51+0.0022*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB50[44],_45PB50[89]); + +_45PB60(maxInd2); + for (int i=0; i5) _45PB60[i] = -1.6 +0.0015*(i-5); + else if (i<90 && i>=45) _45PB60[i] = -1.54+0.001*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB60[44],_45PB60[89]); +_45PB70(maxInd3); + for (int i=0; i5) _45PB70[i] = -1.63 +0.0017*(i-5); + } + //printf("45 %1.2f\n",_45PB70[49]); +_45PB80(maxInd3); + for (int i=0; i5) _45PB80[i] = -1.67 +0.0025*(i-5); + } + //printf("45 %1.2f %1.2f\n",_45PB80[38], _45PB80[49]); + +//_6PB +_6PB10(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _6PB10[i] = -1.33 +0.005*(i-5); + else if (i<85 && i>=45) _6PB10[i] = -1.13+0.0045*(i-45); + else if (i<140 && i >=85) _6PB10[i] = -0.95+0.0015*(i-85); + } + //printf("60 %1.2f %1.2f %1.2f\n",_6PB10[44],_6PB10[84],_6PB10[139]); + +_6PB20(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _6PB20[i] = -1.36 +0.004*(i-5); + else if (i<85 && i>=45) _6PB20[i] = -1.20+0.00375*(i-45); + else if (i<140 && i >=85) _6PB20[i] = -1.05+0.0017*(i-85); + } + //printf("60 %1.2f %1.2f %1.2f\n",_6PB20[44],_6PB20[84],_6PB20[139]); + +_6PB30(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _6PB30[i] = -1.38 +0.00225*(i-5); + else if (i<85 && i>=45) _6PB30[i] = -1.29+0.00375*(i-45); + else if (i<140 && i >=85) _6PB30[i] = -1.14+0.002*(i-85); + } + //printf("60 %1.2f %1.2f %1.2f\n",_6PB30[44],_6PB30[84],_6PB30[139]); + +_6PB40(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _6PB40[i] = -1.39 +0.00125*(i-5); + else if (i<85 && i>=45) _6PB40[i] = -1.34+0.00275*(i-45); + else if (i<140 && i >=85) _6PB40[i] = -1.23+0.002*(i-85); + } + //printf("60 %1.2f %1.2f %1.2f\n",_6PB40[44],_6PB40[84],_6PB40[139]); + +_6PB50(maxInd2);//limits -1.3 -1.11 + for (int i=0; i5) _6PB50[i] = -1.43 +0.00125*(i-5); + else if (i<90 && i>=45) _6PB50[i] = -1.38+0.00225*(i-45); + } + //printf("60 %1.2f %1.2f \n",_6PB50[44],_6PB50[89]); + +_6PB60(maxInd2);//limits -1.3 -1.11 + for (int i=0; i5) _6PB60[i] = -1.46 +0.0012*(i-5); + else if (i<90 && i>=45) _6PB60[i] = -1.40+0.000875*(i-45); + } + //printf("60 %1.2f %1.2f\n",_6PB60[44],_6PB60[89]); +_6PB70(maxInd3); + for (int i=0; i5) _6PB70[i] = -1.49 +0.0018*(i-5); + } + //printf("6 %1.2f\n",_6PB70[49]); +_6PB80(maxInd3); + for (int i=0; i5) _6PB80[i] = -1.52 +0.0022*(i-5); + } + //printf("6 %1.2f %1.2f\n",_6PB80[38], _6PB80[49]); + + +//_75PB : notation Munsell for maximum deviation blue purple +_75PB10(maxInd);//limits hue -1.23 -0.71 _75PBx x=Luminance eg_75PB10 for L >5 and L<=15 + for (int i=0; i140 + if (i<45 && i>5) _75PB10[i] = -1.23 +0.0065*(i-5); + else if (i<85 && i>=45) _75PB10[i] = -0.97+0.00375*(i-45); + else if (i<140 && i >=85) _75PB10[i] = -0.82+0.0015*(i-85); + } + //printf("75 %1.2f %1.2f %1.2f\n",_75PB10[44],_75PB10[84],_75PB10[139]); + +_75PB20(maxInd);//limits -1.24 -0.79 for L>15 <=25 + for (int i=0; i5) _75PB20[i] = -1.24 +0.004*(i-5); + else if (i<85 && i>=45) _75PB20[i] = -1.08+0.00425*(i-45); + else if (i<140 && i >=85) _75PB20[i] = -0.91+0.0017*(i-85); + } + //printf("75 %1.2f %1.2f %1.2f\n",_75PB20[44],_75PB20[84],_75PB20[139]); + +_75PB30(maxInd);//limits -1.25 -0.85 + for (int i=0; i5) _75PB30[i] = -1.25 +0.00275*(i-5); + else if (i<85 && i>=45) _75PB30[i] = -1.14+0.004*(i-45); + else if (i<140 && i >=85) _75PB30[i] = -0.98+0.0015*(i-85); + } + //printf("75 %1.2f %1.2f %1.2f\n",_75PB30[44],_75PB30[84],_75PB30[139]); + +_75PB40(maxInd);//limits -1.27 -0.92 + for (int i=0; i5) _75PB40[i] = -1.27 +0.002*(i-5); + else if (i<85 && i>=45) _75PB40[i] = -1.19+0.003*(i-45); + else if (i<140 && i >=85) _75PB40[i] = -1.07+0.0022*(i-85); + } + //printf("75 %1.2f %1.2f %1.2f\n",_75PB40[44],_75PB40[84],_75PB40[139]); + +_75PB50(maxInd2);//limits -1.3 -1.11 + for (int i=0; i5) _75PB50[i] = -1.3 +0.00175*(i-5); + else if (i<90 && i>=45) _75PB50[i] = -1.23+0.0025*(i-45); + } + //printf("75 %1.2f %1.2f\n",_75PB50[44],_75PB50[89]); + +_75PB60(maxInd2); + for (int i=0; i5) _75PB60[i] = -1.32 +0.0015*(i-5); + else if (i<90 && i>=45) _75PB60[i] = -1.26+0.002*(i-45); + } + //printf("75 %1.2f %1.2f \n",_75PB60[44],_75PB60[89]); + +_75PB70(maxInd3); + for (int i=0; i5) _75PB70[i] = -1.34 +0.002*(i-5); + } +_75PB80(maxInd3); + for (int i=0; i5) _75PB80[i] = -1.35 +0.00125*(i-5); + } + + +_9PB10(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _9PB10[i] = -1.09 +0.00475*(i-5); + else if (i<85 && i>=45) _9PB10[i] = -0.9+0.003*(i-45); + else if (i<140 && i >=85) _9PB10[i] = -0.78+0.0013*(i-85); + } + //printf("90 %1.2f %1.2f %1.2f\n",_9PB10[44],_9PB10[84],_9PB10[139]); + +_9PB20(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _9PB20[i] = -1.12 +0.0035*(i-5); + else if (i<85 && i>=45) _9PB20[i] = -0.98+0.00325*(i-45); + else if (i<140 && i >=85) _9PB20[i] = -0.85+0.0015*(i-85); + } + //printf("90 %1.2f %1.2f %1.2f\n",_9PB20[44],_9PB20[84],_9PB20[139]); + +_9PB30(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _9PB30[i] = -1.14 +0.0028*(i-5); + else if (i<85 && i>=45) _9PB30[i] = -1.03+0.003*(i-45); + else if (i<140 && i >=85) _9PB30[i] = -0.91+0.0017*(i-85); + } + //printf("90 %1.2f %1.2f %1.2f\n",_9PB30[44],_9PB30[84],_9PB30[139]); + +_9PB40(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _9PB40[i] = -1.16 +0.002*(i-5); + else if (i<85 && i>=45) _9PB40[i] = -1.08+0.00275*(i-45); + else if (i<140 && i >=85) _9PB40[i] = -0.97+0.0016*(i-85); + } + //printf("90 %1.2f %1.2f %1.2f\n",_9PB40[44],_9PB40[84],_9PB40[139]); + +_9PB50(maxInd2); + for (int i=0; i5) _9PB50[i] = -1.19 +0.00175*(i-5); + else if (i<90 && i>=45) _9PB50[i] = -1.12+0.00225*(i-45); + } + //printf("90 %1.2f %1.2f \n",_9PB50[44],_9PB50[84]); + +_9PB60(maxInd2); + for (int i=0; i5) _9PB60[i] = -1.21 +0.0015*(i-5); + else if (i<90 && i>=45) _9PB60[i] = -1.15+0.002*(i-45); + } + //printf("90 %1.2f %1.2f \n",_9PB60[44],_9PB60[89]); +_9PB70(maxInd3); + for (int i=0; i5) _9PB70[i] = -1.23 +0.0018*(i-5); + } + //printf("9 %1.2f\n",_9PB70[49]); +_9PB80(maxInd3); + for (int i=0; i5) _9PB80[i] = -1.24 +0.002*(i-5); + } + //printf("9 %1.2f %1.2f\n",_9PB80[38], _9PB80[49]); + + +//10PB +_10PB10(maxInd); + for (int i=0; i5) _10PB10[i] = -1.02 +0.00425*(i-5); + else if (i<85 && i>=45) _10PB10[i] = -0.85+0.0025*(i-45); + else if (i<140 && i >=85) _10PB10[i] = -0.75+0.0012*(i-85); + } + //printf("10 %1.2f %1.2f %1.2f\n",_10PB10[44],_10PB10[84],_10PB10[139]); + +_10PB20(maxInd); + for (int i=0; i5) _10PB20[i] = -1.05 +0.00325*(i-5); + else if (i<85 && i>=45) _10PB20[i] = -0.92+0.00275*(i-45); + else if (i<140 && i >=85) _10PB20[i] = -0.81+0.0014*(i-85); + } + //printf("10 %1.2f %1.2f %1.2f\n",_10PB20[44],_10PB20[84],_10PB20[139]); + +_10PB30(maxInd); + for (int i=0; i5) _10PB30[i] = -1.07 +0.00275*(i-5); + else if (i<85 && i>=45) _10PB30[i] = -0.96+0.0025*(i-45); + else if (i<140 && i >=85) _10PB30[i] = -0.86+0.0015*(i-85); + } + //printf("10 %1.2f %1.2f %1.2f\n",_10PB30[44],_10PB30[84],_10PB30[139]); + +_10PB40(maxInd); + for (int i=0; i5) _10PB40[i] = -1.09 +0.002*(i-5); + else if (i<85 && i>=45) _10PB40[i] = -1.01+0.00225*(i-45); + else if (i<140 && i >=85) _10PB40[i] = -0.92+0.0016*(i-85); + } + //printf("10 %1.2f %1.2f %1.2f\n",_10PB40[44],_10PB40[84],_10PB40[139]); + +_10PB50(maxInd2); + for (int i=0; i5) _10PB50[i] = -1.12 +0.00175*(i-5); + else if (i<90 && i>=45) _10PB50[i] = -1.05+0.00225*(i-45); + } + //printf("10 %1.2f %1.2f\n",_10PB50[44],_10PB50[84]); + +_10PB60(maxInd2); + for (int i=0; i5) _10PB60[i] = -1.14 +0.0015*(i-5); + else if (i<90 && i>=45) _10PB60[i] = -1.08+0.00225*(i-45); + } + //printf("10 %1.2f %1.2f\n",_10PB60[44],_10PB60[89]); + + +//1P +_1P10(maxInd); + for (int i=0; i5) _1P10[i] = -0.96 +0.00375*(i-5); + else if (i<85 && i>=45) _1P10[i] = -0.81+0.00225*(i-45); + else if (i<140 && i >=85) _1P10[i] = -0.72+0.001*(i-85); + } + //printf("1P %1.2f %1.2f %1.2f\n",_1P10[44],_1P10[84],_1P10[139]); + +_1P20(maxInd); + for (int i=0; i5) _1P20[i] = -1.0 +0.00325*(i-5); + else if (i<85 && i>=45) _1P20[i] = -0.87+0.0025*(i-45); + else if (i<140 && i >=85) _1P20[i] = -0.77+0.0012*(i-85); + } + //printf("1P %1.2f %1.2f %1.2f\n",_1P20[44],_1P20[84],_1P20[139]); + +_1P30(maxInd); + for (int i=0; i5) _1P30[i] = -1.02 +0.00275*(i-5); + else if (i<85 && i>=45) _1P30[i] = -0.91+0.00225*(i-45); + else if (i<140 && i >=85) _1P30[i] = -0.82+0.0011*(i-85); + } + //printf("1P %1.2f %1.2f %1.2f\n",_1P30[44],_1P30[84],_1P30[139]); + +_1P40(maxInd); + for (int i=0; i5) _1P40[i] = -1.04 +0.00225*(i-5); + else if (i<85 && i>=45) _1P40[i] = -0.95+0.00225*(i-45); + else if (i<140 && i >=85) _1P40[i] = -0.86+0.0015*(i-85); + } + //printf("1P %1.2f %1.2f %1.2f\n",_1P40[44],_1P40[84],_1P40[139]); + +_1P50(maxInd2); + for (int i=0; i5) _1P50[i] = -1.06 +0.002*(i-5); + else if (i<90 && i>=45) _1P50[i] = -0.98+0.00175*(i-45); + } + //printf("1P %1.2f %1.2f \n",_1P50[44],_1P50[89]); + +_1P60(maxInd2); + for (int i=0; i5) _1P60[i] = -1.07 +0.0015*(i-5); + else if (i<90 && i>=45) _1P60[i] = -1.01+0.00175*(i-45); + } + //printf("1P %1.2f %1.2f \n",_1P60[44],_1P60[84],_1P60[139]); + + //4P +_4P10(maxInd); + for (int i=0; i5) _4P10[i] = -0.78 +0.002*(i-5); + else if (i<85 && i>=45) _4P10[i] = -0.7+0.00125*(i-45); + else if (i<140 && i >=85) _4P10[i] = -0.65+0.001*(i-85); + } + //printf("4P %1.2f %1.2f %1.2f\n",_4P10[44],_4P10[84],_4P10[139]); + +_4P20(maxInd); + for (int i=0; i5) _4P20[i] = -0.84 +0.0025*(i-5); + else if (i<85 && i>=45) _4P20[i] = -0.74+0.00175*(i-45); + else if (i<140 && i >=85) _4P20[i] = -0.67+0.00085*(i-85); + } + //printf("4P %1.2f %1.2f %1.2f\n",_4P20[44],_4P20[84],_4P20[139]); + +_4P30(maxInd); + for (int i=0; i5) _4P30[i] = -0.85 +0.00225*(i-5); + else if (i<85 && i>=45) _4P30[i] = -0.76+0.00125*(i-45); + else if (i<140 && i >=85) _4P30[i] = -0.71+0.001*(i-85); + } + //printf("4P %1.2f %1.2f %1.2f\n",_4P30[44],_4P30[84],_4P30[139]); + +_4P40(maxInd); + for (int i=0; i5) _4P40[i] = -0.87 +0.00175*(i-5); + else if (i<85 && i>=45) _4P40[i] = -0.8+0.00175*(i-45); + else if (i<140 && i >=85) _4P40[i] = -0.73+0.00075*(i-85); + } + //printf("4P %1.2f %1.2f %1.2f\n",_4P40[44],_4P40[84],_4P40[139]); + +_4P50(maxInd2); + for (int i=0; i5) _4P50[i] = -0.88 +0.0015*(i-5); + else if (i<90 && i>=45) _4P50[i] = -0.82+0.0015*(i-45); + } + //printf("4P %1.2f %1.2f \n",_4P50[44],_4P50[89]); + +_4P60(maxInd2); + for (int i=0; i5) _4P60[i] = -0.89 +0.00125*(i-5); + else if (i<90 && i>=45) _4P60[i] = -0.84+0.00125*(i-45); + } + //printf("4P %1.2f %1.2f\n",_4P60[44],_4P60[89]); + + +//red yellow correction +_10YR20(maxInd2); + for (int i=0; i5) _10YR20[i] = 1.22 +0.002*(i-5); + else if (i<90 && i>=45) _10YR20[i] = 1.30+0.006*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR20[44],_10YR20[56]); +_10YR30(maxInd2); + for (int i=0; i5) _10YR30[i] = 1.27 +0.00175*(i-5); + else if (i<90 && i>=45) _10YR30[i] = 1.34+0.0017*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR30[44],_10YR30[75]); +_10YR40(maxInd2); + for (int i=0; i5) _10YR40[i] = 1.32 +0.00025*(i-5); + else if (i<90 && i>=45) _10YR40[i] = 1.33+0.0015*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR40[44],_10YR40[85]); +_10YR50(maxInd2); + for (int i=0; i5) _10YR50[i] = 1.35 +0.000*(i-5); + else if (i<90 && i>=45) _10YR50[i] = 1.35+0.0012*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR50[44],_10YR50[80]); +_10YR60(maxInd); + for (int i=0; i5) _10YR60[i] = 1.38 - 0.00025*(i-5); + else if (i<85 && i>=45) _10YR60[i] = 1.37+0.0005*(i-45); + else if (i<140 && i >=85) _10YR60[i] = 1.39+0.0013*(i-85); + } + //printf("10YR %1.2f %1.2f %1.2f\n",_10YR60[44],_10YR60[85],_10YR60[139] ); +_10YR70(maxInd); + for (int i=0; i5) _10YR70[i] = 1.41 - 0.0005*(i-5); + else if (i<85 && i>=45) _10YR70[i] = 1.39+0.000*(i-45); + else if (i<140 && i >=85) _10YR70[i] = 1.39+0.0013*(i-85); + } + //printf("10YR %1.2f %1.2f %1.2f\n",_10YR70[44],_10YR70[85],_10YR70[139] ); +_10YR80(maxInd); + for (int i=0; i5) _10YR80[i] = 1.45 - 0.00125*(i-5); + else if (i<85 && i>=45) _10YR80[i] = 1.40+0.000*(i-45); + else if (i<140 && i >=85) _10YR80[i] = 1.40+0.00072*(i-85);//1.436 + } + //printf("10YR %1.2f %1.2f %1.2f\n",_10YR80[44],_10YR80[84],_10YR80[139] ); +_10YR90(maxInd2); + for (int i=0; i5) _10YR90[i] = 1.48 -0.001*(i-5); + else if (i<90 && i>=45) _10YR90[i] = 1.44-0.0009*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR90[45],_10YR90[80]); +_85YR20(maxInd3); + for (int i=0; i5) _85YR20[i] = 1.12 +0.004*(i-5); + } + + //printf("85YR %1.2f \n",_85YR20[44]); +_85YR30(maxInd2); + for (int i=0; i5) _85YR30[i] = 1.16 + 0.0025*(i-5); + else if (i<90 && i>=45) _85YR30[i] = 1.26+0.0028*(i-45); + } + //printf("85YR %1.2f %1.2f\n",_85YR30[44],_85YR30[75]); +_85YR40(maxInd2); + for (int i=0; i5) _85YR40[i] = 1.20 + 0.0015*(i-5); + else if (i<90 && i>=45) _85YR40[i] = 1.26+0.0024*(i-45); + } + //printf("85YR %1.2f %1.2f\n",_85YR40[44],_85YR40[75]); +_85YR50(maxInd); + for (int i=0; i5) _85YR50[i] = 1.24 + 0.0005*(i-5); + else if (i<85 && i>=45) _85YR50[i] = 1.26+0.002*(i-45); + else if (i<140 && i >=85) _85YR50[i] = 1.34+0.0015*(i-85); + } + //printf("85YR %1.2f %1.2f %1.2f\n",_85YR50[44],_85YR50[85],_85YR50[110] ); +_85YR60(maxInd); + for (int i=0; i5) _85YR60[i] = 1.27 + 0.00025*(i-5); + else if (i<85 && i>=45) _85YR60[i] = 1.28+0.0015*(i-45); + else if (i<140 && i >=85) _85YR60[i] = 1.34+0.0012*(i-85); + } + //printf("85YR %1.2f %1.2f %1.2f\n",_85YR60[44],_85YR60[85],_85YR60[139] ); + +_85YR70(maxInd); + for (int i=0; i5) _85YR70[i] = 1.31 - 0.00025*(i-5); + else if (i<85 && i>=45) _85YR70[i] = 1.30+0.0005*(i-45); + else if (i<140 && i >=85) _85YR70[i] = 1.32+0.0012*(i-85); + } + //printf("85YR %1.2f %1.2f %1.2f\n",_85YR70[44],_85YR70[85],_85YR70[139] ); +_85YR80(maxInd); + for (int i=0; i5) _85YR80[i] = 1.35 - 0.00075*(i-5); + else if (i<85 && i>=45) _85YR80[i] = 1.32+0.00025*(i-45); + else if (i<140 && i >=85) _85YR80[i] = 1.33+0.00125*(i-85); + } + //printf("85YR %1.2f %1.2f %1.2f\n",_85YR80[44],_85YR80[85],_85YR80[139] ); +_85YR90(maxInd2); + for (int i=0; i5) _85YR90[i] = 1.39 - 0.00125*(i-5); + else if (i<90 && i>=45) _85YR90[i] = 1.34+0.00*(i-45); + } + //printf("85YR %1.2f %1.2f\n",_85YR90[44],_85YR90[85]); + +//7YR +_7YR30(maxInd2); + for (int i=0; i5) _7YR30[i] = 1.06 + 0.0028*(i-5); + else if (i<90 && i>=45) _7YR30[i] = 1.17+0.0045*(i-45); + } + //printf("7YR %1.2f %1.2f\n",_7YR30[44],_7YR30[66]); +_7YR40(maxInd2); + for (int i=0; i5) _7YR40[i] = 1.10 + 0.0018*(i-5); + else if (i<90 && i>=45) _7YR40[i] = 1.17+0.0035*(i-45); + } + //printf("7YR %1.2f %1.2f\n",_7YR40[44],_7YR40[89]); +_7YR50(maxInd2); + for (int i=0; i5) _7YR50[i] = 1.14 + 0.00125*(i-5); + else if (i<90 && i>=45) _7YR50[i] = 1.19+0.002*(i-45); + } + //printf("7YR %1.2f %1.2f\n",_7YR50[44],_7YR50[89] ); +_7YR60(maxInd); + for (int i=0; i5) _7YR60[i] = 1.17 + 0.00075*(i-5); + else if (i<85 && i>=45) _7YR60[i] = 1.20+0.00175*(i-45); + else if (i<140 && i >=85) _7YR60[i] = 1.27+0.002*(i-85); + } + //printf("7YR %1.2f %1.2f %1.2f\n",_7YR60[44],_7YR60[84],_7YR60[125] ); + +_7YR70(maxInd); + for (int i=0; i5) _7YR70[i] = 1.20 + 0.0005*(i-5); + else if (i<85 && i>=45) _7YR70[i] = 1.22+0.00125*(i-45); + else if (i<140 && i >=85) _7YR70[i] = 1.27+0.0015*(i-85); + } + //printf("7YR %1.2f %1.2f %1.2f\n",_7YR70[44],_7YR70[84],_7YR70[125] ); +_7YR80(maxInd3); + for (int i=0; i5) _7YR80[i] = 1.29 - 0.0008*(i-5); + } + //printf("7YR %1.2f \n",_7YR80[44] ); +_55YR30(maxInd3); + for (int i=0; i5) _55YR30[i] = 0.96 + 0.0038*(i-5); + } + //printf("55YR %1.2f \n",_55YR30[44] ); +_55YR40(maxInd2); + for (int i=0; i5) _55YR40[i] = 1.01 + 0.0022*(i-5); + else if (i<90 && i>=45) _55YR40[i] = 1.10+0.0037*(i-45); + } + //printf("55YR %1.2f %1.2f\n",_55YR40[44],_55YR40[89] ); +_55YR50(maxInd); + for (int i=0; i5) _55YR50[i] = 1.06 + 0.0015*(i-5); + else if (i<85 && i>=45) _55YR50[i] = 1.12+0.00225*(i-45); + else if (i<140 && i >=85) _55YR50[i] = 1.21+0.0015*(i-85); + } + //printf("55YR %1.2f %1.2f %1.2f\n",_55YR50[44],_55YR50[84],_55YR50[125] ); +_55YR60(maxInd); + for (int i=0; i5) _55YR60[i] = 1.08 + 0.0012*(i-5); + else if (i<85 && i>=45) _55YR60[i] = 1.13+0.0018*(i-45); + else if (i<140 && i >=85) _55YR60[i] = 1.20+0.0025*(i-85); + } + //printf("55YR %1.2f %1.2f %1.2f\n",_55YR60[44],_55YR60[84],_55YR60[125] ); +_55YR70(maxInd); + for (int i=0; i5) _55YR70[i] = 1.11 + 0.00075*(i-5); + else if (i<85 && i>=45) _55YR70[i] = 1.14+0.0012*(i-45); + else if (i<140 && i >=85) _55YR70[i] = 1.19+0.00225*(i-85); + } + //printf("55YR %1.2f %1.2f %1.2f\n",_55YR70[44],_55YR70[84],_55YR70[125] ); +_55YR80(maxInd); + for (int i=0; i5) _55YR80[i] = 1.16 + 0.00*(i-5); + else if (i<85 && i>=45) _55YR80[i] = 1.16+0.00075*(i-45); + else if (i<140 && i >=85) _55YR80[i] = 1.19+0.00175*(i-85); + } + //printf("55YR %1.2f %1.2f %1.2f\n",_55YR80[44],_55YR80[84],_55YR80[125] ); +_55YR90(maxInd3); + for (int i=0; i5) _55YR90[i] = 1.19 - 0.0005*(i-5); + } + //printf("55YR %1.2f \n",_55YR90[44] ); + +_4YR30(maxInd2); + for (int i=0; i5) _4YR30[i] = 0.87 + 0.0035*(i-5); + else if (i<90 && i>=45) _4YR30[i] = 1.01+0.0043*(i-45); + } + //printf("4YR %1.2f %1.2f\n",_4YR30[44],_4YR30[78] ); +_4YR40(maxInd2); + for (int i=0; i5) _4YR40[i] = 0.92 + 0.0025*(i-5); + else if (i<90 && i>=45) _4YR40[i] = 1.02+0.0033*(i-45); + } + //printf("4YR %1.2f %1.2f\n",_4YR40[44],_4YR40[74] ); +_4YR50(maxInd2); + for (int i=0; i5) _4YR50[i] = 0.97 + 0.0015*(i-5); + else if (i<90 && i>=45) _4YR50[i] = 1.03+0.0025*(i-45); + } + //printf("4YR %1.2f %1.2f\n",_4YR50[44],_4YR50[85] ); +_4YR60(maxInd); + for (int i=0; i5) _4YR60[i] = 0.99 + 0.00125*(i-5); + else if (i<85 && i>=45) _4YR60[i] = 1.04+0.002*(i-45); + else if (i<140 && i >=85) _4YR60[i] = 1.12+0.003*(i-85); + } + //printf("4YR %1.2f %1.2f %1.2f\n",_4YR60[44],_4YR60[84],_4YR60[125] ); +_4YR70(maxInd); + for (int i=0; i5) _4YR70[i] = 1.02 + 0.00075*(i-5); + else if (i<85 && i>=45) _4YR70[i] = 1.05+0.00175*(i-45); + else if (i<140 && i >=85) _4YR70[i] = 1.12+0.002*(i-85); + } + //printf("4YR %1.2f %1.2f %1.2f\n",_4YR70[44],_4YR70[84],_4YR70[125] ); +_4YR80(maxInd3); + for (int i=0; i5) _4YR80[i] = 1.09 - 0.0002*(i-5); + } + //printf("4YR %1.2f \n",_4YR80[41] ); + +_25YR30(maxInd2); + for (int i=0; i5) _25YR30[i] = 0.77 + 0.004*(i-5); + else if (i<90 && i>=45) _25YR30[i] = 0.94+0.004*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR30[44],_25YR30[74] ); +_25YR40(maxInd2); + for (int i=0; i5) _25YR40[i] = 0.82 + 0.003*(i-5); + else if (i<90 && i>=45) _25YR40[i] = 0.94+0.002*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR40[44],_25YR40[84] ); +_25YR50(maxInd2); + for (int i=0; i5) _25YR50[i] = 0.87+ 0.002*(i-5); + else if (i<90 && i>=45) _25YR50[i] = 0.95+0.003*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR50[44],_25YR50[84] ); +_25YR60(maxInd2); + for (int i=0; i5) _25YR60[i] = 0.89+ 0.0015*(i-5); + else if (i<90 && i>=45) _25YR60[i] = 0.95+0.004*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR60[44],_25YR60[84] ); +_25YR70(maxInd2); + for (int i=0; i5) _25YR70[i] = 0.92+ 0.001*(i-5); + else if (i<90 && i>=45) _25YR70[i] = 0.96+0.003*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR70[44],_25YR70[84] ); + +_10R30(maxInd2); + for (int i=0; i5) _10R30[i] = 0.62 + 0.00225*(i-5); + else if (i<90 && i>=45) _10R30[i] = 0.71+0.003*(i-45); + } + //printf("10R %1.2f %1.2f\n",_10R30[44],_10R30[84] ); +_10R40(maxInd2); + for (int i=0; i5) _10R40[i] = 0.66 + 0.0025*(i-5); + else if (i<90 && i>=45) _10R40[i] = 0.76+0.0035*(i-45); + } + //printf("10R %1.2f %1.2f\n",_10R40[44],_10R40[84] ); +_10R50(maxInd2); + for (int i=0; i5) _10R50[i] = 0.71 + 0.002*(i-5); + else if (i<90 && i>=45) _10R50[i] = 0.79+0.0043*(i-45); + } + //printf("10R %1.2f %1.2f\n",_10R50[44],_10R50[84] ); +_10R60(maxInd); + for (int i=0; i5) _10R60[i] = 0.73 + 0.00175*(i-5); + else if (i<85 && i>=45) _10R60[i] = 0.80 +0.0033*(i-45); + else if (i<140 && i >=85) _10R60[i] = 0.93+0.0018*(i-85); + } + //printf("10R %1.2f %1.2f %1.2f\n",_10R60[44],_10R60[84],_10R60[125] ); +_10R70(maxInd); + for (int i=0; i5) _10R70[i] = 0.75 + 0.0015*(i-5); + else if (i<85 && i>=45) _10R70[i] = 0.81 +0.0017*(i-45); + else if (i<140 && i >=85) _10R70[i] = 0.88+0.0025*(i-85); + } + //printf("10R %1.2f %1.2f %1.2f\n",_10R70[44],_10R70[84],_10R70[125] ); + +_9R30(maxInd2); + for (int i=0; i5) _9R30[i] = 0.57 + 0.002*(i-5); + else if (i<90 && i>=45) _9R30[i] = 0.65+0.0018*(i-45); + } + //printf("9R %1.2f %1.2f\n",_9R30[44],_9R30[84] ); +_9R40(maxInd2); + for (int i=0; i5) _9R40[i] = 0.61 + 0.002*(i-5); + else if (i<90 && i>=45) _9R40[i] = 0.69+0.0025*(i-45); + } + //printf("9R %1.2f %1.2f\n",_9R40[44],_9R40[84] ); +_9R50(maxInd); + for (int i=0; i5) _9R50[i] = 0.66 + 0.00175*(i-5); + else if (i<85 && i>=45) _9R50[i] = 0.73 +0.0025*(i-45); + else if (i<140 && i >=85) _9R50[i] = 0.83+0.0035*(i-85); + } + //printf("9R %1.2f %1.2f %1.2f\n",_9R50[44],_9R50[84],_9R50[125] ); +_9R60(maxInd); + for (int i=0; i5) _9R60[i] = 0.68 + 0.0015*(i-5); + else if (i<85 && i>=45) _9R60[i] = 0.74 +0.0022*(i-45); + else if (i<140 && i >=85) _9R60[i] = 0.93+0.0022*(i-85); + } + //printf("9R %1.2f %1.2f %1.2f\n",_9R60[44],_9R60[84],_9R60[125] ); +_9R70(maxInd2); + for (int i=0; i5) _9R70[i] = 0.70 + 0.0012*(i-5); + else if (i<90 && i>=45) _9R70[i] = 0.75+0.0013*(i-45); + } + //printf("9R %1.2f %1.2f\n",_9R70[44],_9R70[84] ); + +_7R30(maxInd2); + for (int i=0; i5) _7R30[i] = 0.48 + 0.0015*(i-5); + else if (i<90 && i>=45) _7R30[i] = 0.54-0.0005*(i-45); + } + //printf("7R %1.2f %1.2f\n",_7R30[44],_7R30[84] ); +_7R40(maxInd2); + for (int i=0; i5) _7R40[i] = 0.51 + 0.0015*(i-5); + else if (i<90 && i>=45) _7R40[i] = 0.57+0.0005*(i-45); + } + //printf("7R %1.2f %1.2f\n",_7R40[44],_7R40[84] ); +_7R50(maxInd); + for (int i=0; i5) _7R50[i] = 0.54 + 0.0015*(i-5); + else if (i<85 && i>=45) _7R50[i] = 0.60 +0.0005*(i-45); + else if (i<140 && i >=85) _7R50[i] = 0.62+0.0025*(i-85); + } + //printf("7R %1.2f %1.2f %1.2f\n",_7R50[44],_7R50[84],_7R50[125] ); +_7R60(maxInd); + for (int i=0; i5) _7R60[i] = 0.58 + 0.00075*(i-5); + else if (i<85 && i>=45) _7R60[i] = 0.61 +0.00075*(i-45); + else if (i<140 && i >=85) _7R60[i] = 0.64+0.001*(i-85); + } + //printf("7R %1.2f %1.2f %1.2f\n",_7R60[44],_7R60[84],_7R60[107] ); +_7R70(maxInd2); + for (int i=0; i5) _7R70[i] = 0.59 + 0.00075*(i-5); + else if (i<90 && i>=45) _7R70[i] = 0.62+0.00075*(i-45); + } + //printf("7R %1.2f %1.2f\n",_7R70[44],_7R70[84] ); + +//5R 1 2 3 + +//5R +_5R10(maxInd2); + for (int i=0; i5) _5R10[i] = 0.10 - 0.0018*(i-5); + else if (i<90 && i>=45) _5R10[i] = 0.035-0.003*(i-45); + } + //printf("5R %1.2f %1.2f\n",_5R10[44],_5R10[51] ); +_5R20(maxInd2); + for (int i=0; i5) _5R20[i] = 0.26 - 0.00075*(i-5); + else if (i<90 && i>=45) _5R20[i] = 0.023-0.0002*(i-45); + } + //printf("5R %1.2f %1.2f\n",_5R20[44],_5R20[70] ); +_5R30(maxInd2); + for (int i=0; i5) _5R30[i] = 0.39 + 0.00075*(i-5); + else if (i<90 && i>=45) _5R30[i] = 0.42-0.0007*(i-45); + } + //printf("5R %1.2f %1.2f\n",_5R30[44],_5R30[85] ); + +//25R +_25R10(maxInd3); + for (int i=0; i5) _25R10[i] = -0.03 - 0.002*(i-5); + } + //printf("25R %1.2f \n",_25R10[44]); +_25R20(maxInd2); + for (int i=0; i5) _25R20[i] = 0.13 - 0.0012*(i-5); + else if (i<90 && i>=45) _25R20[i] = 0.08-0.002*(i-45); + } + //printf("25R %1.2f %1.2f\n",_25R20[44],_25R20[69] ); + //25R30: 0.28, 0.26, 0.22 +_25R30(maxInd2); + for (int i=0; i5) _25R30[i] = 0.28 - 0.0005*(i-5); + else if (i<90 && i>=45) _25R30[i] = 0.26-0.0009*(i-45); + } + //printf("25R %1.2f %1.2f\n",_25R30[44],_25R30[85] ); + + +_10RP10(maxInd3); + for (int i=0; i5) _10RP10[i] = -0.16 - 0.0017*(i-5); + } + //printf("10RP %1.2f \n",_10RP10[44]); +_10RP20(maxInd2); + for (int i=0; i5) _10RP20[i] = 0.0 - 0.0018*(i-5); + else if (i<90 && i>=45) _10RP20[i] = -0.07-0.0012*(i-45); + } + //printf("10RP %1.2f %1.2f\n",_10RP20[44],_10RP20[69] ); +_10RP30(maxInd2); + for (int i=0; i5) _10RP30[i] = 0.15 - 0.001*(i-5); + else if (i<90 && i>=45) _10RP30[i] = 0.11-0.0012*(i-45); + } + //printf("10RP %1.2f %1.2f\n",_10RP30[44],_10RP30[85] ); + +//7G +_7G30(maxInd); + for (int i=0; i5) _7G30[i] = 2.90 + 0.0027*(i-5); + else if (i<85 && i>=45) _7G30[i] = 3.01+0.0005*(i-45); + else if (i<140 && i >=85) _7G30[i] = 3.03+0.00075*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G30[44],_7G30[84],_7G30[125] ); +_7G40(maxInd); + for (int i=0; i5) _7G40[i] = 2.89 + 0.00125*(i-5); + else if (i<85 && i>=45) _7G40[i] = 2.94+0.0015*(i-45); + else if (i<140 && i >=85) _7G40[i] = 3.0+0.001*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G40[44],_7G40[84],_7G40[125] ); +_7G50(maxInd); + for (int i=0; i5) _7G50[i] = 2.87 + 0.0015*(i-5); + else if (i<85 && i>=45) _7G50[i] = 2.93+0.00125*(i-45); + else if (i<140 && i >=85) _7G50[i] = 2.98+0.001*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G50[44],_7G50[84],_7G50[125] ); +_7G60(maxInd); + for (int i=0; i5) _7G60[i] = 2.86 + 0.00125*(i-5); + else if (i<85 && i>=45) _7G60[i] = 2.91+0.00125*(i-45); + else if (i<140 && i >=85) _7G60[i] = 2.96+0.00075*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G60[44],_7G60[84],_7G60[125] ); +_7G70(maxInd); + for (int i=0; i5) _7G70[i] = 2.85 + 0.001*(i-5); + else if (i<85 && i>=45) _7G70[i] = 2.89+0.00125*(i-45); + else if (i<140 && i >=85) _7G70[i] = 2.94+0.00075*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G70[44],_7G70[84],_7G70[125] ); +_7G80(maxInd); + for (int i=0; i5) _7G80[i] = 2.84 + 0.001*(i-5); + else if (i<85 && i>=45) _7G80[i] = 2.88+0.001*(i-45); + else if (i<140 && i >=85) _7G80[i] = 2.92+0.001*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G80[44],_7G80[84],_7G80[125] ); + + +//5G +_5G30(maxInd); + for (int i=0; i5) _5G30[i] = 2.82 + 0.00175*(i-5); + else if (i<85 && i>=45) _5G30[i] = 2.89+0.0018*(i-45); + else if (i<140 && i >=85) _5G30[i] = 2.96+0.0012*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G30[44],_5G30[84],_5G30[125] ); +_5G40(maxInd); + for (int i=0; i5) _5G40[i] = 2.80 + 0.0015*(i-5); + else if (i<85 && i>=45) _5G40[i] = 2.86+0.00175*(i-45); + else if (i<140 && i >=85) _5G40[i] = 2.93+0.00125*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G40[44],_5G40[84],_5G40[125] ); +_5G50(maxInd); + for (int i=0; i5) _5G50[i] = 2.79 + 0.001*(i-5); + else if (i<85 && i>=45) _5G50[i] = 2.84+0.0015*(i-45); + else if (i<140 && i >=85) _5G50[i] = 2.90+0.0015*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G50[44],_5G50[84],_5G50[125] ); +_5G60(maxInd); + for (int i=0; i5) _5G60[i] = 2.78 + 0.001*(i-5); + else if (i<85 && i>=45) _5G60[i] = 2.82+0.00175*(i-45); + else if (i<140 && i >=85) _5G60[i] = 2.89+0.001*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G60[44],_5G60[84],_5G60[125] ); +_5G70(maxInd); + for (int i=0; i5) _5G70[i] = 2.77 + 0.001*(i-5); + else if (i<85 && i>=45) _5G70[i] = 2.81+0.00125*(i-45); + else if (i<140 && i >=85) _5G70[i] = 2.86+0.00125*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G70[44],_5G70[84],_5G70[125] ); +_5G80(maxInd); + for (int i=0; i5) _5G80[i] = 2.76 + 0.001*(i-5); + else if (i<85 && i>=45) _5G80[i] = 2.8+0.00125*(i-45); + else if (i<140 && i >=85) _5G80[i] = 2.85+0.00125*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G80[44],_5G80[84],_5G80[125] ); + +//25G +_25G30(maxInd); + for (int i=0; i5) _25G30[i] = 2.68 + 0.0015*(i-5); + else if (i<85 && i>=45) _25G30[i] = 2.74+0.0018*(i-45); + else if (i<140 && i >=85) _25G30[i] = 2.81+0.002*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G30[44],_25G30[84],_25G30[125] ); +_25G40(maxInd); + for (int i=0; i5) _25G40[i] = 2.68 + 0.00075*(i-5); + else if (i<85 && i>=45) _25G40[i] = 2.71+0.0015*(i-45); + else if (i<140 && i >=85) _25G40[i] = 2.77+0.00125*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G40[44],_25G40[84],_25G40[125] ); +_25G50(maxInd); + for (int i=0; i5) _25G50[i] = 2.65 + 0.00075*(i-5); + else if (i<85 && i>=45) _25G50[i] = 2.68+0.00125*(i-45); + else if (i<140 && i >=85) _25G50[i] = 2.73+0.00125*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G50[44],_25G50[84],_25G50[125] ); +_25G60(maxInd); + for (int i=0; i5) _25G60[i] = 2.64 + 0.0005*(i-5); + else if (i<85 && i>=45) _25G60[i] = 2.66+0.001*(i-45); + else if (i<140 && i >=85) _25G60[i] = 2.70+0.001*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G60[44],_25G60[84],_25G60[125] ); +_25G70(maxInd); + for (int i=0; i5) _25G70[i] = 2.64 + 0.00*(i-5); + else if (i<85 && i>=45) _25G70[i] = 2.64+0.00075*(i-45); + else if (i<140 && i >=85) _25G70[i] = 2.67+0.001*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G70[44],_25G70[84],_25G70[125] ); +_25G80(maxInd); + for (int i=0; i5) _25G80[i] = 2.63 + 0.00*(i-5); + else if (i<85 && i>=45) _25G80[i] = 2.63+0.0005*(i-45); + else if (i<140 && i >=85) _25G80[i] = 2.65+0.0005*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G80[44],_25G80[84],_25G80[125] ); + + +//1G +_1G30(maxInd); + for (int i=0; i5) _1G30[i] = 2.58 + 0.00025*(i-5); + else if (i<85 && i>=45) _1G30[i] = 2.59+0.001*(i-45); + else if (i<140 && i >=85) _1G30[i] = 2.63+0.00125*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G30[44],_1G30[84],_1G30[125] ); +_1G40(maxInd); + for (int i=0; i5) _1G40[i] = 2.56 - 0.00025*(i-5); + else if (i<85 && i>=45) _1G40[i] = 2.55+0.0005*(i-45); + else if (i<140 && i >=85) _1G40[i] = 2.57+0.0005*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G40[44],_1G40[84],_1G40[125] ); +_1G50(maxInd); + for (int i=0; i5) _1G50[i] = 2.55 - 0.00025*(i-5); + else if (i<85 && i>=45) _1G50[i] = 2.54+0.00025*(i-45); + else if (i<140 && i >=85) _1G50[i] = 2.55+0.0005*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G50[44],_1G50[84],_1G50[125] ); +_1G60(maxInd); + for (int i=0; i5) _1G60[i] = 2.54 - 0.0005*(i-5); + else if (i<85 && i>=45) _1G60[i] = 2.52+0.00025*(i-45); + else if (i<140 && i >=85) _1G60[i] = 2.53+0.00025*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G60[44],_1G60[84],_1G60[125] ); +_1G70(maxInd); + for (int i=0; i5) _1G70[i] = 2.53 - 0.0005*(i-5); + else if (i<85 && i>=45) _1G70[i] = 2.51+0.0*(i-45); + else if (i<140 && i >=85) _1G70[i] = 2.51+0.00025*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G70[44],_1G70[84],_1G70[125] ); +_1G80(maxInd); + for (int i=0; i5) _1G80[i] = 2.52 - 0.0005*(i-5); + else if (i<85 && i>=45) _1G80[i] = 2.50+0.00*(i-45); + else if (i<140 && i >=85) _1G80[i] = 2.50+0.00*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G80[44],_1G80[84],_1G80[125] ); + + +//10GY +_10GY30(maxInd); + for (int i=0; i5) _10GY30[i] = 2.52 - 0.001*(i-5); + else if (i<85 && i>=45) _10GY30[i] = 2.48-0.002*(i-45); + else if (i<140 && i >=85) _10GY30[i] = 2.40+0.0025*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY30[44],_10GY30[84],_10GY30[125] ); +_10GY40(maxInd); + for (int i=0; i5) _10GY40[i] = 2.48 - 0.0005*(i-5); + else if (i<85 && i>=45) _10GY40[i] = 2.46-0.0005*(i-45); + else if (i<140 && i >=85) _10GY40[i] = 2.44-0.0015*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY40[44],_10GY40[84],_10GY40[125] ); +_10GY50(maxInd); + for (int i=0; i5) _10GY50[i] = 2.48 - 0.00075*(i-5); + else if (i<85 && i>=45) _10GY50[i] = 2.45-0.00075*(i-45); + else if (i<140 && i >=85) _10GY50[i] = 2.42-0.00175*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY50[44],_10GY50[84],_10GY50[125] ); +_10GY60(maxInd); + for (int i=0; i5) _10GY60[i] = 2.47 - 0.00125*(i-5); + else if (i<85 && i>=45) _10GY60[i] = 2.42-0.00025*(i-45); + else if (i<140 && i >=85) _10GY60[i] = 2.41-0.0005*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY60[44],_10GY60[84],_10GY60[125] ); +_10GY70(maxInd); + for (int i=0; i5) _10GY70[i] = 2.46 - 0.001*(i-5); + else if (i<85 && i>=45) _10GY70[i] = 2.42+0.0*(i-45); + else if (i<140 && i >=85) _10GY70[i] = 2.42-0.001*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY70[44],_10GY70[84],_10GY70[125] ); +_10GY80(maxInd); + for (int i=0; i5) _10GY80[i] = 2.45 - 0.00075*(i-5); + else if (i<85 && i>=45) _10GY80[i] = 2.42 - 0.0005*(i-45); + else if (i<140 && i >=85) _10GY80[i] = 2.40-0.0005*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY80[44],_10GY80[84],_10GY80[125] ); + + +//75GY +_75GY30(maxInd2); + for (int i=0; i5) _75GY30[i] = 2.36 - 0.0025*(i-5); + else if (i<90 && i>=45) _75GY30[i] = 2.26-0.00175*(i-45); + } + //printf("75GY %1.2f %1.2f\n",_75GY30[44],_75GY30[84] ); +_75GY40(maxInd2); + for (int i=0; i5) _75GY40[i] = 2.34 - 0.00175*(i-5); + else if (i<90 && i>=45) _75GY40[i] = 2.27-0.00225*(i-45); + } + //printf("75GY %1.2f %1.2f \n",_75GY40[44],_75GY40[84] ); +_75GY50(maxInd); + for (int i=0; i5) _75GY50[i] = 2.32 - 0.0015*(i-5); + else if (i<85 && i>=45) _75GY50[i] = 2.26-0.00175*(i-45); + else if (i<140 && i >=85) _75GY50[i] = 2.19-0.00325*(i-85); + } + //printf("75GY %1.2f %1.2f %1.2f %1.2f\n",_75GY50[44],_75GY50[84],_75GY50[125],_75GY50[139] ); +_75GY60(maxInd); + for (int i=0; i5) _75GY60[i] = 2.30 - 0.00125*(i-5); + else if (i<85 && i>=45) _75GY60[i] = 2.25-0.001*(i-45); + else if (i<140 && i >=85) _75GY60[i] = 2.21-0.0027*(i-85); + } + //printf("75GY %1.2f %1.2f %1.2f\n",_75GY60[44],_75GY60[84],_75GY60[125] ); +_75GY70(maxInd); + for (int i=0; i5) _75GY70[i] = 2.29 - 0.00125*(i-5); + else if (i<85 && i>=45) _75GY70[i] = 2.24-0.0015*(i-45); + else if (i<140 && i >=85) _75GY70[i] = 2.18-0.00175*(i-85); + } + //printf("75GY %1.2f %1.2f %1.2f\n",_75GY70[44],_75GY70[84],_75GY70[125] ); +_75GY80(maxInd); + for (int i=0; i5) _75GY80[i] = 2.27 - 0.001*(i-5); + else if (i<85 && i>=45) _75GY80[i] = 2.23 - 0.001*(i-45); + else if (i<140 && i >=85) _75GY80[i] = 2.19-0.00175*(i-85); + } + //printf("75GY %1.2f %1.2f %1.2f\n",_75GY80[44],_75GY80[84],_75GY80[125] ); + + +//55GY +_5GY30(maxInd2); + for (int i=0; i5) _5GY30[i] = 2.16 - 0.002*(i-5); + else if (i<90 && i>=45) _5GY30[i] = 2.07-0.0025*(i-45); + } + //printf("5GY %1.2f %1.2f\n",_5GY30[44],_5GY30[84] ); + +//5GY4: 2.14,2.04, 1.96, 1.91 //95 + +_5GY40(maxInd2); + for (int i=0; i5) _5GY40[i] = 2.14 - 0.0025*(i-5); + else if (i<90 && i>=45) _5GY40[i] = 2.04-0.003*(i-45); + } + //printf("5GY %1.2f %1.2f \n",_5GY40[44],_5GY40[84] ); +_5GY50(maxInd); + for (int i=0; i5) _5GY50[i] = 2.13 - 0.00175*(i-5); + else if (i<85 && i>=45) _5GY50[i] = 2.06-0.002*(i-45); + else if (i<140 && i >=85) _5GY50[i] = 1.98-0.00225*(i-85); + } + //printf("5GY %1.2f %1.2f %1.2f\n",_5GY50[44],_5GY50[84],_5GY50[125] ); +_5GY60(maxInd); + for (int i=0; i5) _5GY60[i] = 2.11 - 0.0015*(i-5); + else if (i<85 && i>=45) _5GY60[i] = 2.05-0.002*(i-45); + else if (i<140 && i >=85) _5GY60[i] = 1.97-0.00275*(i-85); + } + //printf("5GY %1.2f %1.2f %1.2f\n",_5GY60[44],_5GY60[84],_5GY60[125] ); +_5GY70(maxInd); + for (int i=0; i5) _5GY70[i] = 2.09 - 0.001*(i-5); + else if (i<85 && i>=45) _5GY70[i] = 2.05-0.00175*(i-45); + else if (i<140 && i >=85) _5GY70[i] = 1.98-0.002*(i-85); + } + //printf("5GY %1.2f %1.2f %1.2f\n",_5GY70[44],_5GY70[84],_5GY70[125] ); +_5GY80(maxInd); + for (int i=0; i5) _5GY80[i] = 2.07 - 0.001*(i-5); + else if (i<85 && i>=45) _5GY80[i] = 2.03 - 0.00075*(i-45); + else if (i<140 && i >=85) _5GY80[i] = 2.0-0.002*(i-85); + } + //printf("5GY %1.2f %1.2f %1.2f\n",_5GY80[44],_5GY80[84],_5GY80[125] ); + +#ifdef _DEBUG + t2e.set(); + if (settings->verbose) + printf("Lutf Munsell %d usec\n", t2e.etime(t1e)); +#endif +} + + + +void ImProcFunctions::MunsellLch (float lum, float hue, float chrom, float memChprov, float &correction, int zone) { + int x=(int) memChprov; + int y=(int) chrom; + + //found the good LUT and calculate correction + + + //Blue purple correction PB + sky + if(zone==1) {//begin PB correction + if((lum > 5.0 && lum <15.0) ) { + if( (hue >= (_15PB10[x] - 0.035)) && (hue < (_15PB10[x] + 0.052) && x<=45)) {if(y>49) y=49;correction = _15PB10[y] - _15PB10[x] ;} + else if (( hue>=( _3PB10[x] -0.052)) && (hue < (_45PB10[x] + _3PB10[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB10[y] - _3PB10[x] ;} + else if (( hue>=(_45PB10[x] + _3PB10[x])/2.0) && (hue < (_45PB10[x] +0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB10[y] - _45PB10[x] ;} + else if (( hue>=(_6PB10[x] -0.052) && (hue < (_6PB10[x] + _75PB10[x])/2.0))) {correction = _6PB10[y] - _6PB10[x] ; } + else if (( hue>=(_6PB10[x] + _75PB10[x])/2.0) && (hue < (_9PB10[x] + _75PB10[x])/2.0)) {correction = _75PB10[y] - _75PB10[x] ;} + else if (( hue>=(_9PB10[x] + _75PB10[x])/2.0) && (hue < (_9PB10[x] + _10PB10[x])/2.0)) {correction = _9PB10[y] - _9PB10[x] ; } + else if (( hue>=(_10PB10[x] + _9PB10[x])/2.0) && (hue < (_1P10[x] + _10PB10[x])/2.0)) {correction = _10PB10[y] - _10PB10[x] ;} + else if (( hue>=(_10PB10[x] + _1P10[x])/2.0) && (hue < (_1P10[x] + _4P10[x])/2.0)) {correction = _1P10[y] - _1P10[x];} + else if (( hue>=(_1P10[x] + _4P10[x])/2.0) && (hue < (0.035 + _4P10[x])/2.0)) {correction = _4P10[y] - _4P10[x] ;} + } + else if ((lum >= 15.0 && lum <25.0)) { + if( (hue >= (_15PB20[x] - 0.035)) && (hue < (_15PB20[x] + _3PB20[x])/2.0) && x<=85) {if(y>89) y=89;correction = _15PB20[y] - _15PB20[x] ; } + else if (( hue>=(_15PB20[x] + _3PB20[x])/2.0) && (hue < (_45PB20[x] + _3PB20[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB20[y] - _3PB20[x] ; } + else if (( hue>=(_45PB20[x] + _3PB20[x])/2.0) && (hue < ( _45PB20[x] + 0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB20[y] - _45PB20[x] ;} + else if (( hue>=(_45PB20[x] + 0.052)) && (hue < (_6PB20[x] + _75PB20[x])/2.0)) {correction = _6PB20[y] - _6PB20[x];} + else if (( hue>=(_6PB20[x] + _75PB20[x])/2.0) && (hue < (_9PB20[x] + _75PB20[x])/2.0)) {correction = _75PB20[y] - _75PB20[x] ;} + else if (( hue>=(_9PB20[x] + _75PB20[x])/2.0) && (hue < (_9PB20[x] + _10PB20[x])/2.0)) {correction = _9PB20[y] - _9PB20[x] ; } + else if (( hue>=(_10PB20[x] + _9PB20[x])/2.0) && (hue < (_1P20[x] + _10PB20[x])/2.0)) {correction = _10PB20[y] - _10PB20[x] ;} + else if (( hue>=(_10PB20[x] + _1P20[x])/2.0) && (hue < (_1P20[x] + _4P20[x])/2.0)) {correction = _1P20[y] - _1P20[x] ; } + else if (( hue>=(_1P20[x] + _4P20[x])/2.0) && (hue < (0.035 + _4P20[x])/2.0)) {correction = _4P20[y] - _4P20[x] ; } + } + else if ((lum >= 25.0 && lum <35.0)) { + if( (hue >= (_15PB30[x] - 0.035)) && (hue < (_15PB30[x] + _3PB30[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB30[y] - _15PB30[x] ;} + else if (( hue>=(_15PB30[x] + _3PB30[x])/2.0) && (hue < (_45PB30[x] + _3PB30[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB30[y] - _3PB30[x] ;} + else if (( hue>=(_45PB30[x] + _3PB30[x])/2.0) && (hue < (_45PB30[x]+0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB30[y] - _45PB30[x] ; } + else if (( hue>=( _45PB30[x]+ 0.052)) && (hue < (_6PB30[x] + _75PB30[x])/2.0)) {correction = _6PB30[y] - _6PB30[x] ; } + else if (( hue>=(_6PB30[x] + _75PB30[x])/2.0) && (hue < (_9PB30[x] + _75PB30[x])/2.0)) {correction = _75PB30[y] - _75PB30[x] ;} + else if (( hue>=(_9PB30[x] + _75PB30[x])/2.0) && (hue < (_9PB30[x] + _10PB30[x])/2.0)) {correction = _9PB30[y] - _9PB30[x] ; } + else if (( hue>=(_10PB30[x] + _9PB30[x])/2.0) && (hue < (_1P30[x] + _10PB30[x])/2.0)) {correction = _10PB30[y] - _10PB30[x] ;} + else if (( hue>=(_10PB30[x] + _1P30[x])/2.0) && (hue < (_1P30[x] + _4P30[x])/2.0)) {correction = _1P30[y] - _1P30[x] ; } + else if (( hue>=(_1P30[x] + _4P30[x])/2.0) && (hue < (0.035 + _4P30[x])/2.0)) {correction = _4P30[y] - _4P30[x] ;} + } + else if ((lum >= 35.0 && lum <45.0) ) { + if( (hue <= (_05PB40[x] + _15PB40[x])/2.0) && (hue > (_05PB40[x] + _10B40[x])/2.0) && x<75 ) {if(y>75) y=75; correction = _05PB40[y] - _05PB40[x] ;} + else if( (hue <= (_05PB40[x] + _10B40[x])/2.0) && (hue >(_10B40[x] + _9B40[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _10B40[y] - _10B40[x] ;} + else if( (hue <= (_10B40[x] + _9B40[x])/2.0) && (hue >(_9B40[x] + _7B40[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _9B40[y] - _9B40[x] ;} + else if( (hue <= (_9B40[x] + _7B40[x])/2.0) && (hue >(_5B40[x] + _7B40[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _7B40[y] - _7B40[x] ;} + else if (( hue<=(_5B40[x] + _7B40[x])/2.0) && (hue > (_5B40[x]-0.035)) && x < 70) {if(y>70) y=70; correction = _5B40[y] - _5B40[x] ; } // + + else if( (hue >= (_15PB40[x] - 0.035)) && (hue < (_15PB40[x] + _3PB40[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB40[y] - _15PB40[x] ; } + else if (( hue>=(_15PB40[x] + _3PB40[x])/2.0) && (hue < (_45PB40[x] + _3PB40[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB40[y] - _3PB40[x] ;} + else if (( hue>=(_45PB40[x] + _3PB40[x])/2.0) && (hue < (_45PB40[x]+0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB40[y] - _45PB40[x] ;} + else if (( hue>=(_45PB40[x]+0.052)) && (hue < (_6PB40[x] + _75PB40[x])/2.0)) {correction = _6PB40[y] - _6PB40[x] ; } + else if (( hue>=(_6PB40[x] + _75PB40[x])/2.0) && (hue < (_9PB40[x] + _75PB40[x])/2.0)) {correction = _75PB40[y] - _75PB40[x] ; } + else if (( hue>=(_9PB40[x] + _75PB40[x])/2.0) && (hue < (_9PB40[x] + _10PB40[x])/2.0)) {correction = _9PB40[y] - _9PB40[x] ; } + else if (( hue>=(_10PB40[x] + _9PB40[x])/2.0) && (hue < (_1P40[x] + _10PB40[x])/2.0)) {correction = _10PB40[y] - _10PB40[x] ;} + else if (( hue>=(_10PB40[x] + _1P40[x])/2.0) && (hue < (_1P40[x] + _4P40[x])/2.0)) {correction = _1P40[y] - _1P40[x] ;} + else if (( hue>=(_1P40[x] + _4P40[x])/2.0) && (hue < (0.035 + _4P40[x])/2.0)) {correction = _4P40[y] - _4P40[x] ;} + } + else if ((lum >= 45.0 && lum <55.0) ) { + if( (hue <= (_05PB50[x] + _15PB50[x])/2.0) && (hue > (_05PB50[x] + _10B50[x])/2.0) && x<79 ) {if(y>79) y=79; correction = _05PB50[y] - _05PB50[x] ;} + else if( (hue <= (_05PB50[x] + _10B50[x])/2.0) && (hue >(_10B50[x] + _9B50[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _10B50[y] - _10B50[x] ;} + else if( (hue <= (_10B50[x] + _9B50[x])/2.0) && (hue >(_9B50[x] + _7B50[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _9B50[y] - _9B50[x] ;} + else if( (hue <= (_9B50[x] + _7B50[x])/2.0) && (hue >(_5B50[x] + _7B50[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _7B50[y] - _7B50[x] ;} + else if (( hue<=(_5B50[x] + _7B50[x])/2.0) && (hue > (_5B50[x]-0.035)) && x < 79) {if(y>79) y=79; correction = _5B50[y] - _5B50[x] ; } // + + else if( (hue >= (_15PB50[x] - 0.035)) && (hue < (_15PB50[x] + _3PB50[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB50[y] - _15PB50[x] ; } + else if (( hue>=(_15PB50[x] + _3PB50[x])/2.0) && (hue < (_45PB50[x] + _3PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB50[y] - _3PB50[x] ;} + else if (( hue>=(_45PB50[x] + _3PB50[x])/2.0) && (hue < (_6PB50[x] + _45PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _45PB50[y] - _45PB50[x] ; } + else if (( hue>=(_6PB50[x] + _45PB50[x])/2.0) && (hue < (_6PB50[x] + _75PB50[x])/2.0) && x <=85) {if(y>89) y=89;correction = _6PB50[y] - _6PB50[x] ;} + else if (( hue>=(_6PB50[x] + _75PB50[x])/2.0) && (hue < (_9PB50[x] + _75PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _75PB50[y] - _75PB50[x] ;} + else if (( hue>=(_9PB50[x] + _75PB50[x])/2.0) && (hue < (_9PB50[x] + _10PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _9PB50[y] - _9PB50[x] ;} + else if (( hue>=(_10PB50[x] + _9PB50[x])/2.0) && (hue < (_1P50[x] + _10PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _10PB50[y] - _10PB50[x] ;} + else if (( hue>=(_10PB50[x] + _1P50[x])/2.0) && (hue < (_1P50[x] + _4P50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _1P50[y] - _1P50[x] ; } + else if (( hue>=(_1P50[x] + _4P50[x])/2.0) && (hue < (0.035 + _4P50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _4P50[y] - _4P50[x] ;} + } + else if ((lum >= 55.0 && lum <65.0) ) { + if( (hue <= (_05PB60[x] + _15PB60[x])/2.0) && (hue > (_05PB60[x] + _10B60[x])/2.0) && x<79 ) {if(y>79) y=79; correction = _05PB60[y] - _05PB60[x] ;} + else if( (hue <= (_05PB60[x] + _10B60[x])/2.0) && (hue >(_10B60[x] + _9B60[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _10B60[y] - _10B60[x] ;} + else if( (hue <= (_10B60[x] + _9B60[x])/2.0) && (hue >(_9B60[x] + _7B60[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _9B60[y] - _9B60[x] ;} + else if( (hue <= (_9B60[x] + _7B60[x])/2.0) && (hue >(_5B60[x] + _7B60[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _7B60[y] - _7B60[x] ;} + else if (( hue<=(_5B60[x] + _7B60[x])/2.0) && (hue > (_5B60[x]-0.035)) && x < 79) {if(y>79) y=79; correction = _5B60[y] - _5B60[x] ; } // + + else if( (hue >= (_15PB60[x] - 0.035)) && (hue < (_15PB60[x] + _3PB60[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB60[y] - _15PB60[x] ; } + else if (( hue>=(_15PB60[x] + _3PB60[x])/2.0) && (hue < (_45PB60[x] + _3PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB60[y] - _3PB60[x] ;} + else if (( hue>=(_45PB60[x] + _3PB60[x])/2.0) && (hue < (_6PB60[x] + _45PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _45PB60[y] - _45PB60[x] ;} + else if (( hue>=(_6PB60[x] + _45PB60[x])/2.0) && (hue < (_6PB60[x] + _75PB60[x])/2.0) && x <=85) {if(y>89) y=89;correction = _6PB60[y] - _6PB60[x] ;} + else if (( hue>=(_6PB60[x] + _75PB60[x])/2.0) && (hue < (_9PB60[x] + _75PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _75PB60[y] - _75PB60[x] ; } + else if (( hue>=(_9PB60[x] + _75PB60[x])/2.0) && (hue < (_9PB60[x] + _10PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _9PB60[y] - _9PB60[x] ; } + else if (( hue>=(_10PB60[x] + _9PB60[x])/2.0) && (hue < (_1P60[x] + _10PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _10PB60[y] - _10PB60[x] ; } + else if (( hue>=(_10PB60[x] + _1P60[x])/2.0) && (hue < (_1P60[x] + _4P60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _1P60[y] - _1P60[x] ; } + else if (( hue>=(_1P60[x] + _4P60[x])/2.0) && (hue < (0.035 + _4P60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _4P60[y] - _4P60[x] ; } + } + else if ((lum >= 65.0 && lum < 75.0) ) { + if( (hue <= (_05PB70[x] + _15PB70[x])/2.0) && (hue > (_05PB70[x] + _10B70[x])/2.0) && x<50 ) {if(y>49) y=49; correction = _05PB70[y] - _05PB70[x] ;} + else if( (hue <= (_05PB70[x] + _10B70[x])/2.0) && (hue >(_10B70[x] + _9B70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _10B70[y] - _10B70[x] ;} + else if( (hue <= (_10B70[x] + _9B70[x])/2.0) && (hue >(_9B70[x] + _7B70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _9B70[y] - _9B70[x] ;} + else if( (hue <= (_9B70[x] + _7B70[x])/2.0) && (hue >(_5B70[x] + _7B70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _7B70[y] - _7B70[x] ;} + else if (( hue<=(_5B70[x] + _7B70[x])/2.0) && (hue > (_5B70[x]-0.035)) && x < 50) {if(y>49) y=49; correction = _5B70[y] - _5B70[x] ; } // + + else if( (hue >= (_15PB70[x] - 0.035)) && (hue < (_15PB70[x] + _3PB70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _15PB70[y] - _15PB70[x] ; } + else if (( hue>=(_45PB70[x] + _3PB70[x])/2.0) && (hue < (_6PB70[x] + _45PB70[x])/2.0) && x < 50) {if(y>49) y=49;correction = _45PB70[y] - _45PB70[x] ;} + else if (( hue>=(_6PB70[x] + _45PB70[x])/2.0) && (hue < (_6PB70[x] + _75PB70[x])/2.0) && x <50) {if(y>49) y=49;correction = _6PB70[y] - _6PB70[x] ;} + else if (( hue>=(_6PB70[x] + _75PB70[x])/2.0) && (hue < (_9PB70[x] + _75PB70[x])/2.0) && x <50) {if(y>49) y=49;correction = _75PB70[y] - _75PB70[x] ; } + else if (( hue>=(_9PB70[x] + _75PB70[x])/2.0) && (hue < (_9PB70[x] + 0.035)) && x <50) {if(y>49) y=49;correction = _9PB70[y] - _9PB70[x] ; } + } + else if ((lum >= 75.0 && lum < 85.0) ) { + if( (hue <= (_05PB80[x] + _15PB80[x])/2.0) && (hue > (_05PB80[x] + _10B80[x])/2.0) && x<40 ) {if(y>39) y=39; correction = _05PB80[y] - _05PB80[x] ;} + else if( (hue <= (_05PB80[x] + _10B80[x])/2.0) && (hue >(_10B80[x] + _9B80[x])/2.0) && x<40 ) {if(y>39) y=39;correction = _10B80[y] - _10B80[x] ;} + else if( (hue <= (_10B80[x] + _9B80[x])/2.0) && (hue >(_9B80[x] + _7B80[x])/2.0) && x<40 ) {if(y>39) y=39;correction = _9B80[y] - _9B80[x] ;} + else if( (hue <= (_9B80[x] + _7B80[x])/2.0) && (hue >(_5B80[x] + _7B80[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _7B80[y] - _7B80[x] ;} + else if (( hue<=(_5B80[x] + _7B80[x])/2.0) && (hue > (_5B80[x]-0.035)) && x < 50) {if(y>49) y=49; correction = _5B80[y] - _5B80[x] ; } // + + else if( (hue >= (_15PB80[x] - 0.035)) && (hue < (_15PB80[x] + _3PB80[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _15PB80[y] - _15PB80[x] ; } + else if (( hue>=(_45PB80[x] + _3PB80[x])/2.0) && (hue < (_6PB80[x] + _45PB80[x])/2.0) && x < 50) {if(y>49) y=49;correction = _45PB80[y] - _45PB80[x] ;} + else if (( hue>=(_6PB80[x] + _45PB80[x])/2.0) && (hue < (_6PB80[x] + _75PB80[x])/2.0) && x <50) {if(y>49) y=49;correction = _6PB80[y] - _6PB80[x] ;} + else if (( hue>=(_6PB80[x] + _75PB80[x])/2.0) && (hue < (_9PB80[x] + _75PB80[x])/2.0) && x <50) {if(y>49) y=49;correction = _75PB80[y] - _75PB80[x] ; } + else if (( hue>=(_9PB80[x] + _75PB80[x])/2.0) && (hue < (_9PB80[x] + 0.035)) && x <50) {if(y>49) y=49;correction = _9PB80[y] - _9PB80[x] ; } + } + } // end PB correction + if(zone==2) {//red yellow correction + if((lum > 15.0 && lum < 25.0) ) { + if( (hue <= (_10YR20[x] + 0.035)) && (hue > (_10YR20[x] + _85YR20[x])/2.0) && x<=45) {if(y>49) y=49;correction = _10YR20[y] - _10YR20[x] ;} + else if (( hue<=(_85YR20[x] + _10YR20[x])/2.0) && (hue > (_85YR20[x] + 0.035) && x <= 45)) {if(y>49) y=49;correction = _85YR20[y] - _85YR20[x] ;} + } + else if ((lum >= 25.0 && lum <35.0)) { + if( (hue <= (_10YR30[x] + 0.035)) && (hue > (_10YR30[x] + _85YR30[x])/2.0) && x < 85) {if(y>89) y=89;correction = _10YR30[y] - _10YR30[x] ;} + else if( (hue <= (_10YR30[x] + _85YR30[x])/2.0) && (hue >(_85YR30[x] + _7YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _85YR30[y] - _85YR30[x] ;} + else if (( hue<=(_85YR30[x] + _7YR30[x])/2.0) && (hue > (_7YR30[x] + _55YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _7YR30[y] - _7YR30[x] ;} + else if (( hue<=(_7YR30[x] + _55YR30[x])/2.0) && (hue > (_55YR30[x] + _4YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _55YR30[y] - _55YR30[x] ; } + else if (( hue<=(_55YR30[x] + _4YR30[x])/2.0) && (hue > (_4YR30[x] + _25YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _4YR30[y] - _4YR30[x] ; } + else if (( hue<=(_4YR30[x] + _25YR30[x])/2.0) && (hue > (_25YR30[x] + _10R30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR30[y] - _25YR30[x] ;} + else if (( hue<=(_25YR30[x] + _10R30[x])/2.0) && (hue > (_10R30[x] + _9R30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R30[y] - _10R30[x] ; } + else if (( hue<=(_10R30[x] + _9R30[x])/2.0) && (hue > (_9R30[x] + _7R30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R30[y] - _9R30[x] ;} + else if (( hue<=(_9R30[x] + _7R30[x])/2.0) && (hue > (_7R30[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R30[y] - _7R30[x] ; } + } + else if ((lum >= 35.0 && lum <45.0)) { + if( (hue <= (_10YR40[x] + 0.035)) && (hue > (_10YR40[x] + _85YR40[x])/2.0)&& x<85) {if(y>89) y=89;correction = _10YR40[y] - _10YR40[x] ;} + else if( (hue <= (_10YR40[x] + _85YR40[x])/2.0) && (hue >(_85YR40[x] + _7YR40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _85YR40[y] - _85YR40[x] ;} + else if (( hue<=(_85YR40[x] + _7YR40[x])/2.0) && (hue > (_7YR40[x] + _55YR40[x])/2.0) && x < 85) {if(y>89) y=89;correction = _7YR40[y] - _7YR40[x] ;} + else if (( hue<=(_7YR40[x] + _55YR40[x])/2.0) && (hue > (_55YR40[x] + _4YR40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _55YR40[y] - _55YR40[x] ; } + else if (( hue<=(_55YR40[x] + _4YR40[x])/2.0) && (hue > (_4YR40[x] + _25YR40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _4YR40[y] - _4YR40[x] ; } + else if (( hue<=(_4YR40[x] + _25YR40[x])/2.0) && (hue > (_25YR40[x] + _10R40[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR40[y] - _25YR40[x] ;} + else if (( hue<=(_25YR40[x] + _10R40[x])/2.0) && (hue > (_10R40[x] + _9R40[x])/2.0) && x < 85) {if(y>89) y=89;correction = _10R40[y] - _10R40[x] ; } + else if (( hue<=(_10R40[x] + _9R40[x])/2.0) && (hue > (_9R40[x] + _7R40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _9R40[y] - _9R40[x] ;} + else if (( hue<=(_9R40[x] + _7R40[x])/2.0) && (hue > (_7R40[x] -0.035))&& x < 85 ) {if(y>89) y=89;correction = _7R40[y] - _7R40[x] ; } + } + else if ((lum >= 45.0 && lum <55.0)) { + if( (hue <= (_10YR50[x] + 0.035)) && (hue > (_10YR50[x] + _85YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10YR50[y] - _10YR50[x] ;} + else if( (hue <= (_10YR50[x] + _85YR50[x])/2.0) && (hue >(_85YR50[x] + _7YR50[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _85YR50[y] - _85YR50[x] ;} + else if (( hue<=(_85YR50[x] + _7YR50[x])/2.0) && (hue > (_7YR50[x] + _55YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _7YR50[y] - _7YR50[x] ;} + else if (( hue<=(_7YR50[x] + _55YR50[x])/2.0) && (hue > (_55YR50[x] + _4YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _55YR50[y] - _55YR50[x] ; } + else if (( hue<=(_55YR50[x] + _4YR50[x])/2.0) && (hue > (_4YR50[x] + _25YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _4YR50[y] - _4YR50[x] ; } + else if (( hue<=(_4YR50[x] + _25YR50[x])/2.0) && (hue > (_25YR50[x] + _10R50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR50[y] - _25YR50[x] ;} + else if (( hue<=(_25YR50[x] + _10R50[x])/2.0) && (hue > (_10R50[x] + _9R50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R50[y] - _10R50[x] ; } + else if (( hue<=(_10R50[x] + _9R50[x])/2.0) && (hue > (_9R50[x] + _7R50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R50[y] - _9R50[x] ;} + else if (( hue<=(_9R50[x] + _7R50[x])/2.0) && (hue > (_7R50[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R50[y] - _7R50[x] ; } + } + else if ((lum >= 55.0 && lum <65.0)) { + if( (hue <= (_10YR60[x] + 0.035)) && (hue > (_10YR60[x] + _85YR60[x])/2.0)) {;correction = _10YR60[y] - _10YR60[x] ;} + else if( (hue <= (_10YR60[x] + _85YR60[x])/2.0) && (hue >(_85YR60[x] + _7YR60[x])/2.0) ) {;correction = _85YR60[y] - _85YR60[x] ;} + else if (( hue<=(_85YR60[x] + _7YR60[x])/2.0) && (hue > (_7YR60[x] + _55YR60[x])/2.0)) {correction = _7YR60[y] - _7YR60[x] ;} + else if (( hue<=(_7YR60[x] + _55YR60[x])/2.0) && (hue > (_55YR60[x] + _4YR60[x])/2.0)) {correction = _55YR60[y] - _55YR60[x] ; } + else if (( hue<=(_55YR60[x] + _4YR60[x])/2.0) && (hue > (_4YR60[x] + _25YR60[x])/2.0)) {correction = _4YR60[y] - _4YR60[x] ; } + else if (( hue<=(_4YR60[x] + _25YR60[x])/2.0) && (hue > (_25YR60[x] + _10R60[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR60[y] - _25YR60[x] ;} + else if (( hue<=(_25YR60[x] + _10R60[x])/2.0) && (hue > (_10R60[x] + _9R60[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R60[y] - _10R60[x] ; } + else if (( hue<=(_10R60[x] + _9R60[x])/2.0) && (hue > (_9R60[x] + _7R60[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R60[y] - _9R60[x] ;} + else if (( hue<=(_9R60[x] + _7R60[x])/2.0) && (hue > (_7R60[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R60[y] - _7R60[x] ; } + } + else if ((lum >= 65.0 && lum <75.0)) { + if( (hue <= (_10YR70[x] + 0.035)) && (hue > (_10YR70[x] + _85YR70[x])/2.0)) {correction = _10YR70[y] - _10YR70[x] ;} + else if( (hue <= (_10YR70[x] + _85YR70[x])/2.0) && (hue >(_85YR70[x] + _7YR70[x])/2.0)) {correction = _85YR70[y] - _85YR70[x] ;} + if (( hue<=(_85YR70[x] + _7YR70[x])/2.0) && (hue > (_7YR70[x] + _55YR70[x])/2.0)) {correction = _7YR70[y] - _7YR70[x] ;} + else if (( hue<=(_7YR70[x] + _55YR70[x])/2.0) && (hue > (_55YR70[x] + _4YR70[x])/2.0)) {correction = _55YR70[y] - _55YR70[x] ; } + else if (( hue<=(_55YR70[x] + _4YR70[x])/2.0) && (hue > (_4YR70[x] + _25YR70[x])/2.0)) {correction = _4YR70[y] - _4YR70[x] ; } + else if (( hue<=(_4YR70[x] + _25YR70[x])/2.0) && (hue > (_25YR70[x] + _10R70[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR70[y] - _25YR70[x] ;} + else if (( hue<=(_25YR70[x] + _10R70[x])/2.0) && (hue > (_10R70[x] + _9R70[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R70[y] - _10R70[x] ; } + else if (( hue<=(_10R70[x] + _9R70[x])/2.0) && (hue > (_9R70[x] + _7R70[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R70[y] - _9R70[x] ;} + else if (( hue<=(_9R70[x] + _7R70[x])/2.0) && (hue > (_7R70[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R70[y] - _7R70[x] ; } + } + else if ((lum >= 75.0 && lum <85.0)) { + if( (hue <= (_10YR80[x] + 0.035)) && (hue > (_10YR80[x] + _85YR80[x])/2.0)) {correction = _10YR80[y] - _10YR80[x] ;} + else if( (hue <= (_10YR80[x] + _85YR80[x])/2.0) && (hue >(_85YR80[x] + _7YR80[x])/2.0)) {correction = _85YR80[y] - _85YR80[x] ;} + else if (( hue<=(_85YR80[x] + _7YR80[x])/2.0) && (hue > (_7YR80[x] + _55YR80[x])/2.0) && x<85) {if(y>89) y=89;correction = _7YR80[y] - _7YR80[x] ;} + else if (( hue<=(_7YR80[x] + _55YR80[x])/2.0) && (hue > (_55YR80[x] + _4YR80[x])/2.0) && x <45) {correction = _55YR80[y] - _55YR80[x] ; } + else if (( hue<=(_55YR80[x] + _4YR80[x])/2.0) && (hue > (_4YR80[x] - 0.035) && x<45)) {if(y>49) y=49;correction = _4YR80[y] - _4YR80[x] ; } + } + else if ((lum >= 85.0 && lum <95.0)) { + if( (hue <= (_10YR90[x] + 0.035)) && (hue > (_10YR90[x] -0.035) && x<85)) {if(y>89) y=89;correction = _10YR90[y] - _10YR90[x] ;} + else if ( hue<=(_85YR90[x] + 0.035) && hue > (_85YR90[x] -0.035) && x<85) {if(y>89) y=89;correction = _85YR90[y] - _85YR90[x] ;} + else if (( hue<=(_55YR90[x] + 0.035) && (hue > (_55YR90[x] - 0.035) && x<45))) {if(y>49) y=49;correction = _55YR90[y] - _55YR90[x] ; } + }//end red yellow + } + if(zone==3) {//Green yellow correction + if ((lum >= 25.0 && lum <35.0)) { + if( (hue <= (_7G30[x] + 0.035)) && (hue > (_7G30[x] + _5G30[x])/2.0) ) {correction = _7G30[y] - _7G30[x] ;} + else if( (hue <= (_7G30[x] + _5G30[x])/2.0) && (hue >(_5G30[x] + _25G30[x])/2.0)) {correction = _5G30[y] - _5G30[x] ;} + else if (( hue<=(_25G30[x] + _5G30[x])/2.0) && (hue > (_25G30[x] + _1G30[x])/2.0)) {correction = _25G30[y] - _25G30[x] ;} + else if (( hue<=(_1G30[x] + _25G30[x])/2.0) && (hue > (_1G30[x] + _10GY30[x])/2.0)) {correction = _1G30[y] - _1G30[x] ; } + else if (( hue<=(_1G30[x] + _10GY30[x])/2.0) && (hue > (_10GY30[x] + _75GY30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10GY30[y] - _10GY30[x] ; } + else if (( hue<=(_10GY30[x] + _75GY30[x])/2.0) && (hue > (_75GY30[x] + _5GY30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _75GY30[y] - _75GY30[x] ;} + else if (( hue<=(_5GY30[x] + _75GY30[x])/2.0) && (hue > (_5GY30[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _5GY30[y] - _5GY30[x] ; } + } + else if ((lum >= 35.0 && lum <45.0)) { + if( (hue <= (_7G40[x] + 0.035)) && (hue > (_7G40[x] + _5G40[x])/2.0) ) {correction = _7G40[y] - _7G40[x] ;} + else if( (hue <= (_7G40[x] + _5G40[x])/2.0) && (hue >(_5G40[x] + _25G40[x])/2.0)) {correction = _5G40[y] - _5G40[x] ;} + else if (( hue<=(_25G40[x] + _5G40[x])/2.0) && (hue > (_25G40[x] + _1G40[x])/2.0)) {correction = _25G40[y] - _25G40[x] ;} + else if (( hue<=(_1G40[x] + _25G40[x])/2.0) && (hue > (_1G40[x] + _10GY40[x])/2.0)) {correction = _1G40[y] - _1G40[x] ; } + else if (( hue<=(_1G40[x] + _10GY40[x])/2.0) && (hue > (_10GY40[x] + _75GY40[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10GY40[y] - _10GY40[x] ; } + else if (( hue<=(_10GY40[x] + _75GY40[x])/2.0) && (hue > (_75GY40[x] + _5GY40[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _75GY40[y] - _75GY40[x] ;} + else if (( hue<=(_5GY40[x] + _75GY40[x])/2.0) && (hue > (_5GY40[x]-0.035)) && x < 85) {if(y>89) y=89; correction = _5GY40[y] - _5GY40[x] ; } // + } + else if ((lum >= 45.0 && lum <55.0)) { + if( (hue <= (_7G50[x] + 0.035)) && (hue > (_7G50[x] + _5G50[x])/2.0) ) {correction = _7G50[y] - _7G50[x] ;} + else if( (hue <= (_7G50[x] + _5G50[x])/2.0) && (hue >(_5G50[x] + _25G50[x])/2.0)) {correction = _5G50[y] - _5G50[x] ;} + else if (( hue<=(_25G50[x] + _5G50[x])/2.0) && (hue > (_25G50[x] + _1G50[x])/2.0)) {correction = _25G50[y] - _25G50[x] ;} + else if (( hue<=(_1G50[x] + _25G50[x])/2.0) && (hue > (_1G50[x] + _10GY50[x])/2.0)) {correction = _1G50[y] - _1G50[x] ; } + else if (( hue<=(_1G50[x] + _10GY50[x])/2.0) && (hue > (_10GY50[x] + _75GY50[x])/2.0)) {correction = _10GY50[y] - _10GY50[x] ; } + else if (( hue<=(_10GY50[x] + _75GY50[x])/2.0) && (hue > (_75GY50[x] + _5GY50[x])/2.0)) {correction = _75GY50[y] - _75GY50[x] ;} + else if (( hue<=(_5GY50[x] + _75GY50[x])/2.0) && (hue > (_5GY50[x] -0.035))) {correction = _5GY50[y] - _5GY50[x] ; } + } + else if ((lum >= 55.0 && lum <65.0)) { + if( (hue <= (_7G60[x] + 0.035)) && (hue > (_7G60[x] + _5G60[x])/2.0) ) {correction = _7G60[y] - _7G60[x] ;} + else if( (hue <= (_7G60[x] + _5G60[x])/2.0) && (hue >(_5G60[x] + _25G60[x])/2.0)) {correction = _5G60[y] - _5G60[x] ;} + else if (( hue<=(_25G60[x] + _5G60[x])/2.0) && (hue > (_25G60[x] + _1G60[x])/2.0)) {correction = _25G60[y] - _25G60[x] ;} + else if (( hue<=(_1G60[x] + _25G60[x])/2.0) && (hue > (_1G60[x] + _10GY60[x])/2.0)) {correction = _1G60[y] - _1G60[x] ; } + else if (( hue<=(_1G60[x] + _10GY60[x])/2.0) && (hue > (_10GY60[x] + _75GY60[x])/2.0)) {correction = _10GY60[y] - _10GY60[x] ; } + else if (( hue<=(_10GY60[x] + _75GY60[x])/2.0) && (hue > (_75GY60[x] + _5GY60[x])/2.0)) {correction = _75GY60[y] - _75GY60[x] ;} + else if (( hue<=(_5GY60[x] + _75GY60[x])/2.0) && (hue > (_5GY60[x] -0.035))) {correction = _5GY60[y] - _5GY60[x] ; } + } + else if ((lum >= 65.0 && lum <75.0)) { + if( (hue <= (_7G70[x] + 0.035)) && (hue > (_7G70[x] + _5G70[x])/2.0) ) {correction = _7G70[y] - _7G70[x] ;} + else if( (hue <= (_7G70[x] + _5G70[x])/2.0) && (hue >(_5G70[x] + _25G70[x])/2.0)) {correction = _5G70[y] - _5G70[x] ;} + else if (( hue<=(_25G70[x] + _5G70[x])/2.0) && (hue > (_25G70[x] + _1G70[x])/2.0)) {correction = _25G70[y] - _25G70[x] ;} + else if (( hue<=(_1G70[x] + _25G70[x])/2.0) && (hue > (_1G70[x] + _10GY70[x])/2.0)) {correction = _1G70[y] - _1G70[x] ; } + else if (( hue<=(_1G70[x] + _10GY70[x])/2.0) && (hue > (_10GY70[x] + _75GY70[x])/2.0)) {correction = _10GY70[y] - _10GY70[x] ; } + else if (( hue<=(_10GY70[x] + _75GY70[x])/2.0) && (hue > (_75GY70[x] + _5GY70[x])/2.0)) {correction = _75GY70[y] - _75GY70[x] ;} + else if (( hue<=(_5GY70[x] + _75GY70[x])/2.0) && (hue > (_5GY70[x] -0.035))) {correction = _5GY70[y] - _5GY70[x] ; } + } + else if ((lum >= 75.0 && lum <85.0)) { + if( (hue <= (_7G80[x] + 0.035)) && (hue > (_7G80[x] + _5G80[x])/2.0) ) {correction = _7G80[y] - _7G80[x] ;} + else if( (hue <= (_7G80[x] + _5G80[x])/2.0) && (hue >(_5G80[x] + _25G80[x])/2.0)) {correction = _5G80[y] - _5G80[x] ;} + else if (( hue<=(_25G80[x] + _5G80[x])/2.0) && (hue > (_25G80[x] + _1G80[x])/2.0)) {correction = _25G80[y] - _25G80[x] ;} + else if (( hue<=(_1G80[x] + _25G80[x])/2.0) && (hue > (_1G80[x] + _10GY80[x])/2.0)) {correction = _1G80[y] - _1G80[x] ; } + else if (( hue<=(_1G80[x] + _10GY80[x])/2.0) && (hue > (_10GY80[x] + _75GY80[x])/2.0)) {correction = _10GY80[y] - _10GY80[x] ; } + else if (( hue<=(_10GY80[x] + _75GY80[x])/2.0) && (hue > (_75GY80[x] + _5GY80[x])/2.0)) {correction = _75GY80[y] - _75GY80[x] ;} + else if (( hue<=(_5GY80[x] + _75GY80[x])/2.0) && (hue > (_5GY80[x] -0.035))) {correction = _5GY80[y] - _5GY80[x] ; } + }//end green yellow + + } + + if(zone==4) {//Red purple correction : only for L < 30 + if ((lum > 5.0 && lum < 15.0)) { + if( (hue <= (_5R10[x] + 0.035)) && (hue > (_5R10[x] - 0.043)) && x<45) {if(y>44) y=44;correction = _5R10[y] - _5R10[x] ;} + else if( (hue <= (_25R10[x] + 0.043)) && (hue >(_25R10[x] + _10RP10[x])/2.0) && x<45 ) {if(y>44) y=44;correction = _25R10[y] - _25R10[x] ;} + else if ( (hue <=(_25R10[x] + _10RP10[x])/2.0) && (hue > (_10RP10[x] -0.035) ) && x<45){if(y>44) y=44; correction = _10RP10[y] - _10RP10[x] ;} + } + else if ((lum >= 15.0 && lum <25.0)) { + if( (hue <= (_5R20[x] + 0.035)) && (hue > (_5R20[x] + _25R20[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _5R20[y] - _5R20[x] ;} + else if( (hue <= (_5R20[x] + _25R20[x])/2.0) && (hue >(_10RP20[x] + _25R20[x])/2.0) && x<70) {if(y>70) y=70;correction = _25R20[y] - _25R20[x] ;} + else if (( hue<=(_10RP20[x] + _25R20[x])/2.0) && (hue > (_10RP20[x] -0.035)) && x<70) {if(y>70) y=70; correction = _10RP20[y] - _10RP20[x] ;} + } + else if ((lum >= 25.0 && lum <35.0)) { + if( (hue <= (_5R30[x] + 0.035)) && (hue > (_5R30[x] + _25R30[x])/2.0) && x<85 ) {if(y>85) y=85;correction = _5R30[y] - _5R30[x] ;} + else if( (hue <= (_5R30[x] + _25R30[x])/2.0) && (hue >(_10RP30[x] + _25R30[x])/2.0) && x< 85) {if(y>85) y=85;correction = _25R30[y] - _25R30[x] ;} + else if (( hue<=(_10RP30[x] + _25R30[x])/2.0) && (hue > (_10RP30[x] -0.035)) && x<85) {if(y>85) y=85; correction = _10RP30[y] - _10RP30[x] ;} + }//end red purple + } +} + + +/* + * copyright (c)2011 Jacques Desmis + * skin color: mixed from NX2 skin color palette, Von Luschan, and photos of people white, + * black, yellow....there are some little exceptions...cover 99% case + * pay attention to white balance, and do not change hue and saturation, upstream of the modification + * + */ +void ImProcFunctions::skinsat (float lum, float hue, float chrom, float &satreduc) { + + float reduction=0.3;// to be adapted...by tests + float extendedreduction=0.4; + float extendedreduction2=0.6; + + float C9=0.0, C8=0.0, C7=0.0, C4=0.0, C3=0.0, C2=0.0, C1=0.0; + float H9=0.0, H8=0.0, H7=0.0, H4=0.0, H3=0.0, H2=0.0, H1=0.0, H10=0.0,H11=0.0; + H9=0.05;H8=0.25;H7=0.1;H4=0.02;H3=0.02;H2=0.1;H1=0.1;H10=-0.2;H11=-0.2;//H10 and H11 are curious...H11=-0.8 ?? + C9=8.0;C8=15.0;C7=12.0;C4=7.0;C3=5.0;C2=5.0;C1=5.0; + // wide area for transition + if(lum >= 92.0 && (hue > -0.1 && hue < 1.65) && (chrom > 7.0 && chrom < (18.0))) satreduc=extendedreduction2; + else if (lum >= 85.0 && lum < 92.0 && (hue > 0.0 && hue < 1.65) && (chrom > 7.0 && chrom < (35.0+C9))) satreduc=extendedreduction2; + else if ((lum > 20 && lum < 85) && (hue > (0.02 + H11) && hue < 1.65) && (chrom > 7.0 && chrom < (55.0+C9) )) satreduc=extendedreduction2; + else if (lum < 20.0 && (hue > (0.02+H11) && hue < 1.60) && (chrom > 7.0 && chrom < (45.0+C1) )) satreduc=extendedreduction2; + + // wide area skin color, useful if not accurate colorimetry or if the user has changed hue and saturation + + if(lum >= 92.0 && (hue > 0.8 && hue < 1.65) && (chrom > 7.0 && chrom < (15.0))) satreduc=extendedreduction; + else if(lum >= 85.0 && lum < 92.0 && (hue > 0.70 && hue < 1.4) && (chrom > 7.0 && chrom < (26.0+C9))) satreduc=extendedreduction; + else if ((lum > 20 && lum < 85) && (hue > (0.02 + H11) && hue < 1.5) && (chrom > 7.0 && chrom < (48.0+C9) )) satreduc=extendedreduction; + else if (lum < 20.0 && (hue > (0.02+H11) && hue < 1.0) && (chrom > 7.0 && chrom < (35.0+C1) )) satreduc=extendedreduction; + + // "real" skin color : take into account a slightly usage of contrast and saturation in RT if option "skin" = 1 + if(lum >= 85.0 && (hue > (0.78-H9) && hue < (1.18+H9)) && (chrom > 8.0 && chrom < (14.0+C9))) satreduc=reduction; + else if ((lum >= 70.0 && lum < 85.0) && (hue > 0.4 && hue < (1.04+H8)) && (chrom > 8.0 && chrom < (35.0+C8))) satreduc=reduction; + else if ((lum >= 52.0 && lum < 70.0) && (hue > 0.3 && hue < (1.27+H7)) && (chrom > 11.0 && chrom < (35.0+C7))) satreduc=reduction; + else if ((lum >= 35.0 && lum < 52.0) && (hue > 0.3 && hue < (1.25+H4)) && (chrom > 13.0 && chrom < (37.0+C4))) satreduc=reduction; + else if ((lum >= 20.0 && lum < 35.0) && (hue > 0.3 && hue < (1.20+H3)) && (chrom > 7.0 && chrom <(35.0+C3) )) satreduc=reduction; + else if ((lum > 10.0 && lum < 20.0) && (hue > (0.0 + H10) && hue < (0.95 +H2)) && (chrom > 8.0 && chrom < (23.0+C2))) satreduc=reduction; + else if ((lum < 10.0) && (hue > (0.02 + H10) && hue < (0.90+H1)) && (chrom > 8.0 && chrom < (23.0+C1))) satreduc=reduction; // no data : extrapolate +} + +/* + * vibrance correction + * copyright (c)2011 Jacques Desmis and Jean-Christophe Frisch + * + */ +void ImProcFunctions::vibrance (LabImage* lab) { + if (!params->vibrance.enabled || (!params->vibrance.pastels && !params->vibrance.saturated)) + return; + + int width = lab->W, height = lab->H; + +#ifdef _DEBUG + MyTime t1e,t2e; + t1e.set(); + + float maxdeltaHueBP=0.0,maxdeltaHueRY=0.0,maxdeltaHueGY=0.0, maxdeltaHueRP=0.0; + int negat=0, moreRGB=0, negsat=0 ,moresat=0; + int Munspb=0, Munsry=0, Munsgy=0, Munsrp=0; + int depass=0; +#endif + + /*float *LL,*CC,*HH; + + LL = new float[width*height];//pointer for ulterior usage(convolution...) + CC = new float[width*height]; + HH = new float[width*height]; + */ + +#ifdef _DEBUG +#pragma omp parallel default(shared) reduction(+: negat, moreRGB, negsat ,moresat, Munspb, Munsry, Munsgy, Munsrp, depass) if (multiThread) +#else +#pragma omp parallel default(shared) if (multiThread) +#endif +{ + + float LL,CC,HH; + float R,G,B,RR,GG,BB; + float fy,fx,fz,x_,y_,z_,Lprov,Lprov1,aprov1,bprov1,aprovn,bprovn,fxx,fyy,fzz,xx_,yy_,zz_; + float saturation; + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); + float chromaPastel= (float) params->vibrance.pastels / 100.0f;// + float chromaSatur = (float) params->vibrance.saturated / 100.0f;// + bool highlight = params->hlrecovery.enabled;//Get the value if "highlight reconstruction" is activated + //inverse matrix user select + float wip[3][3] = { + {wiprof[0][0],wiprof[0][1],wiprof[0][2]}, + {wiprof[1][0],wiprof[1][1],wiprof[1][2]}, + {wiprof[2][0],wiprof[2][1],wiprof[2][2]} + }; + float Chprov,memChprov,Chprov1; + float satredu;//reduct sat in function of skin + float sathue[5],sathue2[4];// adjust sat in function of hue + float correctionHue; // Munsell's correction + float limitpastelsatur; + int zone=0; + bool allwaysingamut=true; + limitpastelsatur=(float)params->vibrance.psthreshold / 100.0f; + if (limitpastelsatur < 0.07) limitpastelsatur=0.07; + float p0,p1,p2;//adapt limit of pyramid to psThreshold + float s0,s1,s2; + float maxdp=(limitpastelsatur-0.07)/4.0; + float maxds=(1.0-limitpastelsatur)/4.0; + p0=0.07+maxdp; + p1=0.07+2.0*maxdp; + p2=0.07+3.0*maxdp; + s0=limitpastelsatur + maxds; + s1=limitpastelsatur + 2.0*maxds; + s2=limitpastelsatur + 3.0*maxds; + + //if (settings->verbose) printf("vibrance: p0=%1.2f p1=%1.2f p2=%1.2f s0=%1.2f s1=%1.2f s2=%1.2f\n", p0,p1,p2,s0,s1,s2); + if (settings->verbose) printf("vibrance: pastel=%f satur=%f limit= %1.2f\n",1.0+chromaPastel,1.0+chromaSatur, limitpastelsatur); + +#pragma omp for schedule(dynamic, 10) + for (int i=0; iL[i][j]/327.68f; + CC=sqrt(lab->a[i][j]/327.68f*lab->a[i][j]/327.68f + lab->b[i][j]/327.68f*lab->b[i][j]/327.68f); + HH=atan2(lab->b[i][j],lab->a[i][j]); + //double pyramid: LL and HH + //I try to take into account: Munsell response (human vision) and Gamut..(less response for red): preferably using Prophoto or WideGamut + //blue: -1.80 -3.14 green = 2.1 3.14 green-yellow=1.4 2.1 red:0 1.4 blue-purple:-0.7 -1.4 purple: 0 -0.7 + //these values allow a better and differential response + if(LL < 20.0) {//more for blue-purple, blue and red modulate + if (HH< -1.5 && HH>- 3.1415) {sathue[0]=1.3;sathue[1]=1.2;sathue[2]=1.1;sathue[3]=1.05;sathue[4]=0.4;sathue2[0]=1.05;sathue2[1]=1.1 ;sathue2[2]=1.05;sathue2[3]=1.0;}//blue + else if(HH> 2.1 && HH<= 3.1415) {sathue[0]=1.4;sathue[1]=1.3;sathue[2]=1.2;sathue[3]=1.15;sathue[4]=0.4;sathue2[0]=1.15;sathue2[1]=1.1 ;sathue2[2]=1.05;sathue2[3]=1.0;}//green + else if(HH> 1.4 && HH<= 2.1 ) {sathue[0]=1.0;sathue[1]=1.0;sathue[2]=1.0;sathue[3]=1.0 ;sathue[4]=0.4;sathue2[0]=1.0 ;sathue2[1]=1.0 ;sathue2[2]=1.0 ;sathue2[3]=1.0;}//green yellow 1.2 1.1 + else if(HH< -0.7 && HH>=-1.5 ) {sathue[0]=1.6;sathue[1]=1.4;sathue[2]=1.3;sathue[3]=1.2 ;sathue[4]=0.4;sathue2[0]=1.2 ;sathue2[1]=1.15;sathue2[2]=1.1 ;sathue2[3]=1.0;}//blue purple 1.2 1.1 + // else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=1.1;sathue[1]=1.1;sathue[2]=1.1;sathue[3]=1.0 ;sathue[4]=0.4;sathue2[0]=1.0 ;sathue2[1]=1.0 ;sathue2[2]=1.0 ;sathue2[3]=1.0;}//red 0.8 0.7 + else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=1.3;sathue[1]=1.2;sathue[2]=1.1;sathue[3]=1.0 ;sathue[4]=0.4;sathue2[0]=1.0 ;sathue2[1]=1.0 ;sathue2[2]=1.0 ;sathue2[3]=1.0;}//red 0.8 0.7 + else if(HH< 0.0 && HH>=-0.7 ) {sathue[0]=1.2;sathue[1]=1.0;sathue[2]=1.0;sathue[3]=1.0 ;sathue[4]=0.4;sathue2[0]=1.0 ;sathue2[1]=1.0 ;sathue2[2]=1.0 ;sathue2[3]=1.0;}//purple + } + else if (LL>=20 && LL< 50) {//more for blue and green, less for red and green-yellow + if (HH< -1.5 && HH>- 3.1415) {sathue[0]=1.5;sathue[1]=1.4;sathue[2]=1.3;sathue[3]=1.2 ;sathue[4]=0.4;sathue2[0]=1.2 ;sathue2[1]=1.1 ;sathue2[2]=1.05;sathue2[3]=1.0;}//blue + else if(HH> 2.1 && HH<= 3.1415) {sathue[0]=1.5;sathue[1]=1.4;sathue[2]=1.3;sathue[3]=1.2 ;sathue[4]=0.4;sathue2[0]=1.2 ;sathue2[1]=1.1 ;sathue2[2]=1.05;sathue2[3]=1.0;}//green + else if(HH> 1.4 && HH<= 2.1 ) {sathue[0]=1.1;sathue[1]=1.1;sathue[2]=1.1;sathue[3]=1.05;sathue[4]=0.4;sathue2[0]=0.9 ;sathue2[1]=0.8 ;sathue2[2]=0.7 ;sathue2[3]=0.6;}//green yellow 1.2 1.1 + else if(HH< -0.7 && HH>=-1.5 ) {sathue[0]=1.3;sathue[1]=1.2;sathue[2]=1.1;sathue[3]=1.05;sathue[4]=0.4;sathue2[0]=1.05;sathue2[1]=1.05;sathue2[2]=1.0 ;sathue2[3]=1.0;}//blue purple 1.2 1.1 + else if(HH< 0.0 && HH>=-0.7 ) {sathue[0]=1.2;sathue[1]=1.0;sathue[2]=1.0;sathue[3]=1.0 ;sathue[4]=0.4;sathue2[0]=1.0 ;sathue2[1]=1.0 ;sathue2[2]=1.0 ;sathue2[3]=1.0;}//purple + // else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=0.8;sathue[1]=0.8;sathue[2]=0.8;sathue[3]=0.8 ;sathue[4]=0.4;sathue2[0]=0.8 ;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//red 0.8 0.7 + else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=1.1;sathue[1]=1.0;sathue[2]=0.9;sathue[3]=0.8 ;sathue[4]=0.4;sathue2[0]=0.8 ;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//red 0.8 0.7 + + } + else if (LL>=50 && LL< 80) {//more for green, less for red and green-yellow + if (HH< -1.5 && HH>- 3.1415) {sathue[0]=1.3;sathue[1]=1.2;sathue[2]=1.15;sathue[3]=1.1 ;sathue[4]=0.3;sathue2[0]=1.1 ;sathue2[1]=1.1 ;sathue2[2]=1.05;sathue2[3]=1.0;}//blue + else if(HH> 2.1 && HH<= 3.1415) {sathue[0]=1.6;sathue[1]=1.4;sathue[2]=1.3 ;sathue[3]=1.25;sathue[4]=0.3;sathue2[0]=1.25;sathue2[1]=1.2 ;sathue2[2]=1.15;sathue2[3]=1.05;}//green - even with Prophoto green are too "little" 1.5 1.3 + else if(HH> 1.4 && HH<= 2.1 ) {sathue[0]=1.3;sathue[1]=1.2;sathue[2]=1.1 ;sathue[3]=1.05;sathue[4]=0.3;sathue2[0]=1.0 ;sathue2[1]=0.9 ;sathue2[2]=0.8 ;sathue2[3]=0.7;}//green yellow 1.2 1.1 + else if(HH< -0.7 && HH>=-1.5 ) {sathue[0]=1.3;sathue[1]=1.2;sathue[2]=1.15;sathue[3]=1.1 ;sathue[4]=0.3;sathue2[0]=1.1 ;sathue2[1]=1.05;sathue2[2]=1.0 ;sathue2[3]=1.0;}//blue purple 1.2 1.1 + else if(HH< 0.0 && HH>=-0.7 ) {sathue[0]=1.2;sathue[1]=1.0;sathue[2]=1.0 ;sathue[3]=1.0 ;sathue[4]=0.3;sathue2[0]=1.0 ;sathue2[1]=1.0 ;sathue2[2]=1.0 ;sathue2[3]=1.0;}//purple + // else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=0.8;sathue[1]=0.8;sathue[2]=0.8 ;sathue[3]=0.8 ;sathue[4]=0.3;sathue2[0]=0.8 ;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//red 0.8 0.7 + else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=1.1;sathue[1]=1.0;sathue[2]=0.9 ;sathue[3]=0.8 ;sathue[4]=0.3;sathue2[0]=0.8 ;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//red 0.8 0.7 + } + else if (LL>=80) {//more for green-yellow, less for red and purple + if (HH< -1.5 && HH>- 3.1415) {sathue[0]=1.0;sathue[1]=1.0;sathue[2]=0.9;sathue[3]=0.8;sathue[4]=0.2;sathue2[0]=0.8;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//blue + else if(HH> 2.1 && HH<= 3.1415) {sathue[0]=1.4;sathue[1]=1.3;sathue[2]=1.2;sathue[3]=1.1;sathue[4]=0.2;sathue2[0]=1.1;sathue2[1]=1.05;sathue2[2]=1.05;sathue2[3]=1.0;}//green + else if(HH> 1.4 && HH<= 2.1 ) {sathue[0]=1.6;sathue[1]=1.5;sathue[2]=1.4;sathue[3]=1.2;sathue[4]=0.2;sathue2[0]=1.1;sathue2[1]=1.05;sathue2[2]=1.0 ;sathue2[3]=1.0;}//green yellow 1.2 1.1 + else if(HH< -0.7 && HH>=-1.5 ) {sathue[0]=1.0;sathue[1]=1.0;sathue[2]=0.9;sathue[3]=0.8;sathue[4]=0.2;sathue2[0]=0.8;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//blue purple 1.2 1.1 + else if(HH< 0.0 && HH>=-0.7 ) {sathue[0]=1.2;sathue[1]=1.0;sathue[2]=1.0;sathue[3]=0.9;sathue[4]=0.2;sathue2[0]=0.9;sathue2[1]=0.9 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//purple + // else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=0.8;sathue[1]=0.8;sathue[2]=0.8;sathue[3]=0.8;sathue[4]=0.2;sathue2[0]=0.8;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//red 0.8 0.7 + else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=1.1;sathue[1]=1.0;sathue[2]=0.9;sathue[3]=0.8;sathue[4]=0.2;sathue2[0]=0.8;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//red 0.8 0.7 + } + + satredu=1.0; + if(params->vibrance.protectskins) + skinsat (LL, HH, CC, satredu);// for skin colors + // here we work on Chromaticity and Hue + // variation of Chromaticity ==> saturation via RGB + // Munsell correction + // then conversion to Lab + Chprov=Chprov1=CC; + memChprov=Chprov; + Lprov1=LL; + bool inGamut; + //begin gamut control: specially if no ICC profil is used and if ICC and GamutICC=true + do { + inGamut=true; + + //Lprov1=LL; + aprov1=Chprov1*cos(HH); + bprov1=Chprov1*sin(HH); + + //conversion Lab RGB to limit Lab values - this conversion is usefull before Munsell correction + fy = (0.00862069 *Lprov1 )+ 0.137932; + fx = (0.002 * aprov1) + fy; + fz = fy - (0.005 * bprov1); + + x_ = 65535.0 * f2xyz(fx)*D50x; + y_ = 65535.0 * f2xyz(fy); + z_ = 65535.0 * f2xyz(fz)*D50z; + xyz2rgb(x_,y_,z_,R,G,B,wip); + + // gamut control before saturation to put Lab values in future gamut, but not RGB + if (allwaysingamut) { // gamut control + if (R<0.0f || G<0.0f || B<0.0f) { +#ifdef _DEBUG + negat++; +#endif + if (Lprov1 < 0.01f) + Lprov1=0.05f; + Chprov1 *=0.95f; // one can modify this value... + if (Chprov1> 3.0f) + inGamut=false; + else { + Lprov1+=0.3f; + inGamut=false; + } + } + else if ((!highlight) && (R>65534.5f || G>65534.5f || B>65534.5f)){ // if "highlight reconstruction" is enabled, don't control Gamut +#ifdef _DEBUG + moreRGB++; +#endif + if (Lprov1>99.99f) + Lprov1=99.8f; + Chprov1 *=0.95f; + if (Chprov1> 3.0f) + inGamut=false; + else { + Lprov1 -=0.3f; + inGamut=false; + } + } + } + } + while (!inGamut); + //end first gamut control + + Chprov=Chprov1; + Lprov=Lprov1; + + saturation=SAT(R,G,B); + // work on saturation + if(Chprov > 6.0) { //protect gray and LUT Munsell + //pyramid to adjust saturation in function of saturation and hue (and Luminance) + if(satredu!=1.0){ + // for skin, no differenciation + sathue [0]=1.; sathue [1]=1.; sathue [2]=1.; sathue [3]=1.0; sathue[4]=1.0; + sathue2[0]=1.; sathue2[1]=1.; sathue2[2]=1.; sathue2[3]=1.0; + } + + if(saturation>0.0) { + float chmodpastel,chmodsat; + + // We handle only positive values here + if (saturation < 0.07) chmodpastel = chromaPastel*satredu*sathue[4]; //neutral tones + else if (saturation < p0) chmodpastel = chromaPastel*satredu*sathue[0]; + else if (saturation < p1) chmodpastel = chromaPastel*satredu*sathue[1]; + else if (saturation < p2) chmodpastel = chromaPastel*satredu*sathue[2]; + else if (saturation < limitpastelsatur) chmodpastel = chromaPastel*satredu*sathue[3]; + else if (saturation < s0) chmodsat = chromaSatur*satredu*sathue2[0]; + else if (saturation < s1) chmodsat = chromaSatur*satredu*sathue2[1]; + else if (saturation < s2) chmodsat = chromaSatur*satredu*sathue2[2]; + else chmodsat = chromaSatur*satredu*sathue2[3]; + + if(chromaPastel != chromaSatur){ + //if sliders pastels and saturated differents: tansition with linear interpolation between p2 and s0 + float chromaPastel_a, chromaPastel_b, chromamean, chromaSatur_a, chromaSatur_b, newchromaPastel, newchromaSatur; + + chromamean = (chromaSatur + chromaPastel)/2.0; + chromaPastel_a = (chromaPastel-chromamean)/(p2-limitpastelsatur); + chromaPastel_b = chromaPastel-chromaPastel_a*p2; + if(saturation > p2 && saturation < limitpastelsatur) { + newchromaPastel = chromaPastel_a*saturation + chromaPastel_b; + chmodpastel = newchromaPastel*satredu*sathue[3]; + } + + chromaSatur_a=(chromaSatur-chromamean)/(s0-limitpastelsatur); + chromaSatur_b=chromaSatur-chromaSatur_a*s0; + if(saturation < s0 && saturation >=limitpastelsatur) {newchromaSatur=chromaSatur_a*saturation + chromaSatur_b; chmodsat = newchromaSatur*satredu*sathue2[0];} + }// end transition + if (saturation <= limitpastelsatur) { + if(chmodpastel > 2.0 ) chmodpastel = 2.0; //avoid too big values + if(chmodpastel < -0.93) chmodpastel =-0.93; //avoid negative values + + Chprov *=(1.0+chmodpastel); + if(Chprov<6.0) Chprov=6.0; + } + else { //if (saturation > limitpastelsatur) + if(chmodsat > 1.8 ) chmodsat = 1.8; //saturated + if(chmodsat < -0.93) chmodsat =-0.93; + + Chprov *= 1.0+chmodsat; + if(Chprov <6.0) Chprov=6.0; + } + } + } + + //Munsell correction + correctionHue=0.0; + do { + inGamut=true; + if(params->vibrance.avoidcolorshift) { + if(memChprov >= 6.0 && memChprov < 140) { //if C > 140 we say C=140 (only in Prophoto ...with very large saturation) + if (Chprov > 140) Chprov=139; //limits of LUTf + if(HH > -2.48 && HH < -0.55) { //limits of hue Blue purple -1.90 + zone=1; // *** blue purple correction and blue correction for sky + MunsellLch (Lprov, HH,Chprov, memChprov, correctionHue, zone); +#ifdef _DEBUG + if(correctionHue !=0.0) { + if(fabs(correctionHue) > maxdeltaHueBP) + maxdeltaHueBP=fabs(correctionHue); + Munspb++; + } + if(fabs(correctionHue) > 0.45) depass++; //verify if no bug in calculation +#endif + } + if(HH > 0.44 && HH < 1.52) { //limits of hue red yellow + zone=2; // *** red yellow correction + MunsellLch (Lprov, HH,Chprov, memChprov, correctionHue, zone); +#ifdef _DEBUG + if(correctionHue !=0.0) { + if(fabs(correctionHue) > maxdeltaHueRY) + maxdeltaHueRY=fabs(correctionHue); + Munsry++; + } + if(fabs(correctionHue) > 0.45) depass++; //verify if no bug in calculation +#endif + } + if(HH > 1.87 && HH < 3.09) { //limits of green and green yellow + zone=3; // *** green yellow correction + MunsellLch (Lprov, HH,Chprov, memChprov, correctionHue, zone); +#ifdef _DEBUG + if(correctionHue !=0.0) { + if(fabs(correctionHue) > maxdeltaHueGY) + maxdeltaHueGY=fabs(correctionHue); + Munsgy++; + } + if(fabs(correctionHue) > 0.45) depass++; //verify if no bug in calculation +#endif + } + if(HH > -0.27 && HH <= 0.44) { //limits of Red purple + zone=4; // *** red purple correction + MunsellLch (Lprov, HH,Chprov, memChprov, correctionHue, zone); +#ifdef _DEBUG + if(correctionHue !=0.0) { + if(fabs(correctionHue) > maxdeltaHueRP) + maxdeltaHueRP=fabs(correctionHue); + Munsrp++; + } + if(fabs(correctionHue) > 0.45) depass++; //verify if no bug in calculation +#endif + } + } + } + //second gamut control take into account Munsell and saturation if R G B > 65535 + aprovn=Chprov*cos(HH+correctionHue); + bprovn=Chprov*sin(HH+correctionHue); + if (allwaysingamut) { // gamut control + + fyy = (0.00862069 *Lprov )+ 0.137932; + fxx = (0.002 * aprovn) + fyy; + fzz = fyy - (0.005 * bprovn); + + xx_ = 65535.0 * f2xyz(fxx)*D50x; + yy_ = 65535.0 * f2xyz(fyy); + zz_ = 65535.0 * f2xyz(fzz)*D50z; + xyz2rgb(xx_,yy_,zz_,RR,GG,BB,wip); + + if(RR<0.0 || GG < 0.0 || BB < 0.0) { +#ifdef _DEBUG + negsat++; +#endif + Chprov*=0.95; + inGamut=false; + } + if((!highlight) && (RR>65535.0 || GG > 65535.0 || BB>65535.0)) {// if "highlight reconstruction" enabled don't control Gamut for highlights + // if(RR>65535.0 || GG > 65535.0 || BB>65535.0) { +#ifdef _DEBUG + moresat++; +#endif + Chprov*=0.95; + inGamut=false; + } + } + } while (!inGamut); + //put new values in Lab + lab->L[i][j]=Lprov*327.68; + lab->a[i][j]=aprovn*327.68; + lab->b[i][j]=bprovn*327.68; + + } + +} +/* +delete [] LL; +delete [] CC; +delete [] HH; +*/ + +#ifdef _DEBUG + t2e.set(); + if (settings->verbose) { + printf("Gamut: G1negat=%iiter G165535=%iiter G2negsat=%iiter G265535=%iiter\n",negat,moreRGB,negsat,moresat); + printf("Munsell: MunPB=%ipix MunRY=%ipix MunGY=%ipix MunRP=%ipix MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad dep=%i\n",Munspb, Munsry,Munsgy,Munsrp, maxdeltaHueBP,maxdeltaHueRY,maxdeltaHueGY,maxdeltaHueRP, depass); + printf("Vibrance %d usec\n", t2e.etime(t1e)); + } +#endif +} + +} diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 67e6aec43..4bcf70e76 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -172,9 +172,14 @@ enum ProcEvent { EvSharpenMicroEnabled=147, EvSharpenMicroMatrix=148, EvDemosaicALLEnhanced=149, - NUMOFEVENTS=150 - - - }; + EvVibranceEnabled=150, + EvVibrancePastels=151, + EvVibranceSaturated=152, + EvVibranceProtectSkins=153, + EvVibranceAvoidColorShift=154, + EvVibrancePastSatTog=155, + EvVibrancePastSatThreshold=156, + NUMOFEVENTS=157 +}; } #endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index a4af9e2eb..1ac64a271 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -115,6 +115,14 @@ void ProcParams::setDefaults () { sharpening.deconviter = 30; sharpening.deconvdamping = 20; sharpening.deconvamount = 75; + + vibrance.enabled = false; + vibrance.pastels = 0; + vibrance.saturated = 0; + vibrance.psthreshold = 75; + vibrance.protectskins = false; + vibrance.avoidcolorshift = true; + vibrance.pastsattog = true; colorBoost.amount = 0; colorBoost.avoidclip = false; @@ -338,6 +346,15 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2) const { keyFile.set_integer ("Sharpening", "DeconvDamping", sharpening.deconvdamping); keyFile.set_integer ("Sharpening", "DeconvIterations", sharpening.deconviter); + // save vibrance + keyFile.set_boolean ("Vibrance", "Enabled", vibrance.enabled); + keyFile.set_integer ("Vibrance", "Pastels", vibrance.pastels); + keyFile.set_integer ("Vibrance", "Saturated", vibrance.saturated); + keyFile.set_integer ("Vibrance", "PSThreshold", vibrance.psthreshold); + keyFile.set_boolean ("Vibrance", "ProtectSkins", vibrance.protectskins); + keyFile.set_boolean ("Vibrance", "AvoidColorShift", vibrance.avoidcolorshift); + keyFile.set_boolean ("Vibrance", "PastSatTog", vibrance.pastsattog); + //save edge sharpening keyFile.set_boolean ("SharpenEdge", "Enabled", sharpenEdge.enabled); keyFile.set_integer ("SharpenEdge", "Passes", sharpenEdge.passes); @@ -652,7 +669,7 @@ if (keyFile.has_group ("Sharpening")) { if (keyFile.has_group ("SharpenEdge")) { if (keyFile.has_key ("SharpenEdge", "Enabled")) sharpenEdge.enabled = keyFile.get_boolean ("SharpenEdge", "Enabled"); if (keyFile.has_key ("SharpenEdge", "Passes")) sharpenEdge.passes = keyFile.get_integer ("SharpenEdge", "Passes"); - if (keyFile.has_key ("SharpenEdge", "Strength")) sharpenEdge.amount = keyFile.get_double ("SharpenEdge", "Strength"); + if (keyFile.has_key ("SharpenEdge", "Strength")) sharpenEdge.amount = keyFile.get_double ("SharpenEdge", "Strength"); if (keyFile.has_key ("SharpenEdge", "ThreeChannels")) sharpenEdge.threechannels = keyFile.get_boolean ("SharpenEdge", "ThreeChannels"); } @@ -660,10 +677,21 @@ if (keyFile.has_group ("SharpenEdge")) { if (keyFile.has_group ("SharpenMicro")) { if (keyFile.has_key ("SharpenMicro", "Enabled")) sharpenMicro.enabled = keyFile.get_boolean ("SharpenMicro", "Enabled"); if (keyFile.has_key ("SharpenMicro", "Matrix")) sharpenMicro.matrix = keyFile.get_boolean ("SharpenMicro", "Matrix"); - if (keyFile.has_key ("SharpenMicro", "Strength")) sharpenMicro.amount = keyFile.get_double ("SharpenMicro", "Strength"); + if (keyFile.has_key ("SharpenMicro", "Strength")) sharpenMicro.amount = keyFile.get_double ("SharpenMicro", "Strength"); if (keyFile.has_key ("SharpenMicro", "Uniformity")) sharpenMicro.uniformity = keyFile.get_double ("SharpenMicro", "Uniformity"); } + // load vibrance +if (keyFile.has_group ("Vibrance")) { + if (keyFile.has_key ("Vibrance", "Enabled")) vibrance.enabled = keyFile.get_boolean ("Vibrance", "Enabled"); + if (keyFile.has_key ("Vibrance", "Pastels")) vibrance.pastels = keyFile.get_integer ("Vibrance", "Pastels"); + if (keyFile.has_key ("Vibrance", "Saturated")) vibrance.saturated = keyFile.get_integer ("Vibrance", "Saturated"); + if (keyFile.has_key ("Vibrance", "PSThreshold")) vibrance.psthreshold = keyFile.get_integer ("Vibrance", "PSThreshold"); + if (keyFile.has_key ("Vibrance", "ProtectSkins")) vibrance.protectskins = keyFile.get_boolean ("Vibrance", "ProtectSkins"); + if (keyFile.has_key ("Vibrance", "AvoidColorShift")) vibrance.avoidcolorshift = keyFile.get_boolean ("Vibrance", "AvoidColorShift"); + if (keyFile.has_key ("Vibrance", "PastSatTog")) vibrance.pastsattog = keyFile.get_boolean ("Vibrance", "PastSatTog"); +} + // load colorBoost if (keyFile.has_group ("Color Boost")) { if (keyFile.has_key ("Color Boost", "Amount")) colorBoost.amount = keyFile.get_integer ("Color Boost", "Amount"); @@ -976,6 +1004,13 @@ bool ProcParams::operator== (const ProcParams& other) { && sharpening.deconvradius == other.sharpening.deconvradius && sharpening.deconviter == other.sharpening.deconviter && sharpening.deconvdamping == other.sharpening.deconvdamping + && vibrance.enabled == other.vibrance.enabled + && vibrance.pastels == other.vibrance.pastels + && vibrance.saturated == other.vibrance.saturated + && vibrance.psthreshold == other.vibrance.psthreshold + && vibrance.protectskins == other.vibrance.protectskins + && vibrance.avoidcolorshift == other.vibrance.avoidcolorshift + && vibrance.pastsattog == other.vibrance.pastsattog && colorBoost.amount == other.colorBoost.amount && colorBoost.avoidclip == other.colorBoost.avoidclip && colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 38bcfcd45..c0fcf6720 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -96,6 +96,22 @@ class SharpenMicroParams { double amount; double uniformity; }; + +/** + * Parameters of the vibrance + */ +class VibranceParams { + + public: + bool enabled; + int pastels; + int saturated; + int psthreshold; + bool protectskins; + bool avoidcolorshift; + bool pastsattog; +}; + /** * Parameters of the color boost */ @@ -451,6 +467,7 @@ class ProcParams { SharpeningParams sharpening; ///< Sharpening parameters SharpenEdgeParams sharpenEdge; ///< Sharpen edge parameters SharpenMicroParams sharpenMicro; ///< Sharpen microcontrast parameters + VibranceParams vibrance; ///< Vibrance parameters ColorBoostParams colorBoost; ///< Color boost parameters WBParams wb; ///< White balance parameters ColorShiftParams colorShift; ///< Color shift parameters diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index d1aee83d2..ed9697215 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -32,6 +32,8 @@ #include #include + + #include #ifdef _OPENMP #include @@ -40,7 +42,6 @@ namespace rtengine { extern const Settings* settings; - #undef ABS #undef MAX #undef MIN @@ -1607,10 +1608,8 @@ void RawImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams //MyTime t1, t2, t3; //t1.set (); - cmsHPROFILE in; if (!findInputProfile(cmp.input, embedded, camName, in)) return; - // Calculate matrix for direct conversion raw>working space TMatrix work = iccStore->workingSpaceInverseMatrix (cmp.working); float mat[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; @@ -1649,9 +1648,76 @@ void RawImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams im->g[h][w] /= 65535.0f ; im->b[h][w] /= 65535.0f ; } - cmsHPROFILE out = iccStore->workingSpace (cmp.working); -// out = iccStore->workingSpaceGamma (wProfile); + if(settings->gamutICC) + // use Prophoto to apply profil ICC, then converted to cmp.working (sRGB..., Adobe.., Wide..) to avoid color shifts due to relative colorimetric + // LCMS use intent for applying profil => suppression of negatives values and > 65535 + //useful for correcting Munsell Lch + { if( settings->verbose ) printf("With Gamut ICC correction float\n"); + Glib::ustring profi ="ProPhoto"; + cmsHPROFILE out = iccStore->workingSpace (profi);//Prophoto + TMatrix wprof = iccStore->workingSpaceMatrix (profi); + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (cmp.working);//sRGB .. Adobe...Wide... + float toxyz[3][3] = { + { + ( wprof[0][0]), + ( wprof[0][1]), + ( wprof[0][2]) + },{ + ( wprof[1][0] ), + ( wprof[1][1] ), + ( wprof[1][2] ) + },{ + ( wprof[2][0]), + ( wprof[2][1]), + ( wprof[2][2]) + } + }; + float wip[3][3] = { + {wiprof[0][0],wiprof[0][1],wiprof[0][2]}, + {wiprof[1][0],wiprof[1][1],wiprof[1][2]}, + {wiprof[2][0],wiprof[2][1],wiprof[2][2]}}; + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (in, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), out, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), + INTENT_RELATIVE_COLORIMETRIC, // float is clipless, so don't trim it + settings->LCMSSafeMode ? 0 : cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + lcmsMutex->unlock (); + if (hTransform) { + im->ExecCMSTransform(hTransform, settings->LCMSSafeMode); + } + else { + // create the profile from camera + lcmsMutex->lock (); + hTransform = cmsCreateTransform (camprofile, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), out, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), settings->colorimetricIntent, + settings->LCMSSafeMode ? cmsFLAGS_NOOPTIMIZE : cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + lcmsMutex->unlock (); + + im->ExecCMSTransform(hTransform, settings->LCMSSafeMode); + } + float x, y,z; + Glib::ustring choiceprofile; + choiceprofile=cmp.working; + if(choiceprofile!="ProPhoto") { + for ( int h = 0; h < im->height; ++h ) + for ( int w = 0; w < im->width; ++w ) {//convert from Prophoto to XYZ + x = (toxyz[0][0] * im->r[h][w] + toxyz[0][1] * im->g[h][w] + toxyz[0][2] * im->b[h][w] ) ; + y = (toxyz[1][0] * im->r[h][w] + toxyz[1][1] * im->g[h][w] + toxyz[1][2] * im->b[h][w] ) ; + z = (toxyz[2][0] * im->r[h][w] + toxyz[2][1] * im->g[h][w] + toxyz[2][2] * im->b[h][w] ) ; + //convert from XYZ to cmp.working (sRGB...Adobe...Wide..) + im->r[h][w] = ((wiprof[0][0]*x + wiprof[0][1]*y + wiprof[0][2]*z)) ; + im->g[h][w] = ((wiprof[1][0]*x + wiprof[1][1]*y + wiprof[1][2]*z)) ; + im->b[h][w] = ((wiprof[2][0]*x + wiprof[2][1]*y + wiprof[2][2]*z)) ; + } + } + + cmsDeleteTransform(hTransform); + + } + else { + if( settings->verbose ) printf("Without Gamut ICC correction float\n"); + cmsHPROFILE out = iccStore->workingSpace (cmp.working); + +// out = iccStore->workingSpaceGamma (wProfile); lcmsMutex->lock (); cmsHTRANSFORM hTransform = cmsCreateTransform (in, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), out, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), INTENT_RELATIVE_COLORIMETRIC, // float is clipless, so don't trim it @@ -1672,7 +1738,8 @@ void RawImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams } cmsDeleteTransform(hTransform); - + } + // restore normalization to the range (0,65535) and blend matrix colors if LCMS is clipping const float RecoverTresh = 65535.0 * 0.98; // just the last few percent highlights are merged #pragma omp parallel for @@ -1736,7 +1803,6 @@ void RawImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams // Converts raw image including ICC input profile to working space - 16bit int version void RawImageSource::colorSpaceConversion16 (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded, cmsHPROFILE camprofile, double camMatrix[3][3], std::string camName, double& defgain) { - cmsHPROFILE in; if (!findInputProfile(cmp.input, embedded, camName, in)) return; @@ -1763,7 +1829,8 @@ TMatrix work = iccStore->workingSpaceInverseMatrix (cmp.working); im->b[i][j] = CLIP((int)newb); } } - else { + else + { cmsHPROFILE out = iccStore->workingSpace (cmp.working); // out = iccStore->workingSpaceGamma (wProfile); lcmsMutex->lock (); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 75ef900bc..f6057eada 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -170,6 +170,13 @@ SHARPENING, // EvSharpenEdgeThreechannels SHARPENING, // EvSharpenMicroEnabled SHARPENING, // EvSharpenMicroMatrix DEMOSAIC, // EvDemosaicALLEnhanced +RGBCURVE, // EvVibranceEnabled +RGBCURVE, // EvVibrancePastels +RGBCURVE, // EvVibranceSaturated +RGBCURVE, // EvVibranceProtectSkins +RGBCURVE, // EvVibranceAvoidColorShift +RGBCURVE, // EvVibrancePastSatTog +RGBCURVE // EvVibrancePastSatThreshold }; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index c32fdb509..8ffc504f3 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -751,6 +751,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, \ params.labCurve.acurve, params.labCurve.bcurve, curve1, curve2, satcurve, 16); ipf.chrominanceCurve (labView, labView, curve1, curve2, satcurve); + ipf.vibrance(labView); // color processing //ipf.colorCurve (labView, labView); diff --git a/rtengine/settings.h b/rtengine/settings.h index 16efcc96c..6eac8b625 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -40,6 +40,7 @@ namespace rtengine { Glib::ustring best; // default name of BestRGB Glib::ustring bruce; // default name of Bruce Glib::ustring srgb; // default name of SRGB space profile + bool gamutICC; // /** Creates a new instance of Settings. * @return a pointer to the new Settings instance. */ diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index e14bf6513..fc728964a 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -170,11 +170,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p hist16[CLIP((int)((labView->L[i][j])))]++; // luminance processing + CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, hist16, curve, dummy, 1); ipf.luminanceCurve (labView, labView, curve); CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, \ params.labCurve.acurve, params.labCurve.bcurve, curve1, curve2, satcurve, 1); ipf.chrominanceCurve (labView, labView, curve1, curve2, satcurve); + ipf.vibrance(labView); ipf.impulsedenoise (labView); ipf.defringe (labView); diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 13e32e1af..e5dba9632 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -9,7 +9,7 @@ set (BASESOURCEFILES resize.cc icmpanel.cc crop.cc shadowshighlights.cc impulsedenoise.cc dirpyrdenoise.cc exifpanel.cc toolpanel.cc - sharpening.cc + sharpening.cc vibrance.cc whitebalance.cc vignetting.cc rotate.cc distortion.cc crophandler.cc dirbrowser.cc curveeditor.cc curveeditorgroup.cc diagonalcurveeditorsubgroup.cc flatcurveeditorsubgroup.cc diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index 26422fcd4..81ccfc974 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -47,7 +47,11 @@ #define ADDSET_SHARPENMICRO_AMOUNT 37 #define ADDSET_SHARPENEDGE_PASS 38 #define ADDSET_SHARPENMICRO_UNIFORMITY 39 +#define ADDSET_VIBRANCE_PASTELS 40 +#define ADDSET_VIBRANCE_SATURATED 41 +#define ADDSET_VIBRANCE_PSTHRESHOLD 42 + // When adding items, make sure to update ADDSET_PARAM_NUM -#define ADDSET_PARAM_NUM 40 // THIS IS USED AS A DELIMITER!! +#define ADDSET_PARAM_NUM 43 // THIS IS USED AS A DELIMITER!! #endif diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 3aacb213c..217bed3bb 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -122,6 +122,7 @@ void BatchToolPanelCoordinator::initSession () { toneCurve->setAdjusterBehavior (false, false, false, false, false, false, false, false); lcurve->setAdjusterBehavior (false, false, false); whitebalance->setAdjusterBehavior (false, false); + vibrance->setAdjusterBehavior (false, false, false); vignetting->setAdjusterBehavior (false); rotate->setAdjusterBehavior (false); distortion->setAdjusterBehavior (false); @@ -144,6 +145,7 @@ void BatchToolPanelCoordinator::initSession () { toneCurve->setAdjusterBehavior (options.baBehav[ADDSET_TC_EXPCOMP], options.baBehav[ADDSET_TC_HLCOMPAMOUNT],options.baBehav[ADDSET_TC_HLCOMPTHRESH], options.baBehav[ADDSET_TC_BRIGHTNESS], options.baBehav[ADDSET_TC_BLACKLEVEL],options.baBehav[ADDSET_TC_SHCOMP], options.baBehav[ADDSET_TC_CONTRAST], options.baBehav[ADDSET_TC_SATURATION]); lcurve->setAdjusterBehavior (options.baBehav[ADDSET_LC_BRIGHTNESS], options.baBehav[ADDSET_LC_CONTRAST], options.baBehav[ADDSET_LC_SATURATION]); whitebalance->setAdjusterBehavior (options.baBehav[ADDSET_WB_TEMPERATURE], options.baBehav[ADDSET_WB_GREEN]); + vibrance->setAdjusterBehavior (options.baBehav[ADDSET_VIBRANCE_PASTELS], options.baBehav[ADDSET_VIBRANCE_SATURATED], options.baBehav[ADDSET_VIBRANCE_PSTHRESHOLD]); vignetting->setAdjusterBehavior (options.baBehav[ADDSET_VIGN_AMOUNT]); rotate->setAdjusterBehavior (options.baBehav[ADDSET_ROTATE_DEGREE]); distortion->setAdjusterBehavior (options.baBehav[ADDSET_DIST_AMOUNT]); @@ -189,6 +191,9 @@ void BatchToolPanelCoordinator::initSession () { if (options.baBehav[ADDSET_WB_TEMPERATURE]) pparams.wb.temperature = 0; if (options.baBehav[ADDSET_WB_GREEN]) pparams.wb.green = 0; + if (options.baBehav[ADDSET_VIBRANCE_PASTELS]) pparams.vibrance.pastels = 0; + if (options.baBehav[ADDSET_VIBRANCE_SATURATED]) pparams.vibrance.saturated = 0; + if (options.baBehav[ADDSET_CBOOST_AMOUNT]) pparams.colorBoost.amount = 0; if (options.baBehav[ADDSET_CS_BLUEYELLOW]) pparams.colorShift.a = 0; diff --git a/rtgui/options.cc b/rtgui/options.cc index 03c653c45..0ced9d81b 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -168,6 +168,7 @@ void Options::setDefaults () { sndEnable=true; sndLngEditProcDoneSecs=3.0; + // Reminder: 0 = SET mode, 1 = ADD mode int babehav[] = { 1, // ADDSET_TC_EXPCOMP 1, // ADDSET_TC_BRIGHTNESS @@ -208,7 +209,11 @@ void Options::setDefaults () { 0, // ADDSET_SHARPENEDGE_AMOUNT 0, // ADDSET_SHARPENMICRO_AMOUNT 0, // ADDSET_SHARPENEDGE_PASS - 0 // ADDSET_SHARPENMICRO_UNIFORMITY + 0, // ADDSET_SHARPENMICRO_UNIFORMITY + 1, // ADDSET_VIBRANCE_PASTELS + 1, // ADDSET_VIBRANCE_SATURATED + 0 // ADDSET_VIBRANCE_SATURATED + }; baBehav = std::vector (babehav, babehav+ADDSET_PARAM_NUM); @@ -234,8 +239,8 @@ void Options::setDefaults () { rtSettings.bruce = "Bruce"; rtSettings.beta = "BetaRGB"; rtSettings.best = "BestRGB"; - rtSettings.verbose = false; + rtSettings.gamutICC = true; } Options* Options::copyFrom (Options* other) { @@ -423,7 +428,8 @@ if (keyFile.has_group ("Color Management")) { if (keyFile.has_key ("Color Management", "Intent")) rtSettings.colorimetricIntent = keyFile.get_integer("Color Management", "Intent"); - if (keyFile.has_key ("Color Management", "WhiteBalanceSpotSize")) whiteBalanceSpotSize = keyFile.get_integer("Color Management", "WhiteBalanceSpotSize"); + if (keyFile.has_key ("Color Management", "WhiteBalanceSpotSize")) whiteBalanceSpotSize = keyFile.get_integer("Color Management", "WhiteBalanceSpotSize"); + if( keyFile.has_key ("Color Management", "GamutICC")) rtSettings.gamutICC = keyFile.get_boolean("Color Management", "GamutICC"); // Disabled (default is true) till issues are sorted out //if (keyFile.has_key ("Color Management", "LCMSSafeMode")) rtSettings.LCMSSafeMode = keyFile.get_boolean ("Color Management", "LCMSSafeMode"); @@ -602,6 +608,7 @@ int Options::saveToFile (Glib::ustring fname) { keyFile.set_string ("Color Management", "B_est", rtSettings.best); keyFile.set_string ("Color Management", "B_ruce", rtSettings.bruce); keyFile.set_integer ("Color Management", "WhiteBalanceSpotSize", whiteBalanceSpotSize); + keyFile.set_boolean ("Color Management", "GamutICC", rtSettings.gamutICC); Glib::ArrayHandle bab = baBehav; keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index b6350b044..9c9b8c908 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -42,57 +42,64 @@ void ParamsEdited::set (bool v) { labCurve.lcurve = v; labCurve.acurve = v; labCurve.bcurve = v; - labCurve.brightness = v; - labCurve.contrast = v; - labCurve.saturation = v; - labCurve.avoidclip = v; + labCurve.brightness = v; + labCurve.contrast = v; + labCurve.saturation = v; + labCurve.avoidclip = v; labCurve.enable_saturationlimiter = v; - labCurve.saturationlimit = v; - sharpening.enabled = v; - sharpening.radius = v; - sharpening.amount = v; - sharpening.threshold = v; - sharpening.edgesonly = v; - sharpening.edges_radius = v; - sharpening.edges_tolerance = v; - sharpening.halocontrol = v; - sharpening.halocontrol_amount= v; - sharpening.method = v; - sharpening.deconvamount = v; - sharpening.deconvradius = v; - sharpening.deconviter = v; - sharpening.deconvdamping = v; + labCurve.saturationlimit = v; + sharpening.enabled = v; + sharpening.radius = v; + sharpening.amount = v; + sharpening.threshold = v; + sharpening.edgesonly = v; + sharpening.edges_radius = v; + sharpening.edges_tolerance = v; + sharpening.halocontrol = v; + sharpening.halocontrol_amount = v; + sharpening.method = v; + sharpening.deconvamount = v; + sharpening.deconvradius = v; + sharpening.deconviter = v; + sharpening.deconvdamping = v; sharpenEdge.enabled = v; sharpenEdge.passes = v; - sharpenEdge.amount = v; + sharpenEdge.amount = v; sharpenEdge.threechannels = v; sharpenMicro.enabled = v; sharpenMicro.matrix = v; - sharpenMicro.amount = v; + sharpenMicro.amount = v; sharpenMicro.uniformity = v; + vibrance.enabled = v; + vibrance.pastels = v; + vibrance.saturated = v; + vibrance.psthreshold = v; + vibrance.protectskins = v; + vibrance.avoidcolorshift = v; + vibrance.pastsattog = v; colorBoost.amount = v; colorBoost.avoidclip = v; colorBoost.enable_saturationlimiter = v; colorBoost.saturationlimit = v; - wb.method = v; - wb.green = v; - wb.temperature = v; - colorShift.a = v; - colorShift.b = v; - lumaDenoise.enabled = v; - lumaDenoise.radius = v; - lumaDenoise.edgetolerance = v; - colorDenoise.enabled = v; - colorDenoise.amount = v; - defringe.enabled = v; - defringe.radius = v; - defringe.threshold = v; - impulseDenoise.enabled = v; - impulseDenoise.thresh = v; - dirpyrDenoise.enabled = v; - dirpyrDenoise.luma = v; - dirpyrDenoise.chroma = v; - dirpyrDenoise.gamma = v; + wb.method = v; + wb.green = v; + wb.temperature = v; + colorShift.a = v; + colorShift.b = v; + lumaDenoise.enabled = v; + lumaDenoise.radius = v; + lumaDenoise.edgetolerance = v; + colorDenoise.enabled = v; + colorDenoise.amount = v; + defringe.enabled = v; + defringe.radius = v; + defringe.threshold = v; + impulseDenoise.enabled = v; + impulseDenoise.thresh = v; + dirpyrDenoise.enabled = v; + dirpyrDenoise.luma = v; + dirpyrDenoise.chroma = v; + dirpyrDenoise.gamma = v; sh.enabled = v; sh.hq = v; sh.highlights = v; @@ -217,7 +224,7 @@ void ParamsEdited::initFrom (const std::vector labCurve.brightness = labCurve.brightness && p.labCurve.brightness == other.labCurve.brightness; labCurve.contrast = labCurve.contrast && p.labCurve.contrast == other.labCurve.contrast; labCurve.saturation = labCurve.saturation && p.labCurve.saturation == other.labCurve.saturation; - labCurve.avoidclip = labCurve.avoidclip && p.labCurve.avoidclip == other.labCurve.avoidclip; + labCurve.avoidclip = labCurve.avoidclip && p.labCurve.avoidclip == other.labCurve.avoidclip; labCurve.enable_saturationlimiter = labCurve.enable_saturationlimiter && p.labCurve.enable_saturationlimiter == other.labCurve.enable_saturationlimiter; labCurve.saturationlimit = labCurve.saturationlimit && p.labCurve.saturationlimit == other.labCurve.saturationlimit; sharpenEdge.enabled = sharpenEdge.enabled && p.sharpenEdge.enabled == other.sharpenEdge.enabled; @@ -242,6 +249,13 @@ void ParamsEdited::initFrom (const std::vector sharpening.deconvradius = sharpening.deconvradius && p.sharpening.deconvradius == other.sharpening.deconvradius; sharpening.deconviter = sharpening.deconviter && p.sharpening.deconviter == other.sharpening.deconviter; sharpening.deconvdamping = sharpening.deconvdamping && p.sharpening.deconvdamping == other.sharpening.deconvdamping; + vibrance.enabled = vibrance.enabled && p.vibrance.enabled == other.vibrance.enabled; + vibrance.pastels = vibrance.pastels && p.vibrance.pastels == other.vibrance.pastels; + vibrance.saturated = vibrance.saturated && p.vibrance.saturated == other.vibrance.saturated; + vibrance.psthreshold = vibrance.psthreshold && p.vibrance.psthreshold == other.vibrance.psthreshold; + vibrance.protectskins = vibrance.protectskins && p.vibrance.protectskins == other.vibrance.protectskins; + vibrance.avoidcolorshift = vibrance.avoidcolorshift && p.vibrance.avoidcolorshift == other.vibrance.avoidcolorshift; + vibrance.pastsattog = vibrance.pastsattog && p.vibrance.pastsattog == other.vibrance.pastsattog; colorBoost.amount = colorBoost.amount && p.colorBoost.amount == other.colorBoost.amount; colorBoost.avoidclip = colorBoost.avoidclip && p.colorBoost.avoidclip == other.colorBoost.avoidclip; colorBoost.enable_saturationlimiter = colorBoost.enable_saturationlimiter && p.colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter; @@ -259,7 +273,7 @@ void ParamsEdited::initFrom (const std::vector defringe.enabled = defringe.enabled && p.defringe.enabled == other.defringe.enabled; defringe.radius = defringe.radius && p.defringe.radius == other.defringe.radius; defringe.threshold = defringe.threshold && p.defringe.threshold == other.defringe.threshold; - + impulseDenoise.enabled = impulseDenoise.enabled && p.impulseDenoise.enabled == other.impulseDenoise.enabled; impulseDenoise.thresh = impulseDenoise.thresh && p.impulseDenoise.thresh == other.impulseDenoise.thresh; @@ -390,7 +404,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (labCurve.saturationlimit) toEdit.labCurve.saturationlimit = mods.labCurve.saturationlimit; if (sharpenEdge.enabled) toEdit.sharpenEdge.enabled = mods.sharpenEdge.enabled; if (sharpenEdge.passes) toEdit.sharpenEdge.passes = dontforceSet && options.baBehav[ADDSET_SHARPENEDGE_PASS] ? toEdit.sharpenEdge.passes + mods.sharpenEdge.passes : mods.sharpenEdge.passes; - if (sharpenEdge.amount) toEdit.sharpenEdge.amount = dontforceSet && options.baBehav[ADDSET_SHARPENEDGE_AMOUNT] ? toEdit.sharpenEdge.amount + mods.sharpenEdge.amount : mods.sharpenEdge.amount; + if (sharpenEdge.amount) toEdit.sharpenEdge.amount = dontforceSet && options.baBehav[ADDSET_SHARPENEDGE_AMOUNT] ? toEdit.sharpenEdge.amount + mods.sharpenEdge.amount : mods.sharpenEdge.amount; if (sharpenEdge.threechannels) toEdit.sharpenEdge.threechannels = mods.sharpenEdge.threechannels; if (sharpenMicro.enabled) toEdit.sharpenMicro.enabled = mods.sharpenMicro.enabled; if (sharpenMicro.matrix) toEdit.sharpenMicro.matrix = mods.sharpenMicro.matrix; @@ -402,15 +416,22 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (sharpening.threshold) toEdit.sharpening.threshold = mods.sharpening.threshold; if (sharpening.edgesonly) toEdit.sharpening.edgesonly = mods.sharpening.edgesonly; if (sharpening.edges_radius) toEdit.sharpening.edges_radius = mods.sharpening.edges_radius; - if (sharpening.edges_tolerance) toEdit.sharpening.edges_tolerance = mods.sharpening.edges_tolerance; - if (sharpening.halocontrol) toEdit.sharpening.halocontrol = mods.sharpening.halocontrol; - if (sharpening.halocontrol_amount) toEdit.sharpening.halocontrol_amount = mods.sharpening.halocontrol_amount; - if (sharpening.method) toEdit.sharpening.method = mods.sharpening.method; + if (sharpening.edges_tolerance) toEdit.sharpening.edges_tolerance = mods.sharpening.edges_tolerance; + if (sharpening.halocontrol) toEdit.sharpening.halocontrol = mods.sharpening.halocontrol; + if (sharpening.halocontrol_amount) toEdit.sharpening.halocontrol_amount = mods.sharpening.halocontrol_amount; + if (sharpening.method) toEdit.sharpening.method = mods.sharpening.method; if (sharpening.deconvamount) toEdit.sharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.deconvamount + mods.sharpening.deconvamount : mods.sharpening.deconvamount; if (sharpening.deconvradius) toEdit.sharpening.deconvradius = mods.sharpening.deconvradius; if (sharpening.deconviter) toEdit.sharpening.deconviter = mods.sharpening.deconviter; - if (sharpening.deconvdamping) toEdit.sharpening.deconvdamping = mods.sharpening.deconvdamping; - if (colorBoost.amount) toEdit.colorBoost.amount = dontforceSet && options.baBehav[ADDSET_CBOOST_AMOUNT] ? toEdit.colorBoost.amount + mods.colorBoost.amount : mods.colorBoost.amount; + if (sharpening.deconvdamping) toEdit.sharpening.deconvdamping = mods.sharpening.deconvdamping; + if (vibrance.enabled) toEdit.vibrance.enabled = mods.vibrance.enabled; + if (vibrance.pastels) toEdit.vibrance.pastels = dontforceSet && options.baBehav[ADDSET_VIBRANCE_PASTELS] ? toEdit.vibrance.pastels + mods.vibrance.pastels : mods.vibrance.pastels; + if (vibrance.saturated) toEdit.vibrance.saturated = dontforceSet && options.baBehav[ADDSET_VIBRANCE_SATURATED] ? toEdit.vibrance.saturated + mods.vibrance.saturated : mods.vibrance.saturated; + if (vibrance.psthreshold) toEdit.vibrance.psthreshold = dontforceSet && options.baBehav[ADDSET_VIBRANCE_PSTHRESHOLD] ? toEdit.vibrance.psthreshold + mods.vibrance.psthreshold : mods.vibrance.psthreshold; + if (vibrance.protectskins) toEdit.vibrance.protectskins = mods.vibrance.protectskins; + if (vibrance.avoidcolorshift) toEdit.vibrance.avoidcolorshift = mods.vibrance.avoidcolorshift; + if (vibrance.pastsattog) toEdit.vibrance.pastsattog = mods.vibrance.pastsattog; + if (colorBoost.amount) toEdit.colorBoost.amount = dontforceSet && options.baBehav[ADDSET_CBOOST_AMOUNT] ? toEdit.colorBoost.amount + mods.colorBoost.amount : mods.colorBoost.amount; if (colorBoost.avoidclip) toEdit.colorBoost.avoidclip = mods.colorBoost.avoidclip; if (colorBoost.enable_saturationlimiter)toEdit.colorBoost.enable_saturationlimiter = mods.colorBoost.enable_saturationlimiter; if (colorBoost.saturationlimit) toEdit.colorBoost.saturationlimit = mods.colorBoost.saturationlimit; @@ -428,7 +449,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (defringe.enabled) toEdit.defringe.enabled = mods.defringe.enabled; if (defringe.radius) toEdit.defringe.radius = mods.defringe.radius; if (defringe.threshold) toEdit.defringe.threshold = mods.defringe.threshold; - + if (impulseDenoise.enabled) toEdit.impulseDenoise.enabled = mods.impulseDenoise.enabled; if (impulseDenoise.thresh) toEdit.impulseDenoise.thresh = mods.impulseDenoise.thresh; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index b7a0278b9..c12f49c47 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -91,6 +91,18 @@ class SharpeningParamsEdited { bool deconvdamping; }; +class VibranceParamsEdited { + + public: + bool enabled; + bool pastels; + bool saturated; + bool psthreshold; + bool protectskins; + bool avoidcolorshift; + bool pastsattog; +}; + class ColorBoostParamsEdited { public: @@ -342,6 +354,7 @@ class ParamsEdited { SharpeningParamsEdited sharpening; SharpenEdgeParamsEdited sharpenEdge; SharpenMicroParamsEdited sharpenMicro; + VibranceParamsEdited vibrance; ColorBoostParamsEdited colorBoost; WBParamsEdited wb; ColorShiftParamsEdited colorShift; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index 4f9654759..6c3354126 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -58,7 +58,8 @@ PartialPasteDlg::PartialPasteDlg () { defringe = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DEFRINGE"))); // options in color: - chmixer = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CHANNELMIXER"))); + vibrance = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_VIBRANCE"))); + chmixer = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CHANNELMIXER"))); dirpyrden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DIRPYRDENOISE"))); hsveq = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_HSVEQUALIZER"))); @@ -133,6 +134,7 @@ PartialPasteDlg::PartialPasteDlg () { vboxes[2]->pack_start (*color, Gtk::PACK_SHRINK, 2); vboxes[2]->pack_start (*hseps[2], Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*vibrance, Gtk::PACK_SHRINK, 2); vboxes[2]->pack_start (*chmixer, Gtk::PACK_SHRINK, 2); vboxes[2]->pack_start (*hsveq, Gtk::PACK_SHRINK, 2); @@ -242,7 +244,8 @@ PartialPasteDlg::PartialPasteDlg () { //waveqConn = waveq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true)); defringeConn = defringe->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true)); - chmixerConn = chmixer->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + vibranceConn = vibrance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + chmixerConn = chmixer->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); hsveqConn = hsveq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); distortionConn = distortion->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true)); @@ -453,14 +456,17 @@ void PartialPasteDlg::detailToggled () { void PartialPasteDlg::colorToggled () { + vibranceConn.block (true); chmixerConn.block (true); hsveqConn.block (true); color->set_inconsistent (false); + vibrance->set_active (color->get_active ()); chmixer->set_active (color->get_active ()); hsveq->set_active (color->get_active ()); + vibranceConn.block (false); chmixerConn.block (false); hsveqConn.block (false); } @@ -542,7 +548,8 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dst, const r if (defringe->get_active ()) dst->defringe = src->defringe; if (dirpyrden->get_active ()) dst->dirpyrDenoise = src->dirpyrDenoise; - if (chmixer->get_active ()) dst->chmixer = src->chmixer; + if (vibrance->get_active ()) dst->vibrance = src->vibrance; + if (chmixer->get_active ()) dst->chmixer = src->chmixer; if (hsveq->get_active ()) dst->hsvequalizer = src->hsvequalizer; if (distortion->get_active ()) dst->distortion = src->distortion; if (cacorr->get_active ()) dst->cacorrection = src->cacorrection; diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h index ae1aea738..b200fa35e 100644 --- a/rtgui/partialpastedlg.h +++ b/rtgui/partialpastedlg.h @@ -55,6 +55,7 @@ class PartialPasteDlg : public Gtk::Dialog { Gtk::CheckButton* dirpyreq; // options in color: + Gtk::CheckButton* vibrance; Gtk::CheckButton* chmixer; Gtk::CheckButton* hsveq; @@ -103,7 +104,7 @@ class PartialPasteDlg : public Gtk::Dialog { sigc::connection wbConn, exposureConn, hlrecConn, shConn, labcurveConn; sigc::connection sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, waveqConn, defringeConn, dirpyreqConn; - sigc::connection chmixerConn, hsveqConn; + sigc::connection vibranceConn, chmixerConn, hsveqConn; sigc::connection distortionConn, cacorrConn, vignettingConn; sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, perspectiveConn, commonTransConn; sigc::connection exifchConn, iptcConn, icmConn; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 4a1b5b6b6..f13ef26e1 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -189,6 +189,12 @@ Gtk::Widget* Preferences::getBatchProcPanel () { appendBehavList (mi, M("TP_WBALANCE_TEMPERATURE"), ADDSET_WB_TEMPERATURE, true); appendBehavList (mi, M("TP_WBALANCE_GREEN"), ADDSET_WB_GREEN, true); + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_VIBRANCE_LABEL")); + appendBehavList (mi, M("TP_VIBRANCE_PASTELS"), ADDSET_VIBRANCE_PASTELS, false); + appendBehavList (mi, M("TP_VIBRANCE_SATURATED"), ADDSET_VIBRANCE_SATURATED, false); + appendBehavList (mi, M("TP_VIBRANCE_PSTHRESHOLD"), ADDSET_VIBRANCE_PSTHRESHOLD, false); + mi = behModel->append (); mi->set_value (behavColumns.label, M("TP_CHMIXER_LABEL")); appendBehavList (mi, M("TP_CHMIXER_RED")+", "+M("TP_CHMIXER_GREEN")+", "+M("TP_CHMIXER_BLUE"), ADDSET_CHMIXER, false); diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index e4e3dcc30..767e4dac4 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -52,6 +52,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { lensgeom = Gtk::manage (new LensGeometry ()); distortion = Gtk::manage (new Distortion ()); rotate = Gtk::manage (new Rotate ()); + vibrance = Gtk::manage (new Vibrance ()); whitebalance = Gtk::manage (new WhiteBalance ()); vignetting = Gtk::manage (new Vignetting ()); perspective = Gtk::manage (new PerspCorrection ()); @@ -75,6 +76,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { addPanel (colorPanel, whitebalance, M("TP_WBALANCE_LABEL")); toolPanels.push_back (whitebalance); addPanel (exposurePanel, toneCurve, M("TP_EXPOSURE_LABEL")); toolPanels.push_back (toneCurve); addPanel (exposurePanel, hlrecovery, M("TP_HLREC_LABEL")); toolPanels.push_back (hlrecovery); + addPanel (colorPanel, vibrance, M("TP_VIBRANCE_LABEL")); toolPanels.push_back (vibrance); addPanel (colorPanel, chmixer, M("TP_CHMIXER_LABEL")); toolPanels.push_back (chmixer); addPanel (exposurePanel, shadowshighlights, M("TP_SHADOWSHLIGHTS_LABEL")); toolPanels.push_back (shadowshighlights); addPanel (detailsPanel, sharpening, M("TP_SHARPENING_LABEL")); toolPanels.push_back (sharpening); diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index e4a158557..e5ff5f23b 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,7 @@ class ToolPanelCoordinator : public ToolPanelListener, PerspCorrection* perspective; CACorrection* cacorrection; HLRecovery* hlrecovery; + Vibrance* vibrance; ChMixer* chmixer; Resize* resize; ICMPanel* icm; diff --git a/rtgui/vibrance.cc b/rtgui/vibrance.cc new file mode 100644 index 000000000..0df764413 --- /dev/null +++ b/rtgui/vibrance.cc @@ -0,0 +1,294 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ + +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +Vibrance::Vibrance () : Gtk::VBox(), FoldableToolPanel(this) { + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + pack_start(*enabled, Gtk::PACK_SHRINK, 0); + + pastels = Gtk::manage(new Adjuster (M("TP_VIBRANCE_PASTELS"),-100,100,5,0)); + pastels->setAdjusterListener (this); + //if (pastels->delay < 1000) pastels->delay = 1000; + pack_start( *pastels, Gtk::PACK_SHRINK, 0); + + saturated = Gtk::manage(new Adjuster (M("TP_VIBRANCE_SATURATED"),-100,100,5,0)); + saturated->setAdjusterListener (this); + saturated->set_sensitive(false); + //if (saturated->delay < 1000) saturated->delay = 1000; + pack_start( *saturated, Gtk::PACK_SHRINK, 0); + + psThreshold = Gtk::manage(new Adjuster (M("TP_VIBRANCE_PSTHRESHOLD"),0,100,5,75)); + psThreshold->setAdjusterListener (this); + psThreshold->set_sensitive(false); + //if (psThreshold->delay < 1000) psThreshold->delay = 1000; + pack_start( *psThreshold, Gtk::PACK_SHRINK, 0); + + protectSkins = Gtk::manage (new Gtk::CheckButton (M("TP_VIBRANCE_PROTECTSKINS"))); + protectSkins->set_active (true); + pack_start(*protectSkins, Gtk::PACK_SHRINK, 0); + + avoidColorShift = Gtk::manage (new Gtk::CheckButton (M("TP_VIBRANCE_AVOIDCOLORSHIFT"))); + avoidColorShift->set_active (true); + pack_start(*avoidColorShift, Gtk::PACK_SHRINK, 0); + + pastSatTog = Gtk::manage (new Gtk::CheckButton (M("TP_VIBRANCE_PASTSATTOG"))); + pastSatTog->set_active (true); + pack_start(*pastSatTog, Gtk::PACK_SHRINK, 0); + + show (); + + enaconn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::enabled_toggled) ); + pskinsconn = protectSkins->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::protectskins_toggled) ); + ashiftconn = avoidColorShift->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::avoidcolorshift_toggled) ); + pastsattogconn = pastSatTog->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::pastsattog_toggled) ); +} + +void Vibrance::read(const ProcParams* pp, const ParamsEdited* pedited) { + disableListener (); + + if(pedited ){ + enabled->set_inconsistent (!pedited->vibrance.enabled); + pastels->setEditedState (pedited->vibrance.pastels ? Edited : UnEdited); + saturated->setEditedState (pedited->vibrance.saturated ? Edited : UnEdited); + psThreshold->setEditedState (pedited->vibrance.psthreshold ? Edited : UnEdited); + protectSkins->set_inconsistent (!pedited->vibrance.protectskins); + avoidColorShift->set_inconsistent (!pedited->vibrance.avoidcolorshift); + pastSatTog->set_inconsistent (!pedited->vibrance.pastsattog); + } + + enaconn.block (true); + enabled->set_active (pp->vibrance.enabled); + enaconn.block (false); + lastEnabled = pp->vibrance.enabled; + + pskinsconn.block (true); + protectSkins->set_active (pp->vibrance.protectskins); + pskinsconn.block (false); + lastProtectSkins = pp->vibrance.protectskins; + + ashiftconn.block (true); + avoidColorShift->set_active (pp->vibrance.avoidcolorshift); + ashiftconn.block (false); + lastAvoidColorShift = pp->vibrance.avoidcolorshift; + + pastsattogconn.block (true); + pastSatTog->set_active (pp->vibrance.pastsattog); + pastsattogconn.block (false); + lastPastSatTog = pp->vibrance.pastsattog; + + pastels->setValue (pp->vibrance.pastels); + psThreshold->setValue (pp->vibrance.psthreshold); + + if (lastPastSatTog) { + // Link both slider, so we set saturated and psThresholds unsensitive + psThreshold->set_sensitive(false); + saturated->set_sensitive(false); + saturated->setValue (pp->vibrance.pastels); // Pastels and Saturated are linked + } + else { + // Separate sliders, so we set saturated and psThresholds sensitive again + psThreshold->set_sensitive(true); + saturated->set_sensitive(true); + saturated->setValue (pp->vibrance.saturated); // Pastels and Saturated are separate + } + + enableListener (); +} + +void Vibrance::write( ProcParams* pp, ParamsEdited* pedited) { + pp->vibrance.enabled = enabled->get_active (); + pp->vibrance.pastels = pastels->getIntValue(); + pp->vibrance.saturated = pastSatTog->get_active() ? pp->vibrance.pastels : saturated->getIntValue (); + pp->vibrance.psthreshold = psThreshold->getIntValue (); + pp->vibrance.protectskins = protectSkins->get_active (); + pp->vibrance.avoidcolorshift = avoidColorShift->get_active (); + pp->vibrance.pastsattog = pastSatTog->get_active (); + + if (pedited) { + pedited->vibrance.enabled = !enabled->get_inconsistent(); + pedited->vibrance.pastels = pastels->getEditedState (); + pedited->vibrance.saturated = saturated->getEditedState (); + pedited->vibrance.psthreshold = psThreshold->getEditedState (); + pedited->vibrance.protectskins = !protectSkins->get_inconsistent(); + pedited->vibrance.avoidcolorshift = !avoidColorShift->get_inconsistent(); + pedited->vibrance.pastsattog = !pastSatTog->get_inconsistent(); + } + +} + +void Vibrance::enabled_toggled () { + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaconn.block (true); + enabled->set_active (false); + enaconn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvVibranceEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvVibranceEnabled, M("GENERAL_DISABLED")); + } +} + +void Vibrance::protectskins_toggled () { + if (batchMode) { + if (protectSkins->get_inconsistent()) { + protectSkins->set_inconsistent (false); + pskinsconn.block (true); + protectSkins->set_active (false); + pskinsconn.block (false); + } + else if (lastProtectSkins) + protectSkins->set_inconsistent (true); + + lastProtectSkins = protectSkins->get_active (); + } + + if (listener && enabled->get_active()) { + if (protectSkins->get_active ()) + listener->panelChanged (EvVibranceProtectSkins, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvVibranceProtectSkins, M("GENERAL_DISABLED")); + } +} + +void Vibrance::avoidcolorshift_toggled () { + if (batchMode) { + if (avoidColorShift->get_inconsistent()) { + avoidColorShift->set_inconsistent (false); + ashiftconn.block (true); + avoidColorShift->set_active (false); + ashiftconn.block (false); + } + else if (lastAvoidColorShift) + avoidColorShift->set_inconsistent (true); + + lastAvoidColorShift = avoidColorShift->get_active (); + } + + if (listener && enabled->get_active()) { + if (avoidColorShift->get_active ()) + listener->panelChanged (EvVibranceAvoidColorShift, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvVibranceAvoidColorShift, M("GENERAL_DISABLED")); + } +} + +void Vibrance::pastsattog_toggled () { + if (batchMode) { + if (pastSatTog->get_inconsistent()) { + pastSatTog->set_inconsistent (false); + pastsattogconn.block (true); + pastSatTog->set_active (false); + pastsattogconn.block (false); + } + else if (lastPastSatTog) + pastSatTog->set_inconsistent (true); + + lastPastSatTog = pastSatTog->get_active (); + } + + if (pastSatTog->get_active()) { + // Link both slider, so we set saturated and psThresholds unsensitive + psThreshold->set_sensitive(false); + saturated->set_sensitive(false); + saturated->setValue (pastels->getValue()); // Pastels and Saturated are linked + } + else { + // Separate sliders, so we set saturated and psThresholds sensitive again + psThreshold->set_sensitive(true); + saturated->set_sensitive(true); + } + + if (listener && enabled->get_active()) { + if (pastSatTog->get_active ()) { + listener->panelChanged (EvVibrancePastSatTog, M("GENERAL_ENABLED")); + } + else + listener->panelChanged (EvVibrancePastSatTog, M("GENERAL_DISABLED")); + } +} + +void Vibrance::adjusterChanged (Adjuster* a, double newval) { + if (a == pastels && pastSatTog->get_active()) + saturated->setValue (newval); + + if (listener && enabled->get_active()) { + Glib::ustring value = a->getTextValue(); + + if (a == pastels ) + listener->panelChanged (EvVibrancePastels, value ); + else if (a == saturated && !pastSatTog->get_active()) + listener->panelChanged (EvVibranceSaturated, value ); + else if (a == psThreshold){ + listener->panelChanged (EvVibrancePastSatThreshold, value ); + } + } +} + +void Vibrance::setBatchMode(bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + + pastels->showEditedCB (); + saturated->showEditedCB (); + psThreshold->showEditedCB (); +} + +void Vibrance::setDefaults(const ProcParams* defParams, const ParamsEdited* pedited) { + pastels->setDefault (defParams->vibrance.pastels); + saturated->setDefault (defParams->vibrance.saturated); + psThreshold->setDefault (defParams->vibrance.psthreshold); + + if (pedited) { + pastels->setDefaultEditedState (pedited->vibrance.pastels ? Edited : UnEdited); + saturated->setDefaultEditedState (pedited->vibrance.saturated ? Edited : UnEdited); + psThreshold->setDefaultEditedState (pedited->vibrance.psthreshold ? Edited : UnEdited); + + } else { + pastels->setDefaultEditedState (Irrelevant); + saturated->setDefaultEditedState (Irrelevant); + psThreshold->setDefaultEditedState (Irrelevant); + } +} + +void Vibrance::setAdjusterBehavior (bool pastelsadd, bool saturatedadd, bool psthreshdadd) { + pastels->setAddMode (pastelsadd); + saturated->setAddMode (saturatedadd); + psThreshold->setAddMode (psthreshdadd); +} + +void Vibrance::trimValues (ProcParams* pp) { + pastels->trimValue (pp->vibrance.pastels); + saturated->trimValue (pp->vibrance.saturated); + psThreshold->trimValue (pp->vibrance.psthreshold); +} diff --git a/rtgui/vibrance.h b/rtgui/vibrance.h new file mode 100644 index 000000000..c0fcfa74a --- /dev/null +++ b/rtgui/vibrance.h @@ -0,0 +1,66 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _VIBRANCE_ +#define _VIBRANCE_ + +#include +#include +//#include +#include + +class Vibrance : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + +protected: + Gtk::CheckButton* enabled; + Adjuster* pastels; + Adjuster* saturated; + Adjuster* psThreshold; + Gtk::CheckButton* protectSkins; + Gtk::CheckButton* avoidColorShift; + Gtk::CheckButton* pastSatTog; + bool lastEnabled; + bool lastProtectSkins; + bool lastAvoidColorShift; + bool lastPastSatTog; + + sigc::connection enaconn; + sigc::connection pskinsconn; + sigc::connection ashiftconn; + sigc::connection pastsattogconn; + +public: + + Vibrance (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void trimValues (rtengine::procparams::ProcParams* pp); + void setAdjusterBehavior (bool amountadd, bool passadd, bool psthreshdadd); + void adjusterChanged (Adjuster* a, double newval); + + void enabled_toggled (); + void protectskins_toggled (); + void avoidcolorshift_toggled (); + void pastsattog_toggled (); +}; + + +#endif