diff --git a/About-Apple.cmake b/About-Apple.cmake index 23307b125..22a02aa1a 100644 --- a/About-Apple.cmake +++ b/About-Apple.cmake @@ -3,6 +3,16 @@ string (TOUPPER ${BUILD_TYPE} UPPER_CMAKE_BUILD_TYPE) +# wee look for the hg command in this paths by order of preference +find_file(HG_CMD hg PATHS "/opt/local/bin" "/usr/local/bin" "/usr/bin") +find_file(HG_CMD hg) + +if (HG_CMD STREQUAL HG_CMD-NOTFOUND) + message(FATAL_ERROR "hg command not found!") +else (HG_CMD STREQUAL HG_CMD-NOTFOUND) + message(STATUS "hg command found: ${HG_CMD}") +endif (HG_CMD STREQUAL HG_CMD-NOTFOUND) + set (OUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/AboutThisBuild.txt") set (VERSION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/rtgui/version.h") set (SHELL "/bin/bash") @@ -11,8 +21,8 @@ set (SHELL "/bin/bash") add_custom_target (AboutFile ALL COMMAND rm -f ${OUT_FILE} COMMAND rm -f ${VERSION_FILE} - COMMAND for i in \$\( hg branch \)\; do echo Branch: $i >${OUT_FILE}\; done - COMMAND hg parents --template=\"Version: {latesttag}.{latesttagdistance}\\nChangset: {node|short}\\n\" >>${OUT_FILE} + COMMAND for i in \$\( ${HG_CMD} -R \"${CMAKE_CURRENT_SOURCE_DIR}\" branch \)\; do echo Branch: $i >${OUT_FILE}\; done + COMMAND ${HG_CMD} -R \"${CMAKE_CURRENT_SOURCE_DIR}\" parents --template=\"Version: {latesttag}.{latesttagdistance}\\nChangset: {node|short}\\n\" >>${OUT_FILE} COMMAND for i in \$\( gcc -dumpversion \) \;do echo Compiler: GCC $i >>${OUT_FILE} \; done COMMAND echo Processor: ${PROC_LABEL} >>${OUT_FILE} COMMAND echo Bit depth: ${PROC_BIT_DEPTH} >>${OUT_FILE} @@ -22,6 +32,6 @@ add_custom_target (AboutFile ALL COMMAND if [ \"${OPTION_OMP}\" = \"ON\" ] \; then echo OpenMP support: Yes >>${OUT_FILE} \;else echo OpenMP support: No >>${OUT_FILE} \;fi COMMAND if [ \"${WITH_MYFILE_MMAP}\" = \"ON\" ] \; then echo MMAP support: Yes >>${OUT_FILE} \; else echo MMAP support: No >>${OUT_FILE} \;fi COMMAND if [ \"${WITH_RAWZOR}\" = \"ON\" ] \; then echo Rawzor support: Yes >>${OUT_FILE} \;else echo Rawzor support: No >>${OUT_FILE} \;fi - COMMAND hg parents --template=\"// This file is automatically generated by the Makefile \; DO NOT EDIT!\\n// You can \(should\) also tell mercurial to ignore it.\\n\\n\#ifndef _VERSION_\\n\#define _VERSION_\\n\\n\#define VERSION \\"{latesttag}.{latesttagdistance}\\"\\n\#define TAGDISTANCE {latesttagdistance}\\n\\n\#endif\\n\" >${VERSION_FILE} + COMMAND ${HG_CMD} -R \"${CMAKE_CURRENT_SOURCE_DIR}\" parents --template=\"// This file is automatically generated by the Makefile \; DO NOT EDIT!\\n// You can \(should\) also tell mercurial to ignore it.\\n\\n\#ifndef _VERSION_\\n\#define _VERSION_\\n\\n\#define VERSION \\"{latesttag}.{latesttagdistance}\\"\\n\#define TAGDISTANCE {latesttagdistance}\\n\\n\#endif\\n\" >${VERSION_FILE} COMMENT "Creating the about file" ) diff --git a/AboutThisBuild.txt b/AboutThisBuild.txt index 3a88744d5..d2ae68a46 100644 --- a/AboutThisBuild.txt +++ b/AboutThisBuild.txt @@ -1,5 +1,5 @@ -Version: release-3.0-a1.669 -Changset: 92cd1a6ffc04 +Version: release-3.0-a1.671 +Changset: 965e55a4a9d9 Processor: undefined Bit depth: 64 bits Gtkmm: V2.22.0 diff --git a/rtdata/languages/default b/rtdata/languages/default index fff78e3c8..d636ca9b5 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -754,7 +754,7 @@ TP_LABCURVE_BRIGHTNESS;Brightness TP_LABCURVE_CONTRAST;Contrast TP_LABCURVE_CURVEEDITOR;Luminance Curve TP_LABCURVE_ENABLESATLIMITER;Enable saturation limiter -TP_LABCURVE_LABEL;Lab Curves +TP_LABCURVE_LABEL;Lab Adjustments TP_LABCURVE_SATLIMIT;Saturation limit TP_LABCURVE_SATURATION;Saturation TP_LENSGEOM_AUTOCROP;Auto Crop diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index 07f1899f7..8403c8adf 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -372,14 +372,6 @@ void RawImageSource::CA_correct_RT(double cared, double cablue) { fabs((rgb[indx-4][1]-rgb[indx-4][c])-(rgb[indx][1]-rgb[indx][c])) - \ fabs((rgb[indx-4][1]-rgb[indx-4][c])-(rgb[indx+4][1]-rgb[indx+4][c]))); - /*ghpfv = fabs(fabs(rgb[indx][1]-rgb[indx+v4][1])+fabs(rgb[indx][1]-rgb[indx-v4][1]) - \ - fabs(rgb[indx+v4][1]-rgb[indx-v4][1])); - ghpfh = fabs(fabs(rgb[indx][1]-rgb[indx+4][1])+fabs(rgb[indx][1]-rgb[indx-4][1]) - \ - fabs(rgb[indx+4][1]-rgb[indx-4][1])); - rbhpfv[indx] = fabs(ghpfv - fabs(fabs(rgb[indx][c]-rgb[indx+v4][c])+fabs(rgb[indx][c]-rgb[indx-v4][c]) - \ - fabs(rgb[indx+v4][c]-rgb[indx-v4][c]))); - rbhpfh[indx] = fabs(ghpfh - fabs(fabs(rgb[indx][c]-rgb[indx+4][c])+fabs(rgb[indx][c]-rgb[indx-4][c]) - \ - fabs(rgb[indx+4][c]-rgb[indx-4][c])));*/ glpfv = 0.25*(2*rgb[indx][1]+rgb[indx+v2][1]+rgb[indx-v2][1]); glpfh = 0.25*(2*rgb[indx][1]+rgb[indx+2][1]+rgb[indx-2][1]); @@ -408,7 +400,7 @@ void RawImageSource::CA_correct_RT(double cared, double cablue) { coeff[0][0][c] += gradwt*deltgrb*deltgrb; coeff[0][1][c] += gradwt*gdiff*deltgrb; coeff[0][2][c] += gradwt*gdiff*gdiff; - areawt[0][c]+=1; + areawt[0][c]++; //horizontal @@ -420,7 +412,7 @@ void RawImageSource::CA_correct_RT(double cared, double cablue) { coeff[1][0][c] += gradwt*deltgrb*deltgrb; coeff[1][1][c] += gradwt*gdiff*deltgrb; coeff[1][2][c] += gradwt*gdiff*gdiff; - areawt[1][c]+=1; + areawt[1][c]++; // In Mathematica, @@ -430,68 +422,7 @@ void RawImageSource::CA_correct_RT(double cared, double cablue) { } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - /* - for (rr=4; rr < rr1-4; rr++) - for (cc=4+(FC(rr,2)&1), indx=rr*TS+cc, c = FC(rr,cc); cc < cc1-4; cc+=2, indx+=2) { - - - rbhpfv[indx] = SQR(fabs((rgb[indx][1]-rgb[indx][c])-(rgb[indx+v4][1]-rgb[indx+v4][c])) + \ - fabs((rgb[indx-v4][1]-rgb[indx-v4][c])-(rgb[indx][1]-rgb[indx][c])) - \ - fabs((rgb[indx-v4][1]-rgb[indx-v4][c])-(rgb[indx+v4][1]-rgb[indx+v4][c]))); - rbhpfh[indx] = SQR(fabs((rgb[indx][1]-rgb[indx][c])-(rgb[indx+4][1]-rgb[indx+4][c])) + \ - fabs((rgb[indx-4][1]-rgb[indx-4][c])-(rgb[indx][1]-rgb[indx][c])) - \ - fabs((rgb[indx-4][1]-rgb[indx-4][c])-(rgb[indx+4][1]-rgb[indx+4][c]))); - - - glpfv = 0.25*(2*rgb[indx][1]+rgb[indx+v2][1]+rgb[indx-v2][1]); - glpfh = 0.25*(2*rgb[indx][1]+rgb[indx+2][1]+rgb[indx-2][1]); - rblpfv[indx] = eps+fabs(glpfv - 0.25*(2*rgb[indx][c]+rgb[indx+v2][c]+rgb[indx-v2][c])); - rblpfh[indx] = eps+fabs(glpfh - 0.25*(2*rgb[indx][c]+rgb[indx+2][c]+rgb[indx-2][c])); - grblpfv[indx] = glpfv + 0.25*(2*rgb[indx][c]+rgb[indx+v2][c]+rgb[indx-v2][c]); - grblpfh[indx] = glpfh + 0.25*(2*rgb[indx][c]+rgb[indx+2][c]+rgb[indx-2][c]); - } - - for (c=0;c<3;c++) {areawt[0][c]=areawt[1][c]=0;} - - // along line segments, find the point along each segment that minimizes the color variance - // averaged over the tile; evaluate for up/down and left/right away from R/B grid point - for (rr=rrmin+8; rr < rrmax-8; rr++) - for (cc=ccmin+8+(FC(rr,2)&1), indx=rr*TS+cc, c = FC(rr,cc); cc < ccmax-8; cc+=2, indx+=2) { - - if (rgb[indx][c]>0.8*clip_pt || Gtmp[indx]>0.8*clip_pt) continue; - - //in linear interpolation, color differences are a quadratic function of interpolation position; - //solve for the interpolation position that minimizes color difference variance over the tile - - //vertical - gdiff=0.3125*(rgb[indx+TS][1]-rgb[indx-TS][1])+0.09375*(rgb[indx+TS+1][1]-rgb[indx-TS+1][1]+rgb[indx+TS-1][1]-rgb[indx-TS-1][1]); - deltgrb=(rgb[indx][c]-rgb[indx][1])-0.5*((rgb[indx-v4][c]-rgb[indx-v4][1])+(rgb[indx+v4][c]-rgb[indx+v4][1])); - - gradwt=fabs(0.25*rbhpfv[indx]+0.125*(rbhpfv[indx+2]+rbhpfv[indx-2]) );//*(grblpfv[indx-v2]+grblpfv[indx+v2])/(eps+0.1*grblpfv[indx-v2]+rblpfv[indx-v2]+0.1*grblpfv[indx+v2]+rblpfv[indx+v2]); - if (gradwt>eps) { - coeff[0][0][c] += gradwt*deltgrb*deltgrb; - coeff[0][1][c] += gradwt*gdiff*deltgrb; - coeff[0][2][c] += gradwt*gdiff*gdiff; - areawt[0][c]++; - } - - //horizontal - gdiff=0.3125*(rgb[indx+1][1]-rgb[indx-1][1])+0.09375*(rgb[indx+1+TS][1]-rgb[indx-1+TS][1]+rgb[indx+1-TS][1]-rgb[indx-1-TS][1]); - deltgrb=(rgb[indx][c]-rgb[indx][1])-0.5*((rgb[indx-4][c]-rgb[indx-4][1])+(rgb[indx+4][c]-rgb[indx+4][1])); - - gradwt=fabs(0.25*rbhpfh[indx]+0.125*(rbhpfh[indx+v2]+rbhpfh[indx-v2]) );//*(grblpfh[indx-2]+grblpfh[indx+2])/(eps+0.1*grblpfh[indx-2]+rblpfh[indx-2]+0.1*grblpfh[indx+2]+rblpfh[indx+2]); - if (gradwt>eps) { - coeff[1][0][c] += gradwt*deltgrb*deltgrb; - coeff[1][1][c] += gradwt*gdiff*deltgrb; - coeff[1][2][c] += gradwt*gdiff*gdiff; - areawt[1][c]++; - } - - // In Mathematica, - // f[x_]=Expand[Total[Flatten[ - // ((1-x) RotateLeft[Gint,shift1]+x RotateLeft[Gint,shift2]-cfapad)^2[[dv;;-1;;2,dh;;-1;;2]]]]]; - // extremum = -.5Coefficient[f[x],x]/Coefficient[f[x],x^2] - }*/ + for (c=0; c<3; c+=2){ for (j=0; j<2; j++) {// vert/hor //printf("hblock %d vblock %d j %d c %d areawt %d \n",hblock,vblock,j,c,areawt[j][c]); @@ -518,7 +449,7 @@ void RawImageSource::CA_correct_RT(double cared, double cablue) { if (fabs(CAshift[j][c])<2.0) { blockave[j][c] += CAshift[j][c]; blocksqave[j][c] += SQR(CAshift[j][c]); - blockdenom[j][c] += 1; + blockdenom[j][c] ++; } }//vert/hor }//color diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 2073e33a6..39c5bfe1e 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -302,7 +302,7 @@ void Curve::getVal (const std::vector& t, std::vector& res) { } -void CurveFactory::complexsgnCurve (double saturation, const std::vector& curvePoints, float* outCurve, int skip) { +void CurveFactory::complexsgnCurve (double saturation, bool satlimit, double satlimthresh, const std::vector& curvePoints, float* outCurve, int skip) { //colormult = chroma_scale for Lab manipulations @@ -316,14 +316,32 @@ void CurveFactory::complexsgnCurve (double saturation, const std::vector std::vector satcurvePoints; satcurvePoints.push_back((double)((CurveType)NURBS)); if (saturation>0) { + double satslope = (0.5+2*saturation/500.0)/(0.5-2*saturation/500.0); + double scale = (satlimthresh/100.1); + if (!satlimit) scale=100/100.1; + satcurvePoints.push_back(0); //black point. Value in [0 ; 1] range satcurvePoints.push_back(0); //black point. Value in [0 ; 1] range - satcurvePoints.push_back(0.25+saturation/500.0); //toe point - satcurvePoints.push_back(0.25-saturation/500.0); //value at toe point - - satcurvePoints.push_back(0.75-saturation/500.0); //shoulder point - satcurvePoints.push_back(0.75+saturation/500.0); //value at shoulder point + //if (satlimit) { + satcurvePoints.push_back(0.5-0.5*scale); //toe point + satcurvePoints.push_back(0.5-0.5*scale); //value at toe point + + satcurvePoints.push_back(0.5-(0.5/satslope)*scale); //toe point + satcurvePoints.push_back(0.5-0.5*scale); //value at toe point + + satcurvePoints.push_back(0.5+(0.5/satslope)*scale); //shoulder point + satcurvePoints.push_back(0.5+0.5*scale); //value at shoulder point + + satcurvePoints.push_back(0.5+0.5*scale); //shoulder point + satcurvePoints.push_back(0.5+0.5*scale); //value at shoulder point + /*} else { + satcurvePoints.push_back(0.25+saturation/500.0); //toe point + satcurvePoints.push_back(0.25-saturation/500.0); //value at toe point + + satcurvePoints.push_back(0.75-saturation/500.0); //shoulder point + satcurvePoints.push_back(0.75+saturation/500.0); //value at shoulder point + }*/ satcurvePoints.push_back(1); // white point satcurvePoints.push_back(1); // value at white point diff --git a/rtengine/curves.h b/rtengine/curves.h index e35b9cd7d..f90b614f5 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -157,7 +157,7 @@ class CurveFactory { public: // static void updateCurve3 (int* curve, int* ohistogram, const std::vector& cpoints, double defmul, double ecomp, int black, double hlcompr, double shcompr, double br, double contr, double gamma_, bool igamma, int skip=1); static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr, double defmul, double gamma_, bool igamma, const std::vector& curvePoints, unsigned int* histogram, float* hlCurve, float* shCurve, int* outCurve, unsigned int* outBeforeCCurveHistogram, int skip=1); - static void complexsgnCurve (double saturation, const std::vector& curvePoints, float* outCurve, int skip=1); + static void complexsgnCurve (double saturation, bool satlimit, double satlimthresh, const std::vector& curvePoints, float* outCurve, int skip=1); }; diff --git a/rtengine/green_equil_RT.cc b/rtengine/green_equil_RT.cc index 21f7484d9..d946762a4 100644 --- a/rtengine/green_equil_RT.cc +++ b/rtengine/green_equil_RT.cc @@ -1,6 +1,27 @@ -// CFA pixel cleaning via directional average -// © Emil Martinec -// 2/18/2010 +//////////////////////////////////////////////////////////////// +// +// Green Equilibration via directional average +// +// copyright (c) 2008-2010 Emil Martinec +// +// +// code dated: February 12, 2011 +// +// green_equil_RT.cc 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. +// +// This program 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 this program. If not, see . +// +//////////////////////////////////////////////////////////////// + #define TS 256 // Tile size #include @@ -20,7 +41,6 @@ void RawImageSource::green_equilibrate(float thresh) static const int v1=TS, v2=2*TS, v3=3*TS, /*v4=4*TS,*/ p1=-TS+1, p2=-2*TS+2, p3=-3*TS+3, m1=TS+1, m2=2*TS+2, m3=3*TS+3; int height=H, width=W; //for RT only - int top, left; int verbose=1; @@ -68,16 +88,12 @@ void RawImageSource::green_equilibrate(float thresh) int numcols = right - left; int row, col; - int rr, cc, c, indx; + int rr, cc, indx; int vote1, vote2; - - float val1; - + float gin, gse, gsw, gne, gnw, wtse, wtsw, wtne, wtnw; - float gu, gd, gl, gr; float mcorr, pcorr; float ginterp; - float diffvarh, diffvarv, hvwt; // rgb from input CFA data /* rgb values should be floating point number between 0 and 1 @@ -92,47 +108,58 @@ void RawImageSource::green_equilibrate(float thresh) //The green equilibration algorithm starts here + //%%%%%%%%%%%%%%%%%%%%%%%%% + // To the extent possible under law, Manuel Llorens + // has waived all copyright and related or neighboring rights to this work. + // This code is licensed under CC0 v1.0, see license information at + // http://creativecommons.org/publicdomain/zero/1.0/ + + double d1,d2,c1,c2; + int o1_1,o1_2,o1_3,o1_4; + int o2_1,o2_2,o2_3,o2_4; + + + //%%%%%%%%%%%%%%%%%%%%%% + for (rr=2; rr < numrows-2; rr++) - //for (cc=3-(FC(rr,2)&1), indx=rr*TS+cc; cc < numcols-2; cc+=2, indx+=2) { - for (indx=rr*TS+2; indx < rr*TS+numcols-2; indx++) { + for (cc=3-(FC(rr,2)&1), indx=rr*TS+cc; cc < numcols-2; cc+=2, indx+=2) { - if (FC(rr,indx)&1) { - pcorr = (cfa[indx+p1]-cfa[indx])*(cfa[indx-p1]-cfa[indx]); - mcorr = (cfa[indx+m1]-cfa[indx])*(cfa[indx-m1]-cfa[indx]); - - if (pcorr>0 && mcorr>0) {checker[indx]=1;} else {checker[indx]=0;} - - //checker[indx]=1;//test what happens if we always interpolate - } else { - gu=cfa[indx-v1]+0.5*(cfa[indx]-cfa[indx-v2]); - gd=cfa[indx+v1]+0.5*(cfa[indx]-cfa[indx+v2]); - gl=cfa[indx-1]+0.5*(cfa[indx]-cfa[indx-2]); - gr=cfa[indx+1]+0.5*(cfa[indx]-cfa[indx+2]); - - gdiffh[indx] = SQR((gl-gr)/(eps+gl+gr)); - gdiffv[indx] = SQR((gu-gd)/(eps+gu+gd)); - - //gvar[indx] = 0.25*(gu*gu+gd*gd+gl*gl+gr*gr)-SQR(0.25*(gu+gd+gl+gr)); - } + pcorr = (cfa[indx+p1]-cfa[indx])*(cfa[indx-p1]-cfa[indx]); + mcorr = (cfa[indx+m1]-cfa[indx])*(cfa[indx-m1]-cfa[indx]); + + if (pcorr>0 && mcorr>0) {checker[indx]=1;} else {checker[indx]=0;} + + //checker[indx]=1;//test what happens if we always interpolate } //now smooth the cfa data - for (rr=6; rr < numrows-6; rr++) + for (rr=6; rr < numrows-6; rr+=2) for (cc=7-(FC(rr,2)&1), indx=rr*TS+cc; cc < numcols-6; cc+=2, indx+=2) { if (checker[indx]) { + //%%%%%%%%%%%%%%%%%%%%%% + //neighbor checking code from Manuel Llorens Garcia + o1_1=cfa[(rr-1)*TS+cc-1]; + o1_2=cfa[(rr-1)*TS+cc+1]; + o1_3=cfa[(rr+1)*TS+cc-1]; + o1_4=cfa[(rr+1)*TS+cc+1]; + o2_1=cfa[(rr-2)*TS+cc]; + o2_2=cfa[(rr+2)*TS+cc]; + o2_3=cfa[(rr)*TS+cc-2]; + o2_4=cfa[(rr)*TS+cc+2]; - diffvarh = eps+(gdiffh[indx-v1]+gdiffh[indx-1]+gdiffh[indx+1]+gdiffh[indx+v1]); - diffvarv = eps+(gdiffv[indx-v1]+gdiffv[indx-1]+gdiffv[indx+1]+gdiffv[indx+v1]); - hvwt = fabs(diffvarv-diffvarh)/(diffvarv+diffvarh); + d1=(o1_1+o1_2+o1_3+o1_4)/4.0; + d2=(o2_1+o2_2+o2_3+o2_4)/4.0; + c1=(fabs(o1_1-o1_2)+fabs(o1_1-o1_3)+fabs(o1_1-o1_4)+fabs(o1_2-o1_3)+fabs(o1_3-o1_4)+fabs(o1_2-o1_4))/6.0; + c2=(fabs(o2_1-o2_2)+fabs(o2_1-o2_3)+fabs(o2_1-o2_4)+fabs(o2_2-o2_3)+fabs(o2_3-o2_4)+fabs(o2_2-o2_4))/6.0; + //%%%%%%%%%%%%%%%%%%%%%% vote1=(checker[indx-v2]+checker[indx-2]+checker[indx+2]+checker[indx+v2]); vote2=(checker[indx-m1]+checker[indx+p1]+checker[indx-p1]+checker[indx+m1]); - if (vote1>0 && vote2>0 && hvwt0 && vote2>0 && (c1+c2)<4*thresh*fabs(d1-d2)) { //pixel interpolation - gin=cfa[indx]; gse=(cfa[indx+m1])+0.5*(cfa[indx]-cfa[indx+m2]); @@ -149,10 +176,7 @@ void RawImageSource::green_equilibrate(float thresh) ginterp=(gse*wtse+gnw*wtnw+gne*wtne+gsw*wtsw)/(wtse+wtnw+wtne+wtsw); - if (/*(SQR(ginterp-gin) > 0.125*(gvar[indx-1]+gvar[indx+1]+gvar[indx-v1]+gvar[indx+v1])) &&*/ ((ginterp-gin) < thresh*(ginterp+gin)) ) { - cfa[indx]=0.5*(ginterp+gin); - } - + cfa[indx]=ginterp;//0.5*(ginterp+gin); } } } @@ -160,15 +184,14 @@ void RawImageSource::green_equilibrate(float thresh) // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // copy smoothed results back to image matrix - for (rr=border; rr < numrows-border; rr++) + for (rr=border; rr < numrows-border; rr+=2) for (row=rr+top, cc=border+1-(FC(rr,2)&1), indx=rr*TS+cc; cc < numcols-border; cc+=2, indx+=2) { - if (cfa[indx]<1) continue; col = cc + left; //c = FC(row,col); //image[row*width + col][c] = CLIP((int)(cfa[indx] + 0.5)); //for dcraw implementation rawData[row][col] = CLIP((int)(cfa[indx] + 0.5)); } - + // clean up } free(buffer); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index eca2db1c6..ccb151d44 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -221,8 +221,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { if (todo & M_LUMACURVE) { CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, \ params.labCurve.lcurve, lhist16, dummy1, dummy2, lumacurve, bcLhist, scale==1 ? 1 : 16); - CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.acurve, chroma_acurve, scale==1 ? 1 : 16); - CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.bcurve, chroma_bcurve, scale==1 ? 1 : 16); + CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, \ + params.labCurve.acurve, chroma_acurve, scale==1 ? 1 : 16); + CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, \ + params.labCurve.bcurve, chroma_bcurve, scale==1 ? 1 : 16); } diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 7427eb466..37fe8099c 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -451,32 +451,6 @@ void ImProcFunctions::chrominanceCurve (LabImage* lold, LabImage* lnew, float* a //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - double* cmultiplier = new double [181021]; - - double c = (0.5+2*params->labCurve.saturation/500.0) / (0.5-2*params->labCurve.saturation/500.0); - - - if (params->labCurve.enable_saturationlimiter && c>1) { - // re-generate color multiplier lookup table - double d = params->labCurve.saturationlimit * chroma_scale / 3.0; - double alpha = 0.5; - double threshold1 = alpha * d; - double threshold2 = c*d*(alpha+1.0) - d; - for (int i=0; i<=181020; i++) { // lookup table stores multipliers with a 0.25 chrominance resolution - double chrominance = (double)i/4; - if (chrominance < threshold1) - cmultiplier[i] = c; - else if (chrominance < d) - cmultiplier[i] = (c / (2.0*d*(alpha-1.0)) * (chrominance-d)*(chrominance-d) + c*d/2.0 * (alpha+1.0) ) / chrominance; - else if (chrominance < threshold2) - cmultiplier[i] = (1.0 / (2.0*d*(c*(alpha+1.0)-2.0)) * (chrominance-d)*(chrominance-d) + c*d/2.0 * (alpha+1.0) ) / chrominance; - else - cmultiplier[i] = 1.0; - } - } - - #pragma omp parallel for if (multiThread) for (int i=0; ia[i][j]; int ob = lold->b[i][j]; - int atmp = (int)acurve[oa+32768]-32768; - int btmp = (int)bcurve[ob+32768]-32768; - - int chroma = (int)(4.0 * sqrt(SQR(oa) + SQR(ob))); - double wanted_c = c; - if (params->labCurve.enable_saturationlimiter && c>1) { - wanted_c = cmultiplier [MIN(chroma,181020)]; - } - - double real_c = wanted_c; - if (wanted_c >= 1.0 && params->labCurve.avoidclip) { - double cclip = 100000; - double cr = tightestroot ((double)lnew->L[i][j]/655.35, (double)(oa)/chroma_scale, (double)(ob)/chroma_scale, 3.079935, -1.5371515, -0.54278342); - double cg = tightestroot ((double)lnew->L[i][j]/655.35, (double)(oa)/chroma_scale, (double)(ob)/chroma_scale, -0.92123418, 1.87599, 0.04524418); - double cb = tightestroot ((double)lnew->L[i][j]/655.35, (double)(oa)/chroma_scale, (double)(ob)/chroma_scale, 0.052889682, -0.20404134, 1.15115166); - if (cr>1.0 && cr1.0 && cg1.0 && cblabCurve.avoidclip) { + double Lclip = MIN(lnew->L[i][j]/655.35,100.0); + double cr = tightestroot (Lclip, (double)atmp/chroma_scale, (double)btmp/chroma_scale, 3.079935, -1.5371515, -0.54278342); + double cg = tightestroot (Lclip, (double)atmp/chroma_scale, (double)btmp/chroma_scale, -0.92123418, 1.87599, 0.04524418); + double cb = tightestroot (Lclip, (double)atmp/chroma_scale, (double)btmp/chroma_scale, 0.052889682, -0.20404134, 1.15115166); + if (cr>0 && cr0 && cg0 && cb chroma) { - lnew->a[i][j] = CLIPTO(nna,-32000,32000); - lnew->b[i][j] = CLIPTO(nnb,-32000,32000); - } else { - lnew->a[i][j] = CLIPTO(atmp,-32000,32000); - lnew->b[i][j] = CLIPTO(btmp,-32000,32000); - } + int nna = (int)((atmp) * real_c ); + int nnb = (int)((btmp) * real_c ); + lnew->a[i][j] = CLIPTO(nna,-32000,32000); + lnew->b[i][j] = CLIPTO(nnb,-32000,32000); } - delete [] cmultiplier; - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index bf7a46f75..63284908b 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -66,7 +66,7 @@ void ProcParams::setDefaults () { labCurve.saturation = 0; labCurve.avoidclip = false; labCurve.enable_saturationlimiter = false; - labCurve.saturationlimit = 50; + labCurve.saturationlimit = 40; labCurve.lcurve.clear (); labCurve.acurve.clear (); labCurve.bcurve.clear (); diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index ae9921cf5..2e3fdc09b 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -718,8 +718,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei // luminance processing CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, hist16, curve1, curve2, curve, NULL, 16); ipf.luminanceCurve (labView, labView, curve); - CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.acurve, curve1, 16); - CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.bcurve, curve2, 16); + CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, params.labCurve.acurve, curve1, 16); + CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, params.labCurve.bcurve, curve2, 16); ipf.chrominanceCurve (labView, labView, curve1, curve2); delete [] curve1; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 56bb662b5..8a7b44462 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -167,8 +167,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p // luminance processing CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, hist16, curve1, curve2, curve, NULL); ipf.luminanceCurve (labView, labView, curve); - CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.acurve, curve1, 1); - CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.bcurve, curve2, 1); + CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, params.labCurve.acurve, curve1, 1); + CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, params.labCurve.bcurve, curve2, 1); ipf.chrominanceCurve (labView, labView, curve1, curve2); ipf.impulsedenoise (labView); diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc index c0c4f9c6a..db18717e1 100644 --- a/rtgui/labcurve.cc +++ b/rtgui/labcurve.cc @@ -36,6 +36,32 @@ LCurve::LCurve () : Gtk::VBox(), FoldableToolPanel(this), brAdd(false), contrAdd pack_start (*saturation); saturation->show (); + + brightness->setAdjusterListener (this); + contrast->setAdjusterListener (this); + saturation->setAdjusterListener (this); + + //%%%%%%%%%%%%%%%%%% + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + avoidclip = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_AVOIDCOLORCLIP"))); + + pack_start (*avoidclip); + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + enablelimiter = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_ENABLESATLIMITER"))); + pack_start (*enablelimiter); + + saturationlimiter = new Adjuster (M("TP_LABCURVE_SATLIMIT"), 0, 100, 0.1, 40); + pack_start (*saturationlimiter); + saturationlimiter->show (); + saturationlimiter->reference (); + + //saturation->setAdjusterListener (this); + saturationlimiter->setAdjusterListener (this); + acconn = avoidclip->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::avoidclip_toggled) ); + elconn = enablelimiter->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::enablelimiter_toggled) ); + //%%%%%%%%%%%%%%%%%%% Gtk::HSeparator *hsep3 = Gtk::manage (new Gtk::HSeparator()); hsep3->show (); @@ -52,33 +78,7 @@ LCurve::LCurve () : Gtk::VBox(), FoldableToolPanel(this), brAdd(false), contrAdd curveEditorG->curveListComplete(); pack_start (*curveEditorG, Gtk::PACK_SHRINK, 4); - - brightness->setAdjusterListener (this); - contrast->setAdjusterListener (this); - saturation->setAdjusterListener (this); - - //%%%%%%%%%%%%%%%%%% - pack_start (*Gtk::manage (new Gtk::HSeparator())); - - avoidclip = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_AVOIDCOLORCLIP"))); - - pack_start (*avoidclip); - pack_start (*Gtk::manage (new Gtk::HSeparator())); - - enablelimiter = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_ENABLESATLIMITER"))); - pack_start (*enablelimiter); - - saturationlimiter = new Adjuster (M("TP_LABCURVE_SATLIMIT"), 0, 200, 0.1, 100); - saturationlimiter->show (); - saturationlimiter->reference (); - - //saturation->setAdjusterListener (this); - saturationlimiter->setAdjusterListener (this); - acconn = avoidclip->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::avoidclip_toggled) ); - elconn = enablelimiter->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::enablelimiter_toggled) ); - //%%%%%%%%%%%%%%%%%%% - } LCurve::~LCurve () { @@ -119,9 +119,9 @@ void LCurve::read (const ProcParams* pp, const ParamsEdited* pedited) { enablelimiter->set_active (pp->labCurve.enable_saturationlimiter); elconn.block (false); - removeIfThere (this, saturationlimiter, false); - if (enablelimiter->get_active () || enablelimiter->get_inconsistent()) - pack_start (*saturationlimiter); + //removeIfThere (this, saturationlimiter, false); + // if (enablelimiter->get_active () || enablelimiter->get_inconsistent()) + // pack_start (*saturationlimiter); lastACVal = pp->labCurve.avoidclip; lastELVal = pp->labCurve.enable_saturationlimiter; @@ -230,9 +230,9 @@ void LCurve::enablelimiter_toggled () { lastELVal = enablelimiter->get_active (); } - removeIfThere (this, saturationlimiter, false); - if (enablelimiter->get_active () || enablelimiter->get_inconsistent()) - pack_start (*saturationlimiter); + //removeIfThere (this, saturationlimiter, false); + //if (enablelimiter->get_active () || enablelimiter->get_inconsistent()) + // pack_start (*saturationlimiter); if (listener) { if (enablelimiter->get_active ())