Bugfix for saturation limiter; bugfix for build using XCode; improvements to Green Equilibration.
This commit is contained in:
parent
550a868531
commit
c43afe0dfd
@ -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"
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -302,7 +302,7 @@ void Curve::getVal (const std::vector<double>& t, std::vector<double>& res) {
|
||||
}
|
||||
|
||||
|
||||
void CurveFactory::complexsgnCurve (double saturation, const std::vector<double>& curvePoints, float* outCurve, int skip) {
|
||||
void CurveFactory::complexsgnCurve (double saturation, bool satlimit, double satlimthresh, const std::vector<double>& curvePoints, float* outCurve, int skip) {
|
||||
|
||||
//colormult = chroma_scale for Lab manipulations
|
||||
|
||||
@ -316,14 +316,32 @@ void CurveFactory::complexsgnCurve (double saturation, const std::vector<double>
|
||||
std::vector<double> 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
|
||||
|
@ -157,7 +157,7 @@ class CurveFactory {
|
||||
public:
|
||||
// static void updateCurve3 (int* curve, int* ohistogram, const std::vector<double>& 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<double>& curvePoints, unsigned int* histogram, float* hlCurve, float* shCurve, int* outCurve, unsigned int* outBeforeCCurveHistogram, int skip=1);
|
||||
static void complexsgnCurve (double saturation, const std::vector<double>& curvePoints, float* outCurve, int skip=1);
|
||||
static void complexsgnCurve (double saturation, bool satlimit, double satlimthresh, const std::vector<double>& curvePoints, float* outCurve, int skip=1);
|
||||
|
||||
};
|
||||
|
||||
|
@ -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 <ejmartin@uchicago.edu>
|
||||
//
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TS 256 // Tile size
|
||||
|
||||
#include <math.h>
|
||||
@ -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 <manuelllorens@gmail.com>
|
||||
// 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 && hvwt<diffthresh) {
|
||||
if (vote1>0 && 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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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; i<H; i++)
|
||||
for (int j=0; j<W; j++) {
|
||||
@ -484,45 +458,27 @@ void ImProcFunctions::chrominanceCurve (LabImage* lold, LabImage* lnew, float* a
|
||||
int oa = lold->a[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 && cr<cclip) cclip = cr;
|
||||
if (cg>1.0 && cg<cclip) cclip = cg;
|
||||
if (cb>1.0 && cb<cclip) cclip = cb;
|
||||
if (cclip<100000) {
|
||||
real_c = -cclip + 2.0*cclip / (1.0+exp(-2.0*wanted_c/cclip));
|
||||
if (real_c<1.0)
|
||||
real_c = 1.0;
|
||||
}
|
||||
float atmp = acurve[oa+32768]-32768;
|
||||
float btmp = bcurve[ob+32768]-32768;
|
||||
|
||||
double real_c = 1.0;
|
||||
if (params->labCurve.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 && cr<real_c) real_c = cr;
|
||||
if (cg>0 && cg<real_c) real_c = cg;
|
||||
if (cb>0 && cb<real_c) real_c = cb;
|
||||
//if (i%100==50 && j%100==50) printf ("(i,j)=(%d,%d) c= %f, rmax= %f \n", i, j, c, real_c);//diagnostic
|
||||
}
|
||||
|
||||
int nna = (int)((oa) * real_c );
|
||||
int nnb = (int)((ob) * real_c );
|
||||
if (4.0*sqrt(SQR(atmp)+SQR(btmp)) > 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;
|
||||
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
}
|
||||
|
@ -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 ();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 ())
|
||||
|
Loading…
x
Reference in New Issue
Block a user