Merge branch 'dev' into issue1474
This commit is contained in:
commit
fe09f8587d
@ -252,6 +252,12 @@ if(NOT DEFINED APPDATADIR)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (NOT APPLE)
|
||||||
|
if(DEFINED LENSFUNDBDIR AND NOT IS_ABSOLUTE "${LENSFUNDBDIR}")
|
||||||
|
set(LENSFUNDBDIR "${DATADIR}/${LENSFUNDBDIR}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
if("${CODESIGNID}")
|
if("${CODESIGNID}")
|
||||||
set(CODESIGNID "${CODESIGNID}" CACHE STRING "Codesigning Identity")
|
set(CODESIGNID "${CODESIGNID}" CACHE STRING "Codesigning Identity")
|
||||||
@ -396,7 +402,7 @@ if(WITH_PROF)
|
|||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wuninitialized -Wcast-qual -Wno-deprecated-declarations -Wno-unused-result")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wuninitialized -Wcast-qual -Wno-deprecated-declarations -Wno-unused-result -Wunused-macros")
|
||||||
if(OPTION_OMP)
|
if(OPTION_OMP)
|
||||||
find_package(OpenMP)
|
find_package(OpenMP)
|
||||||
if(OPENMP_FOUND)
|
if(OPENMP_FOUND)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
RawTherapee - A powerful, cross-platform raw image processing program.
|
RawTherapee - A powerful, cross-platform raw image processing program.
|
||||||
Copyright (C) 2004-2012 Gabor Horvath <hgabor@rawtherapee.com>
|
Copyright (C) 2004-2012 Gabor Horvath <hgabor@rawtherapee.com>
|
||||||
Copyright (C) 2010-2019 RawTherapee development team.
|
Copyright (C) 2010-2020 RawTherapee development team.
|
||||||
|
|
||||||
RawTherapee is free software: you can redistribute it and/or modify
|
RawTherapee is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
RAWTHERAPEE 5.7-dev RELEASE NOTES
|
RAWTHERAPEE 5.8-dev RELEASE NOTES
|
||||||
|
|
||||||
This is a development version of RawTherapee. We update the code almost daily. Every few months, once enough changes have accumulated and the code is stabilized, we make a new official release. Every code change between these releases is known as a "development" version, and this is one of them.
|
This is a development version of RawTherapee. We update the code almost daily. Every few months, once enough changes have accumulated and the code is stabilized, we make a new official release. Every code change between these releases is known as a "development" version, and this is one of them.
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ https://rawpedia.rawtherapee.com/
|
|||||||
While we only commit tested and relatively stable code and so the development versions should be fairly stable, you should be aware that:
|
While we only commit tested and relatively stable code and so the development versions should be fairly stable, you should be aware that:
|
||||||
- Development versions only had limited testing, so there may be bugs unknown to us.
|
- Development versions only had limited testing, so there may be bugs unknown to us.
|
||||||
- You should report these bugs so that they get fixed for the next stable release. See
|
- You should report these bugs so that they get fixed for the next stable release. See
|
||||||
www.rawpedia.rawtherapee.com/How_to_write_useful_bug_reports
|
https://rawpedia.rawtherapee.com/How_to_write_useful_bug_reports
|
||||||
- The way new tools work in the development versions is likely to change as we tweak and tune them, so your processing profiles may produce different results when used in a future stable version.
|
- The way new tools work in the development versions is likely to change as we tweak and tune them, so your processing profiles may produce different results when used in a future stable version.
|
||||||
- Bugs present in the stable versions get fixed in the development versions, and make it into the next stable version when we make a new official release. That means that in some ways the development versions can be "more stable" than the latest stable release. At the same time, new features may introduce new bugs. This is a trade-off you should be aware of.
|
- Bugs present in the stable versions get fixed in the development versions, and make it into the next stable version when we make a new official release. That means that in some ways the development versions can be "more stable" than the latest stable release. At the same time, new features may introduce new bugs. This is a trade-off you should be aware of.
|
||||||
|
|
||||||
@ -26,14 +26,14 @@ In order to use RawTherapee efficiently you should know that:
|
|||||||
- All curves support the Shift and Ctrl keys while dragging a point. Shift+drag makes the point snap to a meaningful axis (top, bottom, diagonal, other), while Ctrl+drag makes your mouse movement super-fine for precise point positioning.
|
- All curves support the Shift and Ctrl keys while dragging a point. Shift+drag makes the point snap to a meaningful axis (top, bottom, diagonal, other), while Ctrl+drag makes your mouse movement super-fine for precise point positioning.
|
||||||
- There are many keyboard shortcuts which make working with RawTherapee much faster and give you greater control. Make sure you familiarize yourself with them on RawPedia's "Keyboard Shortcuts" page!
|
- There are many keyboard shortcuts which make working with RawTherapee much faster and give you greater control. Make sure you familiarize yourself with them on RawPedia's "Keyboard Shortcuts" page!
|
||||||
|
|
||||||
New features since 5.7:
|
New features since 5.8:
|
||||||
- TODO
|
- TODO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NEWS RELEVANT TO PACKAGE MAINTAINERS
|
NEWS RELEVANT TO PACKAGE MAINTAINERS
|
||||||
|
|
||||||
New since 5.7:
|
New since 5.8:
|
||||||
- TODO
|
- TODO
|
||||||
|
|
||||||
In general:
|
In general:
|
||||||
|
@ -19,13 +19,12 @@
|
|||||||
<url type="donation">https://www.paypal.me/rawtherapee</url>
|
<url type="donation">https://www.paypal.me/rawtherapee</url>
|
||||||
<url type="help">https://rawpedia.rawtherapee.com</url>
|
<url type="help">https://rawpedia.rawtherapee.com</url>
|
||||||
<url type="homepage">https://www.rawtherapee.com</url>
|
<url type="homepage">https://www.rawtherapee.com</url>
|
||||||
<url type="translate">https://discuss.pixls.us/t/localization-how-to-translate-rawtherapee-and-rawpedia/2594</url>
|
<url type="translate">https://rawpedia.rawtherapee.com/Main_Page#Localization</url>
|
||||||
<launchable type="desktop-id">rawtherapee.desktop</launchable>
|
<launchable type="desktop-id">rawtherapee.desktop</launchable>
|
||||||
<releases>
|
<releases>
|
||||||
|
<release version="5.8" date="2020-02-04" type="stable"></release>
|
||||||
<release version="5.7" date="2019-09-10" type="stable"></release>
|
<release version="5.7" date="2019-09-10" type="stable"></release>
|
||||||
<release version="5.6" date="2019-04-20" type="stable"></release>
|
<release version="5.6" date="2019-04-20" type="stable"></release>
|
||||||
<release version="5.6~rc2" date="2019-04-17" type="development"></release>
|
|
||||||
<release version="5.6~rc1" date="2019-04-10" type="development"></release>
|
|
||||||
<release version="5.5" date="2018-12-17" type="stable"></release>
|
<release version="5.5" date="2018-12-17" type="stable"></release>
|
||||||
</releases>
|
</releases>
|
||||||
<provides>
|
<provides>
|
||||||
|
@ -29,9 +29,12 @@ if(UNIX)
|
|||||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rawtherapee.desktop" DESTINATION ${DESKTOPDIR})
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rawtherapee.desktop" DESTINATION ${DESKTOPDIR})
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-16.png" DESTINATION "${ICONSDIR}/hicolor/16x16/apps" RENAME rawtherapee.png)
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-16.png" DESTINATION "${ICONSDIR}/hicolor/16x16/apps" RENAME rawtherapee.png)
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-24.png" DESTINATION "${ICONSDIR}/hicolor/24x24/apps" RENAME rawtherapee.png)
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-24.png" DESTINATION "${ICONSDIR}/hicolor/24x24/apps" RENAME rawtherapee.png)
|
||||||
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-32.png" DESTINATION "${ICONSDIR}/hicolor/32x32/apps" RENAME rawtherapee.png)
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-48.png" DESTINATION "${ICONSDIR}/hicolor/48x48/apps" RENAME rawtherapee.png)
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-48.png" DESTINATION "${ICONSDIR}/hicolor/48x48/apps" RENAME rawtherapee.png)
|
||||||
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-64.png" DESTINATION "${ICONSDIR}/hicolor/64x64/apps" RENAME rawtherapee.png)
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-128.png" DESTINATION "${ICONSDIR}/hicolor/128x128/apps" RENAME rawtherapee.png)
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-128.png" DESTINATION "${ICONSDIR}/hicolor/128x128/apps" RENAME rawtherapee.png)
|
||||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-256.png" DESTINATION "${ICONSDIR}/hicolor/256x256/apps" RENAME rawtherapee.png)
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-256.png" DESTINATION "${ICONSDIR}/hicolor/256x256/apps" RENAME rawtherapee.png)
|
||||||
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/svg/rt-logo.svg" DESTINATION "${ICONSDIR}/hicolor/scalable/apps" RENAME rawtherapee.svg)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
install(FILES ${LANGUAGEFILES} DESTINATION "${DATADIR}/languages")
|
install(FILES ${LANGUAGEFILES} DESTINATION "${DATADIR}/languages")
|
||||||
|
BIN
rtdata/dcpprofiles/Canon PowerShot S120.dcp
Normal file
BIN
rtdata/dcpprofiles/Canon PowerShot S120.dcp
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 83 KiB |
1078
rtdata/images/svg/splash_template.svg
Normal file
1078
rtdata/images/svg/splash_template.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 82 KiB |
File diff suppressed because it is too large
Load Diff
@ -790,12 +790,12 @@ float* RawImageSource::CA_correct_RT(
|
|||||||
for (int m = 0; m < polyord; m++) {
|
for (int m = 0; m < polyord; m++) {
|
||||||
double powHblock = powHblockInit;
|
double powHblock = powHblockInit;
|
||||||
for (int n = 0; n < polyord; n++) {
|
for (int n = 0; n < polyord; n++) {
|
||||||
polymat[c][dir][numpar * (polyord * i + j) + (polyord * m + n)] += powVblock * powHblock * blockwt[vblock * hblsz + hblock];
|
polymat[c][dir][numpar * (polyord * i + j) + (polyord * m + n)] += powVblock * powHblock * static_cast<double>(blockwt[vblock * hblsz + hblock]);
|
||||||
powHblock *= hblock;
|
powHblock *= hblock;
|
||||||
}
|
}
|
||||||
powVblock *= vblock;
|
powVblock *= vblock;
|
||||||
}
|
}
|
||||||
shiftmat[c][dir][(polyord * i + j)] += powVblockInit * powHblockInit * bstemp[dir] * blockwt[vblock * hblsz + hblock];
|
shiftmat[c][dir][(polyord * i + j)] += powVblockInit * powHblockInit * static_cast<double>(bstemp[dir]) * static_cast<double>(blockwt[vblock * hblsz + hblock]);
|
||||||
powHblockInit *= hblock;
|
powHblockInit *= hblock;
|
||||||
}
|
}
|
||||||
powVblockInit *= vblock;
|
powVblockInit *= vblock;
|
||||||
@ -848,7 +848,7 @@ float* RawImageSource::CA_correct_RT(
|
|||||||
for (int top = -border; top < height; top += ts - border2) {
|
for (int top = -border; top < height; top += ts - border2) {
|
||||||
for (int left = -border; left < width - (W & 1); left += ts - border2) {
|
for (int left = -border; left < width - (W & 1); left += ts - border2) {
|
||||||
memset(bufferThr, 0, buffersizePassTwo);
|
memset(bufferThr, 0, buffersizePassTwo);
|
||||||
float lblockshifts[2][2];
|
double lblockshifts[2][2];
|
||||||
const int vblock = ((top + border) / (ts - border2)) + 1;
|
const int vblock = ((top + border) / (ts - border2)) + 1;
|
||||||
const int hblock = ((left + border) / (ts - border2)) + 1;
|
const int hblock = ((left + border) / (ts - border2)) + 1;
|
||||||
const int bottom = min(top + ts, height + border);
|
const int bottom = min(top + ts, height + border);
|
||||||
@ -1036,8 +1036,8 @@ float* RawImageSource::CA_correct_RT(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!autoCA) {
|
if (!autoCA) {
|
||||||
float hfrac = -((float)(hblock - 0.5) / (hblsz - 2) - 0.5);
|
double hfrac = -((hblock - 0.5) / (hblsz - 2) - 0.5);
|
||||||
float vfrac = -((float)(vblock - 0.5) / (vblsz - 2) - 0.5) * height / width;
|
double vfrac = -((vblock - 0.5) / (vblsz - 2) - 0.5) * height / width;
|
||||||
lblockshifts[0][0] = 2 * vfrac * cared;
|
lblockshifts[0][0] = 2 * vfrac * cared;
|
||||||
lblockshifts[0][1] = 2 * hfrac * cared;
|
lblockshifts[0][1] = 2 * hfrac * cared;
|
||||||
lblockshifts[1][0] = 2 * vfrac * cablue;
|
lblockshifts[1][0] = 2 * vfrac * cablue;
|
||||||
@ -1058,7 +1058,7 @@ float* RawImageSource::CA_correct_RT(
|
|||||||
}
|
}
|
||||||
powVblock *= vblock;
|
powVblock *= vblock;
|
||||||
}
|
}
|
||||||
constexpr float bslim = 3.99; //max allowed CA shift
|
constexpr double bslim = 3.99f; //max allowed CA shift
|
||||||
lblockshifts[0][0] = LIM(lblockshifts[0][0], -bslim, bslim);
|
lblockshifts[0][0] = LIM(lblockshifts[0][0], -bslim, bslim);
|
||||||
lblockshifts[0][1] = LIM(lblockshifts[0][1], -bslim, bslim);
|
lblockshifts[0][1] = LIM(lblockshifts[0][1], -bslim, bslim);
|
||||||
lblockshifts[1][0] = LIM(lblockshifts[1][0], -bslim, bslim);
|
lblockshifts[1][0] = LIM(lblockshifts[1][0], -bslim, bslim);
|
||||||
@ -1070,14 +1070,14 @@ float* RawImageSource::CA_correct_RT(
|
|||||||
//some parameters for the bilinear interpolation
|
//some parameters for the bilinear interpolation
|
||||||
shiftvfloor[c] = floor((float)lblockshifts[c>>1][0]);
|
shiftvfloor[c] = floor((float)lblockshifts[c>>1][0]);
|
||||||
shiftvceil[c] = ceil((float)lblockshifts[c>>1][0]);
|
shiftvceil[c] = ceil((float)lblockshifts[c>>1][0]);
|
||||||
if (lblockshifts[c>>1][0] < 0.f) {
|
if (lblockshifts[c>>1][0] < 0.0) {
|
||||||
std::swap(shiftvfloor[c], shiftvceil[c]);
|
std::swap(shiftvfloor[c], shiftvceil[c]);
|
||||||
}
|
}
|
||||||
shiftvfrac[c] = fabs(lblockshifts[c>>1][0] - shiftvfloor[c]);
|
shiftvfrac[c] = fabs(lblockshifts[c>>1][0] - shiftvfloor[c]);
|
||||||
|
|
||||||
shifthfloor[c] = floor((float)lblockshifts[c>>1][1]);
|
shifthfloor[c] = floor((float)lblockshifts[c>>1][1]);
|
||||||
shifthceil[c] = ceil((float)lblockshifts[c>>1][1]);
|
shifthceil[c] = ceil((float)lblockshifts[c>>1][1]);
|
||||||
if (lblockshifts[c>>1][1] < 0.f) {
|
if (lblockshifts[c>>1][1] < 0.0) {
|
||||||
std::swap(shifthfloor[c], shifthceil[c]);
|
std::swap(shifthfloor[c], shifthceil[c]);
|
||||||
}
|
}
|
||||||
shifthfrac[c] = fabs(lblockshifts[c>>1][1] - shifthfloor[c]);
|
shifthfrac[c] = fabs(lblockshifts[c>>1][1] - shifthfloor[c]);
|
||||||
|
@ -12,6 +12,11 @@ include_directories(${EXTRA_INCDIR}
|
|||||||
${LENSFUN_INCLUDE_DIRS}
|
${LENSFUN_INCLUDE_DIRS}
|
||||||
${RSVG_INCLUDE_DIRS}
|
${RSVG_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
if(NOT WITH_SYSTEM_KLT)
|
||||||
|
include_directories("${CMAKE_SOURCE_DIR}/rtengine/klt")
|
||||||
|
else()
|
||||||
|
include_directories(${KLT_INCLUDE_DIRS})
|
||||||
|
endif()
|
||||||
|
|
||||||
link_directories("${PROJECT_SOURCE_DIR}/rtexif"
|
link_directories("${PROJECT_SOURCE_DIR}/rtexif"
|
||||||
${EXPAT_LIBRARY_DIRS}
|
${EXPAT_LIBRARY_DIRS}
|
||||||
@ -94,6 +99,7 @@ set(RTENGINESOURCEFILES
|
|||||||
ipretinex.cc
|
ipretinex.cc
|
||||||
ipshadowshighlights.cc
|
ipshadowshighlights.cc
|
||||||
ipsharpen.cc
|
ipsharpen.cc
|
||||||
|
ipsharpenedges.cc
|
||||||
ipsoftlight.cc
|
ipsoftlight.cc
|
||||||
iptransform.cc
|
iptransform.cc
|
||||||
ipvibrance.cc
|
ipvibrance.cc
|
||||||
@ -105,6 +111,7 @@ set(RTENGINESOURCEFILES
|
|||||||
lj92.c
|
lj92.c
|
||||||
lmmse_demosaic.cc
|
lmmse_demosaic.cc
|
||||||
loadinitial.cc
|
loadinitial.cc
|
||||||
|
munselllch.cc
|
||||||
myfile.cc
|
myfile.cc
|
||||||
panasonic_decoders.cc
|
panasonic_decoders.cc
|
||||||
pdaflinesfilter.cc
|
pdaflinesfilter.cc
|
||||||
@ -185,6 +192,7 @@ target_link_libraries(rtengine rtexif
|
|||||||
${ZLIB_LIBRARIES}
|
${ZLIB_LIBRARIES}
|
||||||
${LENSFUN_LIBRARIES}
|
${LENSFUN_LIBRARIES}
|
||||||
${RSVG_LIBRARIES}
|
${RSVG_LIBRARIES}
|
||||||
|
${KLT_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
install(FILES ${CAMCONSTSFILE} DESTINATION "${DATADIR}" PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
|
install(FILES ${CAMCONSTSFILE} DESTINATION "${DATADIR}" PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
|
||||||
|
@ -55,7 +55,7 @@ float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), fl
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(int ii = 0; ii < n; ii++) {
|
for(int ii = 0; ii < n; ii++) {
|
||||||
rs += r[ii] * s[ii];
|
rs += static_cast<double>(r[ii]) * static_cast<double>(s[ii]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Search direction d.
|
//Search direction d.
|
||||||
@ -84,15 +84,15 @@ float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), fl
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(int ii = 0; ii < n; ii++) {
|
for(int ii = 0; ii < n; ii++) {
|
||||||
ab += d[ii] * ax[ii];
|
ab += static_cast<double>(d[ii]) * static_cast<double>(ax[ii]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ab == 0.0f) {
|
if(ab == 0.0) {
|
||||||
break; //So unlikely. It means perfectly converged or singular, stop either way.
|
break; //So unlikely. It means perfectly converged or singular, stop either way.
|
||||||
}
|
}
|
||||||
|
|
||||||
ab = rs / ab;
|
ab = rs / ab;
|
||||||
|
float abf = ab;
|
||||||
//Update x and r with this step size.
|
//Update x and r with this step size.
|
||||||
double rms = 0.0; // use double precision for large summations
|
double rms = 0.0; // use double precision for large summations
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
@ -100,15 +100,15 @@ float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), fl
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(int ii = 0; ii < n; ii++) {
|
for(int ii = 0; ii < n; ii++) {
|
||||||
x[ii] += ab * d[ii];
|
x[ii] += abf * d[ii];
|
||||||
r[ii] -= ab * ax[ii]; //"Fast recursive formula", use explicit r = b - Ax occasionally?
|
r[ii] -= abf * ax[ii]; //"Fast recursive formula", use explicit r = b - Ax occasionally?
|
||||||
rms += r[ii] * r[ii];
|
rms += rtengine::SQR<double>(r[ii]);
|
||||||
}
|
}
|
||||||
|
|
||||||
rms = sqrtf(rms / n);
|
rms = sqrtf(rms / n);
|
||||||
|
|
||||||
//Quit? This probably isn't the best stopping condition, but ok.
|
//Quit? This probably isn't the best stopping condition, but ok.
|
||||||
if(rms < RMSResidual) {
|
if(rms < static_cast<double>(RMSResidual)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,20 +129,20 @@ float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), fl
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(int ii = 0; ii < n; ii++) {
|
for(int ii = 0; ii < n; ii++) {
|
||||||
rs += r[ii] * s[ii];
|
rs += static_cast<double>(r[ii]) * static_cast<double>(s[ii]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ab = rs / ab;
|
ab = rs / ab;
|
||||||
|
abf = ab;
|
||||||
//Update search direction p.
|
//Update search direction p.
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(int ii = 0; ii < n; ii++) {
|
for(int ii = 0; ii < n; ii++) {
|
||||||
d[ii] = s[ii] + ab * d[ii];
|
d[ii] = s[ii] + abf * d[ii];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,7 +56,6 @@
|
|||||||
|
|
||||||
#define TS 64 // Tile size
|
#define TS 64 // Tile size
|
||||||
#define offset 25 // shift between tiles
|
#define offset 25 // shift between tiles
|
||||||
#define fTS ((TS/2+1)) // second dimension of Fourier tiles
|
|
||||||
#define blkrad 1 // radius of block averaging
|
#define blkrad 1 // radius of block averaging
|
||||||
|
|
||||||
#define epsilon 0.001f/(TS*TS) //tolerance
|
#define epsilon 0.001f/(TS*TS) //tolerance
|
||||||
@ -548,7 +547,7 @@ BENCHFUN
|
|||||||
const bool denoiseMethodRgb = (dnparams.dmethod == "RGB");
|
const bool denoiseMethodRgb = (dnparams.dmethod == "RGB");
|
||||||
// init luma noisevarL
|
// init luma noisevarL
|
||||||
const float noiseluma = static_cast<float>(dnparams.luma);
|
const float noiseluma = static_cast<float>(dnparams.luma);
|
||||||
const float noisevarL = (useNoiseLCurve && (denoiseMethodRgb || !isRAW)) ? static_cast<float>(SQR(((noiseluma + 1.0) / 125.0) * (10. + (noiseluma + 1.0) / 25.0))) : static_cast<float>(SQR((noiseluma / 125.0) * (1.0 + noiseluma / 25.0)));
|
const float noisevarL = (useNoiseLCurve && (denoiseMethodRgb || !isRAW)) ? SQR(((noiseluma + 1.f) / 125.f) * (10.f + (noiseluma + 1.f) / 25.f)) : SQR((noiseluma / 125.f) * (1.f + noiseluma / 25.f));
|
||||||
const bool denoiseLuminance = (noisevarL > 0.00001f);
|
const bool denoiseLuminance = (noisevarL > 0.00001f);
|
||||||
|
|
||||||
//printf("NL=%f \n",noisevarL);
|
//printf("NL=%f \n",noisevarL);
|
||||||
@ -635,20 +634,20 @@ BENCHFUN
|
|||||||
|
|
||||||
if (dnparams.luma != 0 || dnparams.chroma != 0 || dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly") {
|
if (dnparams.luma != 0 || dnparams.chroma != 0 || dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly") {
|
||||||
// gamma transform for input data
|
// gamma transform for input data
|
||||||
float gam = dnparams.gamma;
|
double gam = dnparams.gamma;
|
||||||
float gamthresh = 0.001f;
|
constexpr double gamthresh = 0.001;
|
||||||
|
|
||||||
if (!isRAW) {//reduce gamma under 1 for Lab mode ==> TIF and JPG
|
if (!isRAW) {//reduce gamma under 1 for Lab mode ==> TIF and JPG
|
||||||
if (gam < 1.9f) {
|
if (gam < 1.9) {
|
||||||
gam = 1.f - (1.9f - gam) / 3.f; //minimum gamma 0.7
|
gam = 1.0 - (1.9 - gam) / 3.0; //minimum gamma 0.7
|
||||||
} else if (gam >= 1.9f && gam <= 3.f) {
|
} else if (gam >= 1.9 && gam <= 3.0) {
|
||||||
gam = (1.4f / 1.1f) * gam - 1.41818f;
|
gam = (1.4 / 1.1) * gam - 1.41818;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LUTf gamcurve(65536, LUT_CLIP_BELOW);
|
LUTf gamcurve(65536, LUT_CLIP_BELOW);
|
||||||
float gamslope = exp(log(static_cast<double>(gamthresh)) / gam) / gamthresh;
|
const double gamslope = exp(log(gamthresh) / gam) / gamthresh;
|
||||||
|
|
||||||
if (denoiseMethodRgb) {
|
if (denoiseMethodRgb) {
|
||||||
Color::gammaf2lut(gamcurve, gam, gamthresh, gamslope, 65535.f, 32768.f);
|
Color::gammaf2lut(gamcurve, gam, gamthresh, gamslope, 65535.f, 32768.f);
|
||||||
@ -657,9 +656,9 @@ BENCHFUN
|
|||||||
}
|
}
|
||||||
|
|
||||||
// inverse gamma transform for output data
|
// inverse gamma transform for output data
|
||||||
float igam = 1.f / gam;
|
const float igam = 1.0 / gam;
|
||||||
float igamthresh = gamthresh * gamslope;
|
const float igamthresh = gamthresh * gamslope;
|
||||||
float igamslope = 1.f / gamslope;
|
const float igamslope = 1.0 / gamslope;
|
||||||
|
|
||||||
LUTf igamcurve(65536, LUT_CLIP_BELOW);
|
LUTf igamcurve(65536, LUT_CLIP_BELOW);
|
||||||
|
|
||||||
@ -669,9 +668,9 @@ BENCHFUN
|
|||||||
Color::gammanf2lut(igamcurve, igam, 32768.f, 65535.f);
|
Color::gammanf2lut(igamcurve, igam, 32768.f, 65535.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float gain = pow(2.0f, float(expcomp));
|
const float gain = std::pow(2.0, expcomp);
|
||||||
float params_Ldetail = min(float(dnparams.Ldetail), 99.9f); // max out to avoid div by zero when using noisevar_Ldetail as divisor
|
const double params_Ldetail = std::min(dnparams.Ldetail, 99.9); // max out to avoid div by zero when using noisevar_Ldetail as divisor
|
||||||
float noisevar_Ldetail = SQR(static_cast<float>(SQR(100. - params_Ldetail) + 50.*(100. - params_Ldetail)) * TS * 0.5f);
|
const float noisevar_Ldetail = SQR(SQR(100. - params_Ldetail) + 50.0 * (100.0 - params_Ldetail) * TS * 0.5);
|
||||||
|
|
||||||
array2D<float> tilemask_in(TS, TS);
|
array2D<float> tilemask_in(TS, TS);
|
||||||
array2D<float> tilemask_out(TS, TS);
|
array2D<float> tilemask_out(TS, TS);
|
||||||
@ -681,13 +680,13 @@ BENCHFUN
|
|||||||
|
|
||||||
for (int i = 0; i < TS; ++i) {
|
for (int i = 0; i < TS; ++i) {
|
||||||
float i1 = abs((i > TS / 2 ? i - TS + 1 : i));
|
float i1 = abs((i > TS / 2 ? i - TS + 1 : i));
|
||||||
float vmask = (i1 < border ? SQR(sin((rtengine::RT_PI * i1) / (2 * border))) : 1.0f);
|
float vmask = (i1 < border ? SQR(sin((rtengine::RT_PI_F * i1) / (2 * border))) : 1.f);
|
||||||
float vmask2 = (i1 < 2 * border ? SQR(sin((rtengine::RT_PI * i1) / (2 * border))) : 1.0f);
|
float vmask2 = (i1 < 2 * border ? SQR(sin((rtengine::RT_PI_F * i1) / (2 * border))) : 1.f);
|
||||||
|
|
||||||
for (int j = 0; j < TS; ++j) {
|
for (int j = 0; j < TS; ++j) {
|
||||||
float j1 = abs((j > TS / 2 ? j - TS + 1 : j));
|
float j1 = abs((j > TS / 2 ? j - TS + 1 : j));
|
||||||
tilemask_in[i][j] = (vmask * (j1 < border ? SQR(sin((rtengine::RT_PI * j1) / (2 * border))) : 1.0f)) + epsilon;
|
tilemask_in[i][j] = (vmask * (j1 < border ? SQR(sin((rtengine::RT_PI_F * j1) / (2 * border))) : 1.0f)) + epsilon;
|
||||||
tilemask_out[i][j] = (vmask2 * (j1 < 2 * border ? SQR(sin((rtengine::RT_PI * j1) / (2 * border))) : 1.0f)) + epsilon;
|
tilemask_out[i][j] = (vmask2 * (j1 < 2 * border ? SQR(sin((rtengine::RT_PI_F * j1) / (2 * border))) : 1.0f)) + epsilon;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -883,19 +882,19 @@ BENCHFUN
|
|||||||
int height = tilebottom - tiletop;
|
int height = tilebottom - tiletop;
|
||||||
int width2 = (width + 1) / 2;
|
int width2 = (width + 1) / 2;
|
||||||
float realred, realblue;
|
float realred, realblue;
|
||||||
float interm_med = static_cast<float>(dnparams.chroma) / 10.0;
|
float interm_med = dnparams.chroma / 10.0;
|
||||||
float intermred, intermblue;
|
float intermred, intermblue;
|
||||||
|
|
||||||
if (dnparams.redchro > 0.) {
|
if (dnparams.redchro > 0.) {
|
||||||
intermred = (dnparams.redchro / 10.);
|
intermred = dnparams.redchro / 10.0;
|
||||||
} else {
|
} else {
|
||||||
intermred = static_cast<float>(dnparams.redchro) / 7.0; //increase slower than linear for more sensit
|
intermred = dnparams.redchro / 7.0; //increase slower than linear for more sensit
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dnparams.bluechro > 0.) {
|
if (dnparams.bluechro > 0.) {
|
||||||
intermblue = (dnparams.bluechro / 10.);
|
intermblue = dnparams.bluechro / 10.0;
|
||||||
} else {
|
} else {
|
||||||
intermblue = static_cast<float>(dnparams.bluechro) / 7.0; //increase slower than linear for more sensit
|
intermblue = dnparams.bluechro / 7.0; //increase slower than linear for more sensit
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ponder && kall == 2) {
|
if (ponder && kall == 2) {
|
||||||
@ -1096,7 +1095,7 @@ BENCHFUN
|
|||||||
//binary 1 or 0 for each level, eg subsampling = 0 means no subsampling, 1 means subsample
|
//binary 1 or 0 for each level, eg subsampling = 0 means no subsampling, 1 means subsample
|
||||||
//the first level only, 7 means subsample the first three levels, etc.
|
//the first level only, 7 means subsample the first three levels, etc.
|
||||||
//actual implementation only works with subsampling set to 1
|
//actual implementation only works with subsampling set to 1
|
||||||
float interm_medT = static_cast<float>(dnparams.chroma) / 10.0;
|
float interm_medT = dnparams.chroma / 10.0;
|
||||||
bool execwavelet = true;
|
bool execwavelet = true;
|
||||||
|
|
||||||
if (!denoiseLuminance && interm_medT < 0.05f && dnparams.median && (dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly")) {
|
if (!denoiseLuminance && interm_medT < 0.05f && dnparams.median && (dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly")) {
|
||||||
@ -2121,7 +2120,7 @@ float ImProcFunctions::Mad(const float * DataList, const int datalen)
|
|||||||
int count_ = count - histo[median - 1];
|
int count_ = count - histo[median - 1];
|
||||||
|
|
||||||
// interpolate
|
// interpolate
|
||||||
return (((median - 1) + (datalen / 2 - count_) / (static_cast<float>(count - count_))) / 0.6745);
|
return (((median - 1) + (datalen / 2 - count_) / (static_cast<float>(count - count_))) / 0.6745f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float ImProcFunctions::MadRgb(const float * DataList, const int datalen)
|
float ImProcFunctions::MadRgb(const float * DataList, const int datalen)
|
||||||
@ -2155,7 +2154,7 @@ float ImProcFunctions::MadRgb(const float * DataList, const int datalen)
|
|||||||
|
|
||||||
// interpolate
|
// interpolate
|
||||||
delete[] histo;
|
delete[] histo;
|
||||||
return (((median - 1) + (datalen / 2 - count_) / (static_cast<float>(count - count_))) / 0.6745);
|
return (((median - 1) + (datalen / 2 - count_) / (static_cast<float>(count - count_))) / 0.6745f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2908,7 +2907,7 @@ void ImProcFunctions::RGB_denoise_infoGamCurve(const procparams::DirPyrDenoisePa
|
|||||||
bool denoiseMethodRgb = (dnparams.dmethod == "RGB");
|
bool denoiseMethodRgb = (dnparams.dmethod == "RGB");
|
||||||
|
|
||||||
if (denoiseMethodRgb) {
|
if (denoiseMethodRgb) {
|
||||||
gamslope = exp(log(static_cast<double>(gamthresh)) / gam) / gamthresh;
|
gamslope = exp(log(static_cast<double>(gamthresh)) / static_cast<double>(gam)) / static_cast<double>(gamthresh);
|
||||||
Color::gammaf2lut(gamcurve, gam, gamthresh, gamslope, 65535.f, 32768.f);
|
Color::gammaf2lut(gamcurve, gam, gamthresh, gamslope, 65535.f, 32768.f);
|
||||||
} else {
|
} else {
|
||||||
Color::gammanf2lut(gamcurve, gam, 65535.f, 32768.f);
|
Color::gammanf2lut(gamcurve, gam, 65535.f, 32768.f);
|
||||||
@ -3189,19 +3188,19 @@ void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
float realred, realblue;
|
float realred, realblue;
|
||||||
float interm_med = static_cast<float>(dnparams.chroma) / 10.0;
|
float interm_med = dnparams.chroma / 10.0;
|
||||||
float intermred, intermblue;
|
float intermred, intermblue;
|
||||||
|
|
||||||
if (dnparams.redchro > 0.) {
|
if (dnparams.redchro > 0.) {
|
||||||
intermred = (dnparams.redchro / 10.);
|
intermred = dnparams.redchro / 10.0;
|
||||||
} else {
|
} else {
|
||||||
intermred = static_cast<float>(dnparams.redchro) / 7.0; //increase slower than linear for more sensit
|
intermred = dnparams.redchro / 7.0; //increase slower than linear for more sensit
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dnparams.bluechro > 0.) {
|
if (dnparams.bluechro > 0.) {
|
||||||
intermblue = (dnparams.bluechro / 10.);
|
intermblue = dnparams.bluechro / 10.0;
|
||||||
} else {
|
} else {
|
||||||
intermblue = static_cast<float>(dnparams.bluechro) / 7.0; //increase slower than linear for more sensit
|
intermblue = dnparams.bluechro / 7.0; //increase slower than linear for more sensit
|
||||||
}
|
}
|
||||||
|
|
||||||
realred = interm_med + intermred;
|
realred = interm_med + intermred;
|
||||||
|
@ -103,7 +103,7 @@ void ImProcFunctions::PF_correct_RT(LabImage * lab, double radius, int thresh)
|
|||||||
// no precalculated values without SSE => calculate
|
// no precalculated values without SSE => calculate
|
||||||
const float HH = xatan2f(lab->b[i][j], lab->a[i][j]);
|
const float HH = xatan2f(lab->b[i][j], lab->a[i][j]);
|
||||||
#endif
|
#endif
|
||||||
float chparam = chCurve->getVal((Color::huelab_to_huehsv2(HH))) - 0.5f; // get C=f(H)
|
float chparam = chCurve->getVal((Color::huelab_to_huehsv2(HH))) - 0.5; // get C=f(H)
|
||||||
|
|
||||||
if (chparam < 0.f) {
|
if (chparam < 0.f) {
|
||||||
chparam *= 2.f; // increased action if chparam < 0
|
chparam *= 2.f; // increased action if chparam < 0
|
||||||
@ -113,25 +113,25 @@ void ImProcFunctions::PF_correct_RT(LabImage * lab, double radius, int thresh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const float chroma = chromaChfactor * (SQR(lab->a[i][j] - tmpa[i][j]) + SQR(lab->b[i][j] - tmpb[i][j])); // modulate chroma function hue
|
const float chroma = chromaChfactor * (SQR(lab->a[i][j] - tmpa[i][j]) + SQR(lab->b[i][j] - tmpb[i][j])); // modulate chroma function hue
|
||||||
chromave += chroma;
|
chromave += static_cast<double>(chroma);
|
||||||
fringe[i * width + j] = chroma;
|
fringe[i * width + j] = chroma;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chromave /= height * width;
|
chromave /= height * width;
|
||||||
|
|
||||||
if (chromave > 0.0) {
|
if (chromave > 0.0) {
|
||||||
// now as chromave is calculated, we postprocess fringe to reduce the number of divisions in future
|
// now as chromave is calculated, we postprocess fringe to reduce the number of divisions in future
|
||||||
|
const float chromavef = chromave;
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for simd
|
#pragma omp parallel for simd
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int j = 0; j < width * height; j++) {
|
for (int j = 0; j < width * height; j++) {
|
||||||
fringe[j] = 1.f / (fringe[j] + chromave);
|
fringe[j] = 1.f / (fringe[j] + chromavef);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float threshfactor = 1.f / (SQR(thresh / 33.f) * chromave * 5.0f + chromave);
|
const float threshfactor = 1.f / (SQR(thresh / 33.f) * chromavef * 5.0f + chromavef);
|
||||||
const int halfwin = std::ceil(2 * radius) + 1;
|
const int halfwin = std::ceil(2 * radius) + 1;
|
||||||
|
|
||||||
// Issue 1674:
|
// Issue 1674:
|
||||||
@ -297,7 +297,7 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * ncie, double radius, int thres
|
|||||||
// no precalculated values without SSE => calculate
|
// no precalculated values without SSE => calculate
|
||||||
const float HH = xatan2f(srbb[i][j], sraa[i][j]);
|
const float HH = xatan2f(srbb[i][j], sraa[i][j]);
|
||||||
#endif
|
#endif
|
||||||
float chparam = chCurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f; //get C=f(H)
|
float chparam = chCurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5; //get C=f(H)
|
||||||
|
|
||||||
if (chparam < 0.f) {
|
if (chparam < 0.f) {
|
||||||
chparam *= 2.f; // increase action if chparam < 0
|
chparam *= 2.f; // increase action if chparam < 0
|
||||||
@ -307,7 +307,7 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * ncie, double radius, int thres
|
|||||||
}
|
}
|
||||||
|
|
||||||
const float chroma = chromaChfactor * (SQR(sraa[i][j] - tmaa[i][j]) + SQR(srbb[i][j] - tmbb[i][j])); //modulate chroma function hue
|
const float chroma = chromaChfactor * (SQR(sraa[i][j] - tmaa[i][j]) + SQR(srbb[i][j] - tmbb[i][j])); //modulate chroma function hue
|
||||||
chromave += chroma;
|
chromave += static_cast<double>(chroma);
|
||||||
fringe[i * width + j] = chroma;
|
fringe[i * width + j] = chroma;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -317,15 +317,16 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * ncie, double radius, int thres
|
|||||||
|
|
||||||
if (chromave > 0.0) {
|
if (chromave > 0.0) {
|
||||||
// now as chromave is calculated, we postprocess fringe to reduce the number of divisions in future
|
// now as chromave is calculated, we postprocess fringe to reduce the number of divisions in future
|
||||||
|
const float chromavef = chromave;
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for simd
|
#pragma omp parallel for simd
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int j = 0; j < width * height; j++) {
|
for (int j = 0; j < width * height; j++) {
|
||||||
fringe[j] = 1.f / (fringe[j] + chromave);
|
fringe[j] = 1.f / (fringe[j] + chromavef);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float threshfactor = 1.f / (SQR(thresh / 33.f) * chromave * 5.0f + chromave);
|
const float threshfactor = 1.f / (SQR(thresh / 33.f) * chromavef * 5.0f + chromavef);
|
||||||
const int halfwin = std::ceil(2 * radius) + 1;
|
const int halfwin = std::ceil(2 * radius) + 1;
|
||||||
|
|
||||||
// Issue 1674:
|
// Issue 1674:
|
||||||
@ -695,7 +696,7 @@ void ImProcFunctions::Badpixelscam(CieImage * ncie, double radius, int thresh, i
|
|||||||
for (int i = 0; i < height; i++) {
|
for (int i = 0; i < height; i++) {
|
||||||
for (int j = 0; j < width; j++) {
|
for (int j = 0; j < width; j++) {
|
||||||
const float chroma = SQR(sraa[i][j] - tmaa[i][j]) + SQR(srbb[i][j] - tmbb[i][j]);
|
const float chroma = SQR(sraa[i][j] - tmaa[i][j]) + SQR(srbb[i][j] - tmbb[i][j]);
|
||||||
chrommed += chroma;
|
chrommed += static_cast<double>(chroma);
|
||||||
badpix[i * width + j] = chroma;
|
badpix[i * width + j] = chroma;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -703,15 +704,16 @@ void ImProcFunctions::Badpixelscam(CieImage * ncie, double radius, int thresh, i
|
|||||||
chrommed /= height * width;
|
chrommed /= height * width;
|
||||||
|
|
||||||
if (chrommed > 0.0) {
|
if (chrommed > 0.0) {
|
||||||
|
const float chrommedf = chrommed;
|
||||||
// now as chrommed is calculated, we postprocess badpix to reduce the number of divisions in future
|
// now as chrommed is calculated, we postprocess badpix to reduce the number of divisions in future
|
||||||
const float threshfactor = 1.f / ((thresh * chrommed) / 33.f + chrommed);
|
const float threshfactor = 1.f / ((thresh * chrommedf) / 33.f + chrommedf);
|
||||||
const int halfwin = std::ceil(2 * radius) + 1;
|
const int halfwin = std::ceil(2 * radius) + 1;
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
const vfloat chrommedv = F2V(chrommed);
|
const vfloat chrommedv = F2V(chrommedf);
|
||||||
const vfloat onev = F2V(1.f);
|
const vfloat onev = F2V(1.f);
|
||||||
#endif
|
#endif
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
@ -726,7 +728,7 @@ void ImProcFunctions::Badpixelscam(CieImage * ncie, double radius, int thresh, i
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
for (; j < width; j++) {
|
for (; j < width; j++) {
|
||||||
badpix[i * width + j] = 1.f / (badpix[i * width + j] + chrommed);
|
badpix[i * width + j] = 1.f / (badpix[i * width + j] + chrommedf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1040,7 +1042,7 @@ void ImProcFunctions::BadpixelsLab(LabImage * lab, double radius, int thresh, fl
|
|||||||
for (int i = 0; i < height; i++) {
|
for (int i = 0; i < height; i++) {
|
||||||
for (int j = 0; j < width; j++) {
|
for (int j = 0; j < width; j++) {
|
||||||
const float chroma = SQR(lab->a[i][j] - tmaa[i][j]) + SQR(lab->b[i][j] - tmbb[i][j]);
|
const float chroma = SQR(lab->a[i][j] - tmaa[i][j]) + SQR(lab->b[i][j] - tmbb[i][j]);
|
||||||
chrommed += chroma;
|
chrommed += static_cast<double>(chroma);
|
||||||
badpix[i * width + j] = chroma;
|
badpix[i * width + j] = chroma;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1049,13 +1051,13 @@ void ImProcFunctions::BadpixelsLab(LabImage * lab, double radius, int thresh, fl
|
|||||||
|
|
||||||
if (chrommed > 0.0) {
|
if (chrommed > 0.0) {
|
||||||
// now as chrommed is calculated, we postprocess badpix to reduce the number of divisions in future
|
// now as chrommed is calculated, we postprocess badpix to reduce the number of divisions in future
|
||||||
|
const float chrommedf = chrommed;
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
const vfloat chrommedv = F2V(chrommed);
|
const vfloat chrommedv = F2V(chrommedf);
|
||||||
const vfloat onev = F2V(1.f);
|
const vfloat onev = F2V(1.f);
|
||||||
#endif
|
#endif
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
@ -1070,12 +1072,12 @@ void ImProcFunctions::BadpixelsLab(LabImage * lab, double radius, int thresh, fl
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
for (; j < width; j++) {
|
for (; j < width; j++) {
|
||||||
badpix[i * width + j] = 1.f / (badpix[i * width + j] + chrommed);
|
badpix[i * width + j] = 1.f / (badpix[i * width + j] + chrommedf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const float threshfactor = 1.f / ((thresh * chrommed) / 33.f + chrommed);
|
const float threshfactor = 1.f / ((thresh * chrommedf) / 33.f + chrommedf);
|
||||||
|
|
||||||
chrom *= 327.68f;
|
chrom *= 327.68f;
|
||||||
chrom *= chrom;
|
chrom *= chrom;
|
||||||
|
@ -52,13 +52,13 @@ void RawImageSource::ahd_demosaic()
|
|||||||
|
|
||||||
int width = W, height = H;
|
int width = W, height = H;
|
||||||
|
|
||||||
constexpr double xyz_rgb[3][3] = { /* XYZ from RGB */
|
constexpr float xyz_rgb[3][3] = { /* XYZ from RGB */
|
||||||
{ 0.412453, 0.357580, 0.180423 },
|
{ 0.412453f, 0.357580f, 0.180423f },
|
||||||
{ 0.212671, 0.715160, 0.072169 },
|
{ 0.212671f, 0.715160f, 0.072169f },
|
||||||
{ 0.019334, 0.119193, 0.950227 }
|
{ 0.019334f, 0.119193f, 0.950227f }
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr float d65_white[3] = { 0.950456, 1, 1.088754 };
|
constexpr float d65_white[3] = { 0.950456f, 1.f, 1.088754f };
|
||||||
|
|
||||||
double progress = 0.0;
|
double progress = 0.0;
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ void RawImageSource::ahd_demosaic()
|
|||||||
for (unsigned int j = 0; j < 3; j++) {
|
for (unsigned int j = 0; j < 3; j++) {
|
||||||
xyz_cam[i][j] = 0;
|
xyz_cam[i][j] = 0;
|
||||||
for (int k = 0; k < 3; k++) {
|
for (int k = 0; k < 3; k++) {
|
||||||
xyz_cam[i][j] += xyz_rgb[i][k] * imatrices.rgb_cam[k][j] / d65_white[i];
|
xyz_cam[i][j] += xyz_rgb[i][k] * static_cast<float>(imatrices.rgb_cam[k][j]) / d65_white[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -477,7 +477,7 @@ int RawImageSource::interpolateBadPixelsXtrans(const PixelsMap &bitmapBads)
|
|||||||
int RawImageSource::findHotDeadPixels(PixelsMap &bpMap, const float thresh, const bool findHotPixels, const bool findDeadPixels) const
|
int RawImageSource::findHotDeadPixels(PixelsMap &bpMap, const float thresh, const bool findHotPixels, const bool findDeadPixels) const
|
||||||
{
|
{
|
||||||
BENCHFUN
|
BENCHFUN
|
||||||
const float varthresh = (20.0 * (thresh / 100.0) + 1.0) / 24.f;
|
const float varthresh = (20.f * (thresh / 100.f) + 1.f) / 24.f;
|
||||||
|
|
||||||
// counter for dead or hot pixels
|
// counter for dead or hot pixels
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
|
@ -5,8 +5,8 @@ locations (before and after tracking) to text files and to PPM files,
|
|||||||
and prints the features to the screen.
|
and prints the features to the screen.
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#include "klt/pnmio.h"
|
#include <pnmio.h>
|
||||||
#include "klt/klt.h"
|
#include <klt.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
@ -553,7 +553,7 @@ CameraConst::get_Levels(struct camera_const_levels & lvl, int bw, int iso, float
|
|||||||
float av = (avh - 1) + (float)k / 3;
|
float av = (avh - 1) + (float)k / 3;
|
||||||
float aperture = sqrtf(powf(2, av));
|
float aperture = sqrtf(powf(2, av));
|
||||||
|
|
||||||
if (fnumber > aperture * 0.97 && fnumber < aperture / 0.97) {
|
if (fnumber > aperture * 0.97f && fnumber < aperture / 0.97f) {
|
||||||
fnumber = fn_tab[avh][k];
|
fnumber = fn_tab[avh][k];
|
||||||
it = mApertureScaling.find(fnumber);
|
it = mApertureScaling.find(fnumber);
|
||||||
avh = 7;
|
avh = 7;
|
||||||
@ -579,7 +579,7 @@ CameraConst::get_Levels(struct camera_const_levels & lvl, int bw, int iso, float
|
|||||||
scaling = it->second;
|
scaling = it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scaling > 1.0) {
|
if (scaling > 1.f) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
lvl.levels[i] *= scaling;
|
lvl.levels[i] *= scaling;
|
||||||
|
|
||||||
@ -638,7 +638,7 @@ CameraConst::update_globalGreenEquilibration(bool other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CameraConstantsStore::parse_camera_constants_file(Glib::ustring filename_)
|
CameraConstantsStore::parse_camera_constants_file(const Glib::ustring& filename_)
|
||||||
{
|
{
|
||||||
// read the file into a single long string
|
// read the file into a single long string
|
||||||
const char *filename = filename_.c_str();
|
const char *filename = filename_.c_str();
|
||||||
@ -809,7 +809,7 @@ CameraConstantsStore::~CameraConstantsStore()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraConstantsStore::init(Glib::ustring baseDir, Glib::ustring userSettingsDir)
|
void CameraConstantsStore::init(const Glib::ustring& baseDir, const Glib::ustring& userSettingsDir)
|
||||||
{
|
{
|
||||||
parse_camera_constants_file(Glib::build_filename(baseDir, "camconst.json"));
|
parse_camera_constants_file(Glib::build_filename(baseDir, "camconst.json"));
|
||||||
|
|
||||||
|
@ -3,10 +3,17 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <glibmm/ustring.h>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Glib
|
||||||
|
{
|
||||||
|
|
||||||
|
class ustring;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -14,7 +21,7 @@ struct camera_const_levels {
|
|||||||
int levels[4];
|
int levels[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
class CameraConst
|
class CameraConst final
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string make_model;
|
std::string make_model;
|
||||||
@ -56,17 +63,17 @@ public:
|
|||||||
void update_globalGreenEquilibration(bool other);
|
void update_globalGreenEquilibration(bool other);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CameraConstantsStore
|
class CameraConstantsStore final
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::map<std::string, CameraConst *> mCameraConstants;
|
std::map<std::string, CameraConst *> mCameraConstants;
|
||||||
|
|
||||||
CameraConstantsStore();
|
CameraConstantsStore();
|
||||||
bool parse_camera_constants_file(Glib::ustring filename);
|
bool parse_camera_constants_file(const Glib::ustring& filename);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~CameraConstantsStore();
|
~CameraConstantsStore();
|
||||||
void init(Glib::ustring baseDir, Glib::ustring userSettingsDir);
|
void init(const Glib::ustring& baseDir, const Glib::ustring& userSettingsDir);
|
||||||
static CameraConstantsStore *getInstance(void);
|
static CameraConstantsStore *getInstance(void);
|
||||||
CameraConst *get(const char make[], const char model[]);
|
CameraConst *get(const char make[], const char model[]);
|
||||||
};
|
};
|
||||||
|
@ -1221,7 +1221,7 @@ Camera constants:
|
|||||||
|
|
||||||
{ // Quality A, changes for raw crop which is wrong (larger) in dcraw
|
{ // Quality A, changes for raw crop which is wrong (larger) in dcraw
|
||||||
"make_model": "Canon PowerShot S120",
|
"make_model": "Canon PowerShot S120",
|
||||||
"dcraw_matrix": [ 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 ],
|
"dcraw_matrix": [ 6961, -1685, -695, -4625, 12945, 1836, -1114, 2152, 5518 ], // ColorMatrix2 using illuminant D65 from Adobe DNG Converter 12.2
|
||||||
"raw_crop": [ 120, 30, 4024, 3030 ],
|
"raw_crop": [ 120, 30, 4024, 3030 ],
|
||||||
"masked_areas": [ 32, 2, 3028, 80 ],
|
"masked_areas": [ 32, 2, 3028, 80 ],
|
||||||
"ranges": { "white": 4050 }
|
"ranges": { "white": 4050 }
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Code adapted from ART
|
// Code adapted from ART
|
||||||
|
// https://bitbucket.org/agriggio/art/
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* This file is part of ART.
|
* This file is part of ART.
|
||||||
@ -37,11 +38,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Code adapted from libraw
|
// Code adapted from libraw
|
||||||
/* -*- C++ -*-
|
// https://github.com/LibRaw/LibRaw/
|
||||||
* Copyright 2019 LibRaw LLC (info@libraw.org)
|
/*
|
||||||
|
* File: libraw_crxdec.cpp
|
||||||
|
* Copyright (C) 2018-2019 Alexey Danilchenko
|
||||||
|
* Copyright (C) 2019 Alex Tutubalin, LibRaw LLC
|
||||||
*
|
*
|
||||||
LibRaw is free software; you can redistribute it and/or modify
|
Canon CR3 file decoder
|
||||||
it under the terms of the one of two licenses as you choose:
|
|
||||||
|
LibRaw is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the one of two licenses as you choose:
|
||||||
|
|
||||||
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
|
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
|
||||||
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
|
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
|
||||||
@ -49,7 +55,7 @@
|
|||||||
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
|
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
|
||||||
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
|
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -761,13 +761,13 @@ bool checkForStop(float** tmpIThr, float** iterCheck, int fullTileSize, int bord
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureDeconvSharpening (float** luminance, const float* const * oldLuminance, const float * const * blend, int W, int H, double sigma, double sigmaCornerOffset, int iterations, bool checkIterStop, rtengine::ProgressListener* plistener, double startVal, double endVal)
|
void CaptureDeconvSharpening (float** luminance, const float* const * oldLuminance, const float * const * blend, int W, int H, float sigma, float sigmaCornerOffset, int iterations, bool checkIterStop, rtengine::ProgressListener* plistener, double startVal, double endVal)
|
||||||
{
|
{
|
||||||
BENCHFUN
|
BENCHFUN
|
||||||
const bool is9x9 = (sigma <= 1.50 && sigmaCornerOffset == 0.0);
|
const bool is9x9 = (sigma <= 1.5f && sigmaCornerOffset == 0.f);
|
||||||
const bool is7x7 = (sigma <= 1.15 && sigmaCornerOffset == 0.0);
|
const bool is7x7 = (sigma <= 1.15f && sigmaCornerOffset == 0.f);
|
||||||
const bool is5x5 = (sigma <= 0.84 && sigmaCornerOffset == 0.0);
|
const bool is5x5 = (sigma <= 0.84f && sigmaCornerOffset == 0.f);
|
||||||
const bool is3x3 = (sigma < 0.6 && sigmaCornerOffset == 0.0);
|
const bool is3x3 = (sigma < 0.6f && sigmaCornerOffset == 0.f);
|
||||||
float kernel13[13][13];
|
float kernel13[13][13];
|
||||||
float kernel9[9][9];
|
float kernel9[9][9];
|
||||||
float kernel7[7][7];
|
float kernel7[7][7];
|
||||||
@ -906,11 +906,11 @@ BENCHFUN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (sigmaCornerOffset != 0.0) {
|
if (sigmaCornerOffset != 0.f) {
|
||||||
const float distance = sqrt(rtengine::SQR(i + tileSize / 2 - H / 2) + rtengine::SQR(j + tileSize / 2 - W / 2));
|
const float distance = sqrt(rtengine::SQR(i + tileSize / 2 - H / 2) + rtengine::SQR(j + tileSize / 2 - W / 2));
|
||||||
const float sigmaTile = static_cast<float>(sigma) + distanceFactor * distance;
|
const float sigmaTile = static_cast<float>(sigma) + distanceFactor * distance;
|
||||||
if (sigmaTile >= 0.4f) {
|
if (sigmaTile >= 0.4f) {
|
||||||
if (sigmaTile > 1.50) { // have to use 13x13 kernel
|
if (sigmaTile > 1.5f) { // have to use 13x13 kernel
|
||||||
float lkernel13[13][13];
|
float lkernel13[13][13];
|
||||||
compute13x13kernel(static_cast<float>(sigma) + distanceFactor * distance, lkernel13);
|
compute13x13kernel(static_cast<float>(sigma) + distanceFactor * distance, lkernel13);
|
||||||
for (int k = 0; k < iterations; ++k) {
|
for (int k = 0; k < iterations; ++k) {
|
||||||
@ -921,7 +921,7 @@ BENCHFUN
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (sigmaTile > 1.15) { // have to use 9x9 kernel
|
} else if (sigmaTile > 1.15f) { // have to use 9x9 kernel
|
||||||
float lkernel9[9][9];
|
float lkernel9[9][9];
|
||||||
compute9x9kernel(static_cast<float>(sigma) + distanceFactor * distance, lkernel9);
|
compute9x9kernel(static_cast<float>(sigma) + distanceFactor * distance, lkernel9);
|
||||||
for (int k = 0; k < iterations; ++k) {
|
for (int k = 0; k < iterations; ++k) {
|
||||||
@ -932,7 +932,7 @@ BENCHFUN
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (sigmaTile > 0.84) { // have to use 7x7 kernel
|
} else if (sigmaTile > 0.84f) { // have to use 7x7 kernel
|
||||||
float lkernel7[7][7];
|
float lkernel7[7][7];
|
||||||
compute7x7kernel(static_cast<float>(sigma) + distanceFactor * distance, lkernel7);
|
compute7x7kernel(static_cast<float>(sigma) + distanceFactor * distance, lkernel7);
|
||||||
for (int k = 0; k < iterations; ++k) {
|
for (int k = 0; k < iterations; ++k) {
|
||||||
@ -1021,7 +1021,7 @@ BENCHFUN
|
|||||||
{ 0.019334, 0.119193, 0.950227 }
|
{ 0.019334, 0.119193, 0.950227 }
|
||||||
};
|
};
|
||||||
|
|
||||||
float contrast = conrastThreshold / 100.f;
|
float contrast = conrastThreshold / 100.0;
|
||||||
|
|
||||||
const float clipVal = (ri->get_white(1) - ri->get_cblack(1)) * scale_mul[1];
|
const float clipVal = (ri->get_white(1) - ri->get_cblack(1)) * scale_mul[1];
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef CLIPD
|
#undef CLIPD
|
||||||
#define CLIPD(a) ((a)>0.0?((a)<1.0?(a):1.0):0.0)
|
#define CLIPD(a) ((a)>0.f?((a)<1.f?(a):1.f):0.f)
|
||||||
#define MAXR(a,b) ((a) > (b) ? (a) : (b))
|
#define MAXR(a,b) ((a) > (b) ? (a) : (b))
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
@ -408,7 +408,7 @@ void Ciecam02::initcam1float (float yb, float pilotd, float f, float la, float x
|
|||||||
{
|
{
|
||||||
n = yb / yw;
|
n = yb / yw;
|
||||||
|
|
||||||
if (pilotd == 2.0) {
|
if (pilotd == 2.f) {
|
||||||
d = d_factorfloat ( f, la );
|
d = d_factorfloat ( f, la );
|
||||||
} else {
|
} else {
|
||||||
d = pilotd;
|
d = pilotd;
|
||||||
@ -434,7 +434,7 @@ void Ciecam02::initcam2float (float yb, float pilotd, float f, float la, float x
|
|||||||
{
|
{
|
||||||
n = yb / yw;
|
n = yb / yw;
|
||||||
|
|
||||||
if (pilotd == 2.0) {
|
if (pilotd == 2.f) {
|
||||||
d = d_factorfloat ( f, la );
|
d = d_factorfloat ( f, la );
|
||||||
} else {
|
} else {
|
||||||
d = pilotd;
|
d = pilotd;
|
||||||
@ -492,7 +492,7 @@ void Ciecam02::xyz2jchqms_ciecam02float ( float &J, float &C, float &h, float &Q
|
|||||||
myh = xatan2f ( cb, ca );
|
myh = xatan2f ( cb, ca );
|
||||||
|
|
||||||
if ( myh < 0.0f ) {
|
if ( myh < 0.0f ) {
|
||||||
myh += (2.f * rtengine::RT_PI);
|
myh += (2.f * rtengine::RT_PI_F);
|
||||||
}
|
}
|
||||||
|
|
||||||
a = ((2.0f * rpa) + gpa + (0.05f * bpa) - 0.305f) * nbb;
|
a = ((2.0f * rpa) + gpa + (0.05f * bpa) - 0.305f) * nbb;
|
||||||
@ -620,7 +620,7 @@ void Ciecam02::xyz2jch_ciecam02float ( float &J, float &C, float &h, float aw, f
|
|||||||
myh = xatan2f ( cb, ca );
|
myh = xatan2f ( cb, ca );
|
||||||
|
|
||||||
if ( myh < 0.0f ) {
|
if ( myh < 0.0f ) {
|
||||||
myh += (2.f * rtengine::RT_PI);
|
myh += (2.f * rtengine::RT_PI_F);
|
||||||
}
|
}
|
||||||
|
|
||||||
a = ((2.0f * rpa) + gpa + (0.05f * bpa) - 0.305f) * nbb;
|
a = ((2.0f * rpa) + gpa + (0.05f * bpa) - 0.305f) * nbb;
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
class CieImage :
|
class CieImage final :
|
||||||
public NonCopyable
|
public NonCopyable
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
1379
rtengine/color.cc
1379
rtengine/color.cc
File diff suppressed because it is too large
Load Diff
@ -20,15 +20,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <glibmm/ustring.h>
|
|
||||||
|
|
||||||
#include "rt_math.h"
|
#include "rt_math.h"
|
||||||
#include "LUT.h"
|
#include "LUT.h"
|
||||||
#include "iccmatrices.h"
|
|
||||||
#include "lcms2.h"
|
#include "lcms2.h"
|
||||||
#include "sleef.h"
|
#include "sleef.h"
|
||||||
|
|
||||||
#define SAT(a,b,c) ((float)max(a,b,c)-(float)min(a,b,c))/(float)max(a,b,c)
|
namespace Glib
|
||||||
|
{
|
||||||
|
class ustring;
|
||||||
|
}
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
@ -132,7 +133,7 @@ public:
|
|||||||
constexpr static double sRGBGammaCurve = 2.4;
|
constexpr static double sRGBGammaCurve = 2.4;
|
||||||
|
|
||||||
constexpr static double eps = 216.0 / 24389.0; //0.008856
|
constexpr static double eps = 216.0 / 24389.0; //0.008856
|
||||||
constexpr static double eps_max = MAXVALF * eps; //580.40756;
|
constexpr static double eps_max = MAXVALD * eps; //580.40756;
|
||||||
constexpr static double kappa = 24389.0 / 27.0; //903.29630;
|
constexpr static double kappa = 24389.0 / 27.0; //903.29630;
|
||||||
constexpr static double kappaInv = 27.0 / 24389.0;
|
constexpr static double kappaInv = 27.0 / 24389.0;
|
||||||
constexpr static double epsilonExpInv3 = 6.0 / 29.0;
|
constexpr static double epsilonExpInv3 = 6.0 / 29.0;
|
||||||
@ -144,9 +145,10 @@ public:
|
|||||||
|
|
||||||
constexpr static float D50x = 0.9642f; //0.96422;
|
constexpr static float D50x = 0.9642f; //0.96422;
|
||||||
constexpr static float D50z = 0.8249f; //0.82521;
|
constexpr static float D50z = 0.8249f; //0.82521;
|
||||||
constexpr static double u0 = 4.0 * D50x / (D50x + 15 + 3 * D50z);
|
constexpr static double u0 = 4.0 * static_cast<double>(D50x) / (static_cast<double>(D50x) + 15 + 3 * static_cast<double>(D50z));
|
||||||
constexpr static double v0 = 9.0 / (D50x + 15 + 3 * D50z);
|
constexpr static double v0 = 9.0 / (static_cast<double>(D50x) + 15 + 3 * static_cast<double>(D50z));
|
||||||
constexpr static double epskap = 8.0;
|
constexpr static double epskap = 8.0;
|
||||||
|
constexpr static float epskapf = epskap;
|
||||||
|
|
||||||
constexpr static float c1By116 = 1.0 / 116.0;
|
constexpr static float c1By116 = 1.0 / 116.0;
|
||||||
constexpr static float c16By116 = 16.0 / 116.0;
|
constexpr static float c16By116 = 16.0 / 116.0;
|
||||||
@ -206,7 +208,7 @@ public:
|
|||||||
|
|
||||||
static float rgbLuminance(float r, float g, float b, const double workingspace[3][3])
|
static float rgbLuminance(float r, float g, float b, const double workingspace[3][3])
|
||||||
{
|
{
|
||||||
return r * workingspace[1][0] + g * workingspace[1][1] + b * workingspace[1][2];
|
return static_cast<double>(r) * workingspace[1][0] + static_cast<double>(g) * workingspace[1][1] + static_cast<double>(b) * workingspace[1][2];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
@ -972,10 +974,10 @@ public:
|
|||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
static inline T interpolatePolarHue_PI (T h1, T h2, U balance)
|
static inline T interpolatePolarHue_PI (T h1, T h2, U balance)
|
||||||
{
|
{
|
||||||
float d = h2 - h1;
|
T d = h2 - h1;
|
||||||
float f;
|
T f;
|
||||||
f = T(balance);
|
f = T(balance);
|
||||||
double h;
|
T h;
|
||||||
|
|
||||||
if (h1 > h2) {
|
if (h1 > h2) {
|
||||||
std::swap(h1, h2);
|
std::swap(h1, h2);
|
||||||
@ -986,7 +988,7 @@ public:
|
|||||||
if (d < T(0) || d < T(0.5) || d > T(1.)) { //there was an inversion here !! d > T(rtengine::RT_PI)
|
if (d < T(0) || d < T(0.5) || d > T(1.)) { //there was an inversion here !! d > T(rtengine::RT_PI)
|
||||||
h1 += T(1.);
|
h1 += T(1.);
|
||||||
h = h1 + f * (h2 - h1);
|
h = h1 + f * (h2 - h1);
|
||||||
h = std::fmod(h, 1.);
|
h = std::fmod(h, T(1.));
|
||||||
} else {
|
} else {
|
||||||
h = h1 + f * d;
|
h = h1 + f * d;
|
||||||
}
|
}
|
||||||
|
@ -1071,10 +1071,10 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
|
|||||||
double Xwb, Zwb;
|
double Xwb, Zwb;
|
||||||
temp2mulxyz(temp, method, Xwb, Zwb);
|
temp2mulxyz(temp, method, Xwb, Zwb);
|
||||||
|
|
||||||
float adj = 1.f;
|
double adj = 1.0;
|
||||||
|
|
||||||
if(equal < 0.9999 || equal > 1.0001 ) {
|
if(equal < 0.9999 || equal > 1.0001 ) {
|
||||||
adj = (100.f + ( 1000.f - (1000.f * (float)equal) ) / 20.f) / 100.f;
|
adj = (100.0 + ( 1000.0 - (1000.0 * equal) ) / 20.0) / 100.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1389,7 +1389,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < 8; i++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
CRIs[i] = 100 - 3.0 * DeltaEs[i]; //3.0 coef to adapt ==> same results than CRI "official"
|
CRIs[i] = 100 - 3.f * DeltaEs[i]; //3.0 coef to adapt ==> same results than CRI "official"
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < 8; i++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
@ -1409,7 +1409,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < N_c; i++) {
|
for(int i = 0; i < N_c; i++) {
|
||||||
CRI[i] = 100 - 3.0 * DeltaE[i]; //3.0 coef to adapt ==> same results than CRI "official"
|
CRI[i] = 100 - 3.f * DeltaE[i]; //3.0 coef to adapt ==> same results than CRI "official"
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < N_c; i++) {
|
for(int i = 0; i < N_c; i++) {
|
||||||
@ -1425,8 +1425,8 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
|
|||||||
quadCRI /= N_c;
|
quadCRI /= N_c;
|
||||||
|
|
||||||
if(settings->CRI_color != 0) {
|
if(settings->CRI_color != 0) {
|
||||||
printf("CRI_standard=%i CRI:1->8=%i %i %i %i %i %i %i %i Sigma=%2.1f\n", (int) CRI_RTs, (int) CRIs[0], (int) CRIs[1], (int) CRIs[2], (int) CRIs[3], (int) CRIs[4], (int) CRIs[5], (int) CRIs[6], (int) CRIs[7], sqrt(quadCRIs));
|
printf("CRI_standard=%i CRI:1->8=%i %i %i %i %i %i %i %i Sigma=%2.1f\n", (int) CRI_RTs, (int) CRIs[0], (int) CRIs[1], (int) CRIs[2], (int) CRIs[3], (int) CRIs[4], (int) CRIs[5], (int) CRIs[6], (int) CRIs[7], sqrt(static_cast<double>(quadCRIs)));
|
||||||
printf("CRI_RT_exten=%i CRI:9->20=%i %i %i %i %i %i %i %i %i %i %i %i Sigma=%2.1f\n", (int) CRI_RT, (int) CRI[8], (int) CRI[9], (int) CRI[10], (int) CRI[11], (int) CRI[12], (int) CRI[13], (int) CRI[14], (int) CRI[15], (int) CRI[16], (int) CRI[17], (int) CRI[18], (int) CRI[19], sqrt(quadCRI));
|
printf("CRI_RT_exten=%i CRI:9->20=%i %i %i %i %i %i %i %i %i %i %i %i Sigma=%2.1f\n", (int) CRI_RT, (int) CRI[8], (int) CRI[9], (int) CRI[10], (int) CRI[11], (int) CRI[12], (int) CRI[13], (int) CRI[14], (int) CRI[15], (int) CRI[16], (int) CRI[17], (int) CRI[18], (int) CRI[19], static_cast<double>(sqrt(quadCRI)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <glib.h>
|
#include <glibmm/ustring.h>
|
||||||
#include <glib/gstdio.h>
|
|
||||||
|
|
||||||
#include "rt_math.h"
|
#include "rt_math.h"
|
||||||
|
|
||||||
@ -33,6 +32,7 @@
|
|||||||
#include "opthelper.h"
|
#include "opthelper.h"
|
||||||
#include "ciecam02.h"
|
#include "ciecam02.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
|
#include "iccmatrices.h"
|
||||||
#include "iccstore.h"
|
#include "iccstore.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -2186,7 +2186,7 @@ void PerceptualToneCurve::init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerceptualToneCurve::initApplyState(PerceptualToneCurveState & state, Glib::ustring workingSpace) const
|
void PerceptualToneCurve::initApplyState(PerceptualToneCurveState & state, const Glib::ustring &workingSpace) const
|
||||||
{
|
{
|
||||||
|
|
||||||
// Get the curve's contrast value, and convert to a chroma scaling
|
// Get the curve's contrast value, and convert to a chroma scaling
|
||||||
|
@ -22,21 +22,23 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <glibmm/ustring.h>
|
|
||||||
|
|
||||||
#include "rt_math.h"
|
#include "rt_math.h"
|
||||||
#include "flatcurvetypes.h"
|
#include "flatcurvetypes.h"
|
||||||
#include "diagonalcurvetypes.h"
|
#include "diagonalcurvetypes.h"
|
||||||
#include "pipettebuffer.h"
|
|
||||||
#include "noncopyable.h"
|
#include "noncopyable.h"
|
||||||
#include "LUT.h"
|
#include "LUT.h"
|
||||||
#include "sleef.h"
|
#include "sleef.h"
|
||||||
#define CURVES_MIN_POLY_POINTS 1000
|
#define CURVES_MIN_POLY_POINTS 1000
|
||||||
|
|
||||||
#include "rt_math.h"
|
|
||||||
|
|
||||||
#define CLIPI(a) ((a)>0?((a)<65534?(a):65534):0)
|
#define CLIPI(a) ((a)>0?((a)<65534?(a):65534):0)
|
||||||
|
|
||||||
|
namespace Glib
|
||||||
|
{
|
||||||
|
|
||||||
|
class ustring;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
@ -292,11 +294,11 @@ public:
|
|||||||
}
|
}
|
||||||
static inline float gamma2 (float x)
|
static inline float gamma2 (float x)
|
||||||
{
|
{
|
||||||
return x <= 0.00304 ? x * 12.92310 : 1.055 * expf(logf(x) / sRGBGammaCurve) - 0.055;
|
return x <= 0.00304f ? x * 12.92310f : 1.055f * expf(logf(x) / static_cast<float>(sRGBGammaCurve)) - 0.055f;
|
||||||
}
|
}
|
||||||
static inline float igamma2 (float x)
|
static inline float igamma2 (float x)
|
||||||
{
|
{
|
||||||
return x <= 0.03928 ? x / 12.92310 : expf(logf((x + 0.055) / 1.055) * sRGBGammaCurve);
|
return x <= 0.03928f ? x / 12.92310f : expf(logf((x + 0.055f) / 1.055f) * static_cast<float>(sRGBGammaCurve));
|
||||||
}
|
}
|
||||||
// gamma function with adjustable parameters
|
// gamma function with adjustable parameters
|
||||||
static inline double gamma (double x, double gamma, double start, double slope, double mul, double add)
|
static inline double gamma (double x, double gamma, double start, double slope, double mul, double add)
|
||||||
@ -327,8 +329,8 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
static inline float hlcurve (const float exp_scale, const float comp, const float hlrange, float level)
|
static inline float hlcurve (const float exp_scale, const float comp, const float hlrange, float level)
|
||||||
{
|
{
|
||||||
if (comp > 0.0) {
|
if (comp > 0.f) {
|
||||||
float val = level + (hlrange - 65536.0);
|
float val = level + (hlrange - 65536.f);
|
||||||
|
|
||||||
if(val == 0.0f) { // to avoid division by zero
|
if(val == 0.0f) { // to avoid division by zero
|
||||||
val = 0.000001f;
|
val = 0.000001f;
|
||||||
@ -337,7 +339,7 @@ public:
|
|||||||
float Y = val * exp_scale / hlrange;
|
float Y = val * exp_scale / hlrange;
|
||||||
Y *= comp;
|
Y *= comp;
|
||||||
|
|
||||||
if(Y <= -1.0) { // to avoid log(<=0)
|
if(Y <= -1.f) { // to avoid log(<=0)
|
||||||
Y = -.999999f;
|
Y = -.999999f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,7 +456,7 @@ public:
|
|||||||
virtual bool isIdentity () const = 0;
|
virtual bool isIdentity () const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiagonalCurve : public Curve
|
class DiagonalCurve final : public Curve
|
||||||
{
|
{
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -476,7 +478,7 @@ public:
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class FlatCurve : public Curve, public rtengine::NonCopyable
|
class FlatCurve final : public Curve, public rtengine::NonCopyable
|
||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -940,7 +942,7 @@ private:
|
|||||||
float calculateToneCurveContrastValue() const;
|
float calculateToneCurveContrastValue() const;
|
||||||
public:
|
public:
|
||||||
static void init();
|
static void init();
|
||||||
void initApplyState(PerceptualToneCurveState & state, Glib::ustring workingSpace) const;
|
void initApplyState(PerceptualToneCurveState & state, const Glib::ustring& workingSpace) const;
|
||||||
void BatchApply(const size_t start, const size_t end, float *r, float *g, float *b, const PerceptualToneCurveState &state) const;
|
void BatchApply(const size_t start, const size_t end, float *r, float *g, float *b, const PerceptualToneCurveState &state) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1064,9 +1064,11 @@ void DCPProfile::apply(
|
|||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
for (int j = 0; j < 3; ++j) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
|
double temp = 0.0;
|
||||||
for (int k = 0; k < 3; ++k) {
|
for (int k = 0; k < 3; ++k) {
|
||||||
mat[i][j] += work_matrix[i][k] * xyz_cam[k][j];
|
temp += work_matrix[i][k] * xyz_cam[k][j];
|
||||||
}
|
}
|
||||||
|
mat[i][j] = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1092,9 +1094,11 @@ void DCPProfile::apply(
|
|||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
for (int j = 0; j < 3; ++j) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
|
double temp = 0.0;
|
||||||
for (int k = 0; k < 3; ++k) {
|
for (int k = 0; k < 3; ++k) {
|
||||||
pro_photo[i][j] += prophoto_xyz[i][k] * xyz_cam[k][j];
|
temp += prophoto_xyz[i][k] * xyz_cam[k][j];
|
||||||
}
|
}
|
||||||
|
pro_photo[i][j] = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1102,9 +1106,11 @@ void DCPProfile::apply(
|
|||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
for (int j = 0; j < 3; ++j) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
|
double temp = 0.0;
|
||||||
for (int k = 0; k < 3; ++k) {
|
for (int k = 0; k < 3; ++k) {
|
||||||
work[i][j] += work_matrix[i][k] * xyz_prophoto[k][j];
|
temp += work_matrix[i][k] * xyz_prophoto[k][j];
|
||||||
}
|
}
|
||||||
|
work[i][j] = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1173,19 +1179,27 @@ void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use
|
|||||||
mWork = ICCStore::getInstance()->workingSpaceMatrix (working_space);
|
mWork = ICCStore::getInstance()->workingSpaceMatrix (working_space);
|
||||||
memset(as_out.data->pro_photo, 0, sizeof(as_out.data->pro_photo));
|
memset(as_out.data->pro_photo, 0, sizeof(as_out.data->pro_photo));
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++) {
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++) {
|
||||||
|
double temp = 0.0;
|
||||||
for (int k = 0; k < 3; k++) {
|
for (int k = 0; k < 3; k++) {
|
||||||
as_out.data->pro_photo[i][j] += prophoto_xyz[i][k] * mWork[k][j];
|
temp += prophoto_xyz[i][k] * mWork[k][j];
|
||||||
|
}
|
||||||
|
as_out.data->pro_photo[i][j] = temp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mWork = ICCStore::getInstance()->workingSpaceInverseMatrix (working_space);
|
mWork = ICCStore::getInstance()->workingSpaceInverseMatrix (working_space);
|
||||||
memset(as_out.data->work, 0, sizeof(as_out.data->work));
|
memset(as_out.data->work, 0, sizeof(as_out.data->work));
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++) {
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++) {
|
||||||
|
double temp = 0.0;
|
||||||
for (int k = 0; k < 3; k++) {
|
for (int k = 0; k < 3; k++) {
|
||||||
as_out.data->work[i][j] += mWork[i][k] * xyz_prophoto[k][j];
|
temp += mWork[i][k] * xyz_prophoto[k][j];
|
||||||
|
}
|
||||||
|
as_out.data->work[i][j] = temp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1193,7 +1207,7 @@ void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use
|
|||||||
void DCPProfile::step2ApplyTile(float* rc, float* gc, float* bc, int width, int height, int tile_width, const DCPProfileApplyState& as_in) const
|
void DCPProfile::step2ApplyTile(float* rc, float* gc, float* bc, int width, int height, int tile_width, const DCPProfileApplyState& as_in) const
|
||||||
{
|
{
|
||||||
|
|
||||||
#define FCLIP(a) ((a)>0.0?((a)<65535.5?(a):65535.5):0.0)
|
#define FCLIP(a) ((a)>0.f?((a)<65535.5f?(a):65535.5f):0.f)
|
||||||
#define CLIP01(a) ((a)>0?((a)<1?(a):1):0)
|
#define CLIP01(a) ((a)>0?((a)<1?(a):1):0)
|
||||||
|
|
||||||
float exp_scale = as_in.data->bl_scale;
|
float exp_scale = as_in.data->bl_scale;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-macros"
|
||||||
#if (__GNUC__ >= 6)
|
#if (__GNUC__ >= 6)
|
||||||
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
|
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
|
||||||
#endif
|
#endif
|
||||||
@ -94,7 +95,6 @@
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <sys/utime.h>
|
#include <sys/utime.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#define snprintf _snprintf
|
|
||||||
#define strcasecmp stricmp
|
#define strcasecmp stricmp
|
||||||
#define strncasecmp strnicmp
|
#define strncasecmp strnicmp
|
||||||
typedef __int64 INT64;
|
typedef __int64 INT64;
|
||||||
@ -158,7 +158,6 @@ const float d65_white[3] = { 0.950456, 1, 1.088754 };
|
|||||||
#define MIN(a,b) rtengine::min(a,static_cast<__typeof__(a)>(b))
|
#define MIN(a,b) rtengine::min(a,static_cast<__typeof__(a)>(b))
|
||||||
#define MAX(a,b) rtengine::max(a,static_cast<__typeof__(a)>(b))
|
#define MAX(a,b) rtengine::max(a,static_cast<__typeof__(a)>(b))
|
||||||
#define LIM(x,min,max) rtengine::LIM(x,static_cast<__typeof__(x)>(min),static_cast<__typeof__(x)>(max))
|
#define LIM(x,min,max) rtengine::LIM(x,static_cast<__typeof__(x)>(min),static_cast<__typeof__(x)>(max))
|
||||||
#define ULIM(x,y,z) rtengine::median(x,static_cast<__typeof__(x)>(y),static_cast<__typeof__(x)>(z))
|
|
||||||
#define CLIP(x) rtengine::CLIP(x)
|
#define CLIP(x) rtengine::CLIP(x)
|
||||||
#define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
|
#define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
|
||||||
|
|
||||||
@ -9868,6 +9867,7 @@ void CLASS identify()
|
|||||||
filters = 0;
|
filters = 0;
|
||||||
tiff_samples = colors = 3;
|
tiff_samples = colors = 3;
|
||||||
load_raw = &CLASS canon_sraw_load_raw;
|
load_raw = &CLASS canon_sraw_load_raw;
|
||||||
|
FORC4 cblack[c] = 0; // ALB
|
||||||
} else if (!strcmp(model,"PowerShot 600")) {
|
} else if (!strcmp(model,"PowerShot 600")) {
|
||||||
height = 613;
|
height = 613;
|
||||||
width = 854;
|
width = 854;
|
||||||
@ -11021,7 +11021,6 @@ void CLASS nikon_14bit_load_raw()
|
|||||||
/*RT*/#undef MIN
|
/*RT*/#undef MIN
|
||||||
/*RT*/#undef ABS
|
/*RT*/#undef ABS
|
||||||
/*RT*/#undef LIM
|
/*RT*/#undef LIM
|
||||||
/*RT*/#undef ULIM
|
|
||||||
/*RT*/#undef CLIP
|
/*RT*/#undef CLIP
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "dcrop.h"
|
#include "dcrop.h"
|
||||||
#include "image8.h"
|
#include "image8.h"
|
||||||
#include "imagefloat.h"
|
#include "imagefloat.h"
|
||||||
|
#include "improccoordinator.h"
|
||||||
#include "labimage.h"
|
#include "labimage.h"
|
||||||
#include "mytime.h"
|
#include "mytime.h"
|
||||||
#include "procparams.h"
|
#include "procparams.h"
|
||||||
|
@ -18,11 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "improccoordinator.h"
|
|
||||||
#include "rtengine.h"
|
#include "rtengine.h"
|
||||||
#include "improcfun.h"
|
|
||||||
#include "imagesource.h"
|
|
||||||
#include "procevents.h"
|
|
||||||
#include "pipettebuffer.h"
|
#include "pipettebuffer.h"
|
||||||
#include "../rtgui/threadutils.h"
|
#include "../rtgui/threadutils.h"
|
||||||
|
|
||||||
@ -30,12 +26,13 @@ namespace rtengine
|
|||||||
{
|
{
|
||||||
|
|
||||||
class Image8;
|
class Image8;
|
||||||
|
class CieImage;
|
||||||
|
|
||||||
using namespace procparams;
|
using namespace procparams;
|
||||||
|
|
||||||
class ImProcCoordinator;
|
class ImProcCoordinator;
|
||||||
|
|
||||||
class Crop : public DetailedCrop, public PipetteBuffer
|
class Crop final : public DetailedCrop, public PipetteBuffer
|
||||||
{
|
{
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -1069,7 +1069,7 @@ void RawImageSource::dcb_hid(float (*image)[3], int x0, int y0)
|
|||||||
for (int col = colMin + (FC(y0 - TILEBORDER + row, x0 - TILEBORDER + colMin) & 1), indx = row * CACHESIZE + col; col < colMax; col += 2, indx += 2) {
|
for (int col = colMin + (FC(y0 - TILEBORDER + row, x0 - TILEBORDER + colMin) & 1), indx = row * CACHESIZE + col; col < colMax; col += 2, indx += 2) {
|
||||||
assert(indx - u - 1 >= 0 && indx + u + 1 < u * u);
|
assert(indx - u - 1 >= 0 && indx + u + 1 < u * u);
|
||||||
|
|
||||||
image[indx][1] = 0.25*(image[indx-1][1]+image[indx+1][1]+image[indx-u][1]+image[indx+u][1]);
|
image[indx][1] = 0.25f * (image[indx-1][1]+image[indx+1][1]+image[indx-u][1]+image[indx+u][1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,7 +476,7 @@ dfInfo* DFManager::find( const std::string &mak, const std::string &mod, int iso
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bestD != INFINITY ? &(bestMatch->second) : nullptr ;
|
return bestD != RT_INFINITY ? &(bestMatch->second) : nullptr ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ namespace rtengine
|
|||||||
{
|
{
|
||||||
|
|
||||||
class RawImage;
|
class RawImage;
|
||||||
class dfInfo
|
class dfInfo final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ protected:
|
|||||||
void updateRawImage();
|
void updateRawImage();
|
||||||
};
|
};
|
||||||
|
|
||||||
class DFManager
|
class DFManager final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void init(const Glib::ustring &pathname);
|
void init(const Glib::ustring &pathname);
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <glib.h>
|
|
||||||
#include <glib/gstdio.h>
|
|
||||||
#include "curves.h"
|
#include "curves.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -65,23 +63,23 @@ DiagonalCurve::DiagonalCurve (const std::vector<double>& p, int poly_pn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x[0] != 0.0f || x[N - 1] != 1.0f)
|
if (x[0] != 0.0 || x[N - 1] != 1.0)
|
||||||
// Special (and very rare) case where all points are on the identity line but
|
// Special (and very rare) case where all points are on the identity line but
|
||||||
// not reaching the limits
|
// not reaching the limits
|
||||||
{
|
{
|
||||||
identity = false;
|
identity = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(x[0] == 0.f && x[1] == 0.f)
|
if(x[0] == 0.0 && x[1] == 0.0)
|
||||||
// Avoid crash when first two points are at x = 0 (git Issue 2888)
|
// Avoid crash when first two points are at x = 0 (git Issue 2888)
|
||||||
{
|
{
|
||||||
x[1] = 0.01f;
|
x[1] = 0.01;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(x[0] == 1.f && x[1] == 1.f)
|
if(x[0] == 1.0 && x[1] == 1.0)
|
||||||
// Avoid crash when first two points are at x = 1 (100 in gui) (git Issue 2923)
|
// Avoid crash when first two points are at x = 1 (100 in gui) (git Issue 2923)
|
||||||
{
|
{
|
||||||
x[0] = 0.99f;
|
x[0] = 0.99;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!identity) {
|
if (!identity) {
|
||||||
@ -97,7 +95,7 @@ DiagonalCurve::DiagonalCurve (const std::vector<double>& p, int poly_pn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (kind == DCT_Parametric) {
|
} else if (kind == DCT_Parametric) {
|
||||||
if ((p.size() == 8 || p.size() == 9) && (p.at(4) != 0.0f || p.at(5) != 0.0f || p.at(6) != 0.0f || p.at(7) != 0.0f)) {
|
if ((p.size() == 8 || p.size() == 9) && (p.at(4) != 0.0 || p.at(5) != 0.0 || p.at(6) != 0.0 || p.at(7) != 0.0)) {
|
||||||
identity = false;
|
identity = false;
|
||||||
|
|
||||||
x = new double[9];
|
x = new double[9];
|
||||||
|
@ -228,11 +228,11 @@ void fillLut(LUTf &irangefn, int level, double dirpyrThreshold, float mult, floa
|
|||||||
}
|
}
|
||||||
|
|
||||||
const float offs = skinprot == 0.f ? 0.f : -1.f;
|
const float offs = skinprot == 0.f ? 0.f : -1.f;
|
||||||
constexpr float noise = 2000.f;
|
constexpr double noise = 2000.0;
|
||||||
const float noisehi = 1.33f * noise * dirpyrThreshold / expf(level * log(3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf(level * log(3.0));
|
const float noisehi = 1.33 * noise * dirpyrThreshold / exp(level * log(3.0)), noiselo = 0.66 * noise * dirpyrThreshold / exp(level * log(3.0));
|
||||||
|
|
||||||
for (int i = 0; i < 0x20000; i++) {
|
for (int i = 0; i < 0x20000; i++) {
|
||||||
if (abs(i - 0x10000) > noisehi || multbis < 1.0) {
|
if (abs(i - 0x10000) > noisehi || multbis < 1.f) {
|
||||||
irangefn[i] = multbis + offs;
|
irangefn[i] = multbis + offs;
|
||||||
} else {
|
} else {
|
||||||
if (abs(i - 0x10000) < noiselo) {
|
if (abs(i - 0x10000) < noiselo) {
|
||||||
@ -262,7 +262,7 @@ void idirpyr_eq_channel(const float * const * data_coarse, const float * const *
|
|||||||
buffer[i][j] += irangefn[hipass + 0x10000] * hipass;
|
buffer[i][j] += irangefn[hipass + 0x10000] * hipass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (skinprot > 0.f) {
|
} else if (skinprot > 0.0) {
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for schedule(dynamic,16)
|
#pragma omp parallel for schedule(dynamic,16)
|
||||||
#endif
|
#endif
|
||||||
@ -314,7 +314,7 @@ void idirpyr_eq_channelcam(const float * const * data_coarse, const float * cons
|
|||||||
buffer[i][j] += irangefn[hipass + 0x10000] * hipass;
|
buffer[i][j] += irangefn[hipass + 0x10000] * hipass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (skinprot > 0.f) {
|
} else if (skinprot > 0.0) {
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for schedule(dynamic,16)
|
#pragma omp parallel for schedule(dynamic,16)
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,7 +45,7 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams
|
|||||||
{
|
{
|
||||||
BENCHFUN
|
BENCHFUN
|
||||||
|
|
||||||
if (contrast == 0.f && !autoContrast) {
|
if (contrast == 0.0 && !autoContrast) {
|
||||||
// contrast == 0.0 means only first demosaicer will be used
|
// contrast == 0.0 means only first demosaicer will be used
|
||||||
if(isBayer) {
|
if(isBayer) {
|
||||||
if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEVNG4) ) {
|
if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEVNG4) ) {
|
||||||
@ -103,7 +103,7 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams
|
|||||||
}
|
}
|
||||||
// calculate contrast based blend factors to use vng4 in regions with low contrast
|
// calculate contrast based blend factors to use vng4 in regions with low contrast
|
||||||
JaggedArray<float> blend(winw, winh);
|
JaggedArray<float> blend(winw, winh);
|
||||||
float contrastf = contrast / 100.f;
|
float contrastf = contrast / 100.0;
|
||||||
|
|
||||||
buildBlendMask(L, blend, winw, winh, contrastf, autoContrast);
|
buildBlendMask(L, blend, winw, winh, contrastf, autoContrast);
|
||||||
contrast = contrastf * 100.f;
|
contrast = contrastf * 100.f;
|
||||||
|
@ -428,7 +428,7 @@ ffInfo* FFManager::find( const std::string &mak, const std::string &mod, const s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bestD != INFINITY ? &(bestMatch->second) : nullptr ;
|
return bestD != RT_INFINITY ? &(bestMatch->second) : nullptr ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ namespace rtengine
|
|||||||
{
|
{
|
||||||
|
|
||||||
class RawImage;
|
class RawImage;
|
||||||
class ffInfo
|
class ffInfo final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ protected:
|
|||||||
void updateRawImage();
|
void updateRawImage();
|
||||||
};
|
};
|
||||||
|
|
||||||
class FFManager
|
class FFManager final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void init(const Glib::ustring &pathname);
|
void init(const Glib::ustring &pathname);
|
||||||
|
@ -122,8 +122,8 @@ bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D s
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
printf("Clear film values: R=%g G=%g B=%g\n", clearVals[0], clearVals[1], clearVals[2]);
|
printf("Clear film values: R=%g G=%g B=%g\n", static_cast<double>(clearVals[0]), static_cast<double>(clearVals[1]), static_cast<double>(clearVals[2]));
|
||||||
printf("Dense film values: R=%g G=%g B=%g\n", denseVals[0], denseVals[1], denseVals[2]);
|
printf("Dense film values: R=%g G=%g B=%g\n", static_cast<double>(denseVals[0]), static_cast<double>(denseVals[1]), static_cast<double>(denseVals[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
const float denseGreenRatio = clearVals[1] / denseVals[1];
|
const float denseGreenRatio = clearVals[1] / denseVals[1];
|
||||||
@ -141,12 +141,12 @@ bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D s
|
|||||||
if (ch == 1) {
|
if (ch == 1) {
|
||||||
newExps[ch] = 1.f; // Green is the reference channel
|
newExps[ch] = 1.f; // Green is the reference channel
|
||||||
} else {
|
} else {
|
||||||
newExps[ch] = CLAMP(logBase(clearVals[ch] / denseVals[ch], denseGreenRatio), 0.3f, 4.f);
|
newExps[ch] = rtengine::LIM(logBase(clearVals[ch] / denseVals[ch], denseGreenRatio), 0.3f, 4.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
printf("New exponents: R=%g G=%g B=%g\n", newExps[0], newExps[1], newExps[2]);
|
printf("New exponents: R=%g G=%g B=%g\n", static_cast<double>(newExps[0]), static_cast<double>(newExps[1]), static_cast<double>(newExps[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -246,8 +246,8 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ
|
|||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
printf("Sample count: %zu, %zu, %zu\n", cvs[0].size(), cvs[1].size(), cvs[2].size());
|
printf("Sample count: %zu, %zu, %zu\n", cvs[0].size(), cvs[1].size(), cvs[2].size());
|
||||||
printf("Medians: %g %g %g\n", medians[0], medians[1], medians[2] );
|
printf("Medians: %g %g %g\n", static_cast<double>(medians[0]), static_cast<double>(medians[1]), static_cast<double>(medians[2]));
|
||||||
printf("Computed multipliers: %g %g %g\n", mults[0], mults[1], mults[2] );
|
printf("Computed multipliers: %g %g %g\n", static_cast<double>(mults[0]), static_cast<double>(mults[1]), static_cast<double>(mults[2]));
|
||||||
printf("Median calc time us: %d\n", t3.etime(t2));
|
printf("Median calc time us: %d\n", t3.etime(t2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +89,8 @@ void rtengine::Thumbnail::processFilmNegative(
|
|||||||
const float bmult = (MAX_OUT_VALUE / (bmed * 24)) ;
|
const float bmult = (MAX_OUT_VALUE / (bmed * 24)) ;
|
||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
printf("Thumbnail channel medians: %g %g %g\n", rmed, gmed, bmed);
|
printf("Thumbnail channel medians: %g %g %g\n", static_cast<double>(rmed), static_cast<double>(gmed), static_cast<double>(bmed));
|
||||||
printf("Thumbnail computed multipliers: %g %g %g\n", rmult, gmult, bmult);
|
printf("Thumbnail computed multipliers: %g %g %g\n", static_cast<double>(rmult), static_cast<double>(gmult), static_cast<double>(bmult));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
|
@ -47,7 +47,7 @@ void RawImageSource::green_equilibrate_global(array2D<float> &rawData)
|
|||||||
for (int i = border; i < H - border; i++) {
|
for (int i = border; i < H - border; i++) {
|
||||||
double avgg = 0.;
|
double avgg = 0.;
|
||||||
for (int j = border + ((FC(i, border) & 1) ^ 1); j < W - border; j += 2) {
|
for (int j = border + ((FC(i, border) & 1) ^ 1); j < W - border; j += 2) {
|
||||||
avgg += rawData[i][j];
|
avgg += static_cast<double>(rawData[i][j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ng = (W - 2 * border + (FC(i, border) & 1)) / 2;
|
int ng = (W - 2 * border + (FC(i, border) & 1)) / 2;
|
||||||
@ -71,15 +71,15 @@ void RawImageSource::green_equilibrate_global(array2D<float> &rawData)
|
|||||||
avgg2 = 1.0;
|
avgg2 = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double corrg1 = (avgg1 / ng1 + avgg2 / ng2) / 2.0 / (avgg1 / ng1);
|
const float corrg1 = (avgg1 / ng1 + avgg2 / ng2) / 2.0 / (avgg1 / ng1);
|
||||||
double corrg2 = (avgg1 / ng1 + avgg2 / ng2) / 2.0 / (avgg2 / ng2);
|
const float corrg2 = (avgg1 / ng1 + avgg2 / ng2) / 2.0 / (avgg2 / ng2);
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for schedule(dynamic,16)
|
#pragma omp parallel for schedule(dynamic,16)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = border; i < H - border; i++) {
|
for (int i = border; i < H - border; i++) {
|
||||||
double corrg = (i & 1) ? corrg2 : corrg1;
|
const float corrg = (i & 1) ? corrg2 : corrg1;
|
||||||
|
|
||||||
for (int j = border + ((FC(i, border) & 1) ^ 1); j < W - border; j += 2) {
|
for (int j = border + ((FC(i, border) & 1) ^ 1); j < W - border; j += 2) {
|
||||||
rawData[i][j] *= corrg;
|
rawData[i][j] *= corrg;
|
||||||
@ -220,7 +220,7 @@ void RawImageSource::green_equilibrate(const GreenEqulibrateThreshold &thresh, a
|
|||||||
|
|
||||||
float tf = thresh(rr, cc);
|
float tf = thresh(rr, cc);
|
||||||
|
|
||||||
if (c1 + c2 < 6 * tf * fabs(d1 - d2)) {
|
if (c1 + c2 < 6 * tf * std::fabs(d1 - d2)) {
|
||||||
//pixel interpolation
|
//pixel interpolation
|
||||||
float gin = cfa[rr][cc >> 1];
|
float gin = cfa[rr][cc >> 1];
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
* available at https://arxiv.org/abs/1505.00996
|
* available at https://arxiv.org/abs/1505.00996
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "array2D.h"
|
||||||
#include "boxblur.h"
|
#include "boxblur.h"
|
||||||
#include "guidedfilter.h"
|
#include "guidedfilter.h"
|
||||||
#include "imagefloat.h"
|
#include "imagefloat.h"
|
||||||
|
@ -323,7 +323,7 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue
|
|||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
for (int c = 0; c < 3; ++c) {
|
for (int c = 0; c < 3; ++c) {
|
||||||
printf("chmax[%d] : %f\tclmax[%d] : %f\tratio[%d] : %f\n", c, chmax[c], c, clmax[c], c, chmax[c] / clmax[c]);
|
printf("chmax[%d] : %f\tclmax[%d] : %f\tratio[%d] : %f\n", c, static_cast<double>(chmax[c]), c, static_cast<double>(clmax[c]), c, static_cast<double>(chmax[c] / clmax[c]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,7 +366,7 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue
|
|||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
for (int c = 0; c < 3; ++c) {
|
for (int c = 0; c < 3; ++c) {
|
||||||
printf("correction factor[%d] : %f\n", c, factor[c]);
|
printf("correction factor[%d] : %f\n", c, static_cast<double>(factor[c]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,7 +496,7 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue
|
|||||||
&& blue[i + miny][j + minx] < max_f[2]
|
&& blue[i + miny][j + minx] < max_f[2]
|
||||||
) {
|
) {
|
||||||
// if one or more channels is highlight but none are blown, add to highlight accumulator
|
// if one or more channels is highlight but none are blown, add to highlight accumulator
|
||||||
hipass_sum += channelblur[0][i][j];
|
hipass_sum += static_cast<double>(channelblur[0][i][j]);
|
||||||
++hipass_norm;
|
++hipass_norm;
|
||||||
|
|
||||||
hilite_full[0][i][j] = red[i + miny][j + minx];
|
hilite_full[0][i][j] = red[i + miny][j + minx];
|
||||||
@ -507,7 +507,7 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const float hipass_ave = 2.f * hipass_sum / (hipass_norm + epsilon);
|
const float hipass_ave = 2.0 * hipass_sum / (hipass_norm + static_cast<double>(epsilon));
|
||||||
|
|
||||||
if (plistener) {
|
if (plistener) {
|
||||||
progress += 0.05;
|
progress += 0.05;
|
||||||
|
@ -179,7 +179,7 @@ void mappingToCurve(const std::vector<int> &mapping, std::vector<double> &curve)
|
|||||||
};
|
};
|
||||||
idx = -1;
|
idx = -1;
|
||||||
for (ssize_t i = curve.size()-1; i > 0; i -= 2) {
|
for (ssize_t i = curve.size()-1; i > 0; i -= 2) {
|
||||||
if (curve[i] <= 0.f) {
|
if (curve[i] <= 0.0) {
|
||||||
idx = i+1;
|
idx = i+1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -328,7 +328,7 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, st
|
|||||||
int tw = target->getWidth(), th = target->getHeight();
|
int tw = target->getWidth(), th = target->getHeight();
|
||||||
float thumb_ratio = float(std::max(sw, sh)) / float(std::min(sw, sh));
|
float thumb_ratio = float(std::max(sw, sh)) / float(std::min(sw, sh));
|
||||||
float target_ratio = float(std::max(tw, th)) / float(std::min(tw, th));
|
float target_ratio = float(std::max(tw, th)) / float(std::min(tw, th));
|
||||||
if (std::abs(thumb_ratio - target_ratio) > 0.01) {
|
if (std::abs(thumb_ratio - target_ratio) > 0.01f) {
|
||||||
int cx = 0, cy = 0;
|
int cx = 0, cy = 0;
|
||||||
if (thumb_ratio > target_ratio) {
|
if (thumb_ratio > target_ratio) {
|
||||||
// crop the height
|
// crop the height
|
||||||
@ -342,7 +342,7 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, st
|
|||||||
tw -= cw;
|
tw -= cw;
|
||||||
}
|
}
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
std::cout << "histogram matching: cropping target to get an aspect ratio of " << round(thumb_ratio * 100)/100.0 << ":1, new size is " << tw << "x" << th << std::endl;
|
std::cout << "histogram matching: cropping target to get an aspect ratio of " << round(thumb_ratio * 100)/100.f << ":1, new size is " << tw << "x" << th << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cx || cy) {
|
if (cx || cy) {
|
||||||
|
@ -43,7 +43,6 @@
|
|||||||
#include "color.h"
|
#include "color.h"
|
||||||
|
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
#define inkc_constant 0x696E6B43
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ namespace procparams
|
|||||||
|
|
||||||
typedef const double(*TMatrix)[3];
|
typedef const double(*TMatrix)[3];
|
||||||
|
|
||||||
class ProfileContent
|
class ProfileContent final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ProfileContent();
|
ProfileContent();
|
||||||
@ -54,7 +54,7 @@ private:
|
|||||||
std::string data;
|
std::string data;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ICCStore
|
class ICCStore final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class ProfileType {
|
enum class ProfileType {
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <glibmm/ustring.h>
|
|
||||||
#include <lcms2.h>
|
#include <lcms2.h>
|
||||||
|
|
||||||
#include "alignedbuffer.h"
|
#include "alignedbuffer.h"
|
||||||
@ -41,6 +40,13 @@
|
|||||||
|
|
||||||
#define CHECK_BOUNDS 0
|
#define CHECK_BOUNDS 0
|
||||||
|
|
||||||
|
namespace Glib
|
||||||
|
{
|
||||||
|
|
||||||
|
class ustring;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -658,7 +664,7 @@ public:
|
|||||||
|
|
||||||
/* If any of the required allocation fails, "width" and "height" are set to -1, and all remaining buffer are freed
|
/* If any of the required allocation fails, "width" and "height" are set to -1, and all remaining buffer are freed
|
||||||
* Can be safely used to reallocate an existing image */
|
* Can be safely used to reallocate an existing image */
|
||||||
void allocate (int W, int H) override
|
void allocate (int W, int H) final
|
||||||
{
|
{
|
||||||
|
|
||||||
if (W == width && H == height) {
|
if (W == width && H == height) {
|
||||||
@ -746,7 +752,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rotate (int deg) override
|
void rotate (int deg) final
|
||||||
{
|
{
|
||||||
|
|
||||||
if (deg == 90) {
|
if (deg == 90) {
|
||||||
@ -873,7 +879,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hflip () override
|
void hflip () final
|
||||||
{
|
{
|
||||||
int width2 = width / 2;
|
int width2 = width / 2;
|
||||||
|
|
||||||
@ -905,7 +911,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void vflip () override
|
void vflip () final
|
||||||
{
|
{
|
||||||
|
|
||||||
int height2 = height / 2;
|
int height2 = height / 2;
|
||||||
@ -989,7 +995,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void computeHistogramAutoWB (double &avg_r, double &avg_g, double &avg_b, int &n, LUTu &histogram, const int compression) const override
|
void computeHistogramAutoWB (double &avg_r, double &avg_g, double &avg_b, int &n, LUTu &histogram, const int compression) const final
|
||||||
{
|
{
|
||||||
histogram.clear();
|
histogram.clear();
|
||||||
avg_r = avg_g = avg_b = 0.;
|
avg_r = avg_g = avg_b = 0.;
|
||||||
@ -1328,7 +1334,7 @@ public:
|
|||||||
* If any of the required allocation fails, "width" and "height" are set to -1, and all remaining buffer are freed
|
* If any of the required allocation fails, "width" and "height" are set to -1, and all remaining buffer are freed
|
||||||
* Can be safely used to reallocate an existing image or to free up it's memory with "allocate (0,0);"
|
* Can be safely used to reallocate an existing image or to free up it's memory with "allocate (0,0);"
|
||||||
*/
|
*/
|
||||||
void allocate (int W, int H) override
|
void allocate (int W, int H) final
|
||||||
{
|
{
|
||||||
|
|
||||||
if (W == width && H == height) {
|
if (W == width && H == height) {
|
||||||
@ -1382,7 +1388,7 @@ public:
|
|||||||
memcpy (dest->data, data, 3 * width * height * sizeof(T));
|
memcpy (dest->data, data, 3 * width * height * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
void rotate (int deg) override
|
void rotate (int deg) final
|
||||||
{
|
{
|
||||||
|
|
||||||
if (deg == 90) {
|
if (deg == 90) {
|
||||||
@ -1516,7 +1522,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hflip () override
|
void hflip () final
|
||||||
{
|
{
|
||||||
int width2 = width / 2;
|
int width2 = width / 2;
|
||||||
|
|
||||||
@ -1552,7 +1558,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vflip () override
|
void vflip () final
|
||||||
{
|
{
|
||||||
|
|
||||||
AlignedBuffer<T> lBuffer(3 * width);
|
AlignedBuffer<T> lBuffer(3 * width);
|
||||||
@ -1619,7 +1625,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void computeHistogramAutoWB (double &avg_r, double &avg_g, double &avg_b, int &n, LUTu &histogram, const int compression) const override
|
void computeHistogramAutoWB (double &avg_r, double &avg_g, double &avg_b, int &n, LUTu &histogram, const int compression) const final
|
||||||
{
|
{
|
||||||
histogram.clear();
|
histogram.clear();
|
||||||
avg_r = avg_g = avg_b = 0.;
|
avg_r = avg_g = avg_b = 0.;
|
||||||
|
@ -147,10 +147,10 @@ void Image16::getStdImage(const ColorTemp &ctemp, int tran, Imagefloat* image, P
|
|||||||
gm = dgm;
|
gm = dgm;
|
||||||
bm = dbm;
|
bm = dbm;
|
||||||
|
|
||||||
rm = 1.0 / rm;
|
rm = 1.f / rm;
|
||||||
gm = 1.0 / gm;
|
gm = 1.f / gm;
|
||||||
bm = 1.0 / bm;
|
bm = 1.f / bm;
|
||||||
float mul_lum = 0.299 * rm + 0.587 * gm + 0.114 * bm;
|
float mul_lum = 0.299f * rm + 0.587f * gm + 0.114f * bm;
|
||||||
rm /= mul_lum;
|
rm /= mul_lum;
|
||||||
gm /= mul_lum;
|
gm /= mul_lum;
|
||||||
bm /= mul_lum;
|
bm /= mul_lum;
|
||||||
@ -187,8 +187,6 @@ void Image16::getStdImage(const ColorTemp &ctemp, int tran, Imagefloat* image, P
|
|||||||
gm /= area;
|
gm /= area;
|
||||||
bm /= area;
|
bm /= area;
|
||||||
|
|
||||||
#define GCLIP( x ) Color::gamma_srgb(CLIP(x))
|
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@ namespace rtengine
|
|||||||
class Image8;
|
class Image8;
|
||||||
class Imagefloat;
|
class Imagefloat;
|
||||||
|
|
||||||
class Image16 : public IImage16, public ImageIO
|
class Image16 final : public IImage16, public ImageIO
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -111,10 +111,10 @@ void Image8::getStdImage (const ColorTemp &ctemp, int tran, Imagefloat* image, P
|
|||||||
gm = dgm;
|
gm = dgm;
|
||||||
bm = dbm;
|
bm = dbm;
|
||||||
|
|
||||||
rm = 1.0 / rm;
|
rm = 1.f / rm;
|
||||||
gm = 1.0 / gm;
|
gm = 1.f / gm;
|
||||||
bm = 1.0 / bm;
|
bm = 1.f / bm;
|
||||||
float mul_lum = 0.299 * rm + 0.587 * gm + 0.114 * bm;
|
float mul_lum = 0.299f * rm + 0.587f * gm + 0.114f * bm;
|
||||||
rm /= mul_lum;
|
rm /= mul_lum;
|
||||||
gm /= mul_lum;
|
gm /= mul_lum;
|
||||||
bm /= mul_lum;
|
bm /= mul_lum;
|
||||||
@ -151,8 +151,6 @@ void Image8::getStdImage (const ColorTemp &ctemp, int tran, Imagefloat* image, P
|
|||||||
gm /= area;
|
gm /= area;
|
||||||
bm /= area;
|
bm /= area;
|
||||||
|
|
||||||
#define GCLIP( x ) Color::gamma_srgb(CLIP(x))
|
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ namespace rtengine
|
|||||||
{
|
{
|
||||||
class Imagefloat;
|
class Imagefloat;
|
||||||
|
|
||||||
class Image8 : public IImage8, public ImageIO
|
class Image8 final : public IImage8, public ImageIO
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -502,11 +502,11 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
|
|||||||
} else if (!make.compare (0, 6, "PENTAX") || (!make.compare (0, 5, "RICOH") && !model.compare (0, 6, "PENTAX"))) {
|
} else if (!make.compare (0, 6, "PENTAX") || (!make.compare (0, 5, "RICOH") && !model.compare (0, 6, "PENTAX"))) {
|
||||||
// ISO at max value supported, check manufacturer specific
|
// ISO at max value supported, check manufacturer specific
|
||||||
if (iso_speed == 65535 || iso_speed == 0) {
|
if (iso_speed == 65535 || iso_speed == 0) {
|
||||||
rtexif::Tag* baseIsoTag = mnote->getTag("ISO");
|
const rtexif::Tag* const baseIsoTag = mnote->getTag("ISO");
|
||||||
if (baseIsoTag) {
|
if (baseIsoTag) {
|
||||||
std::string isoData = baseIsoTag->valueToString();
|
const std::string isoData = baseIsoTag->valueToString();
|
||||||
if (isoData.size() > 1) {
|
if (isoData.size() > 1) {
|
||||||
iso_speed = stoi(isoData);
|
iso_speed = std::stoi(isoData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,18 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <glibmm/ustring.h>
|
|
||||||
|
|
||||||
#include <libiptcdata/iptc-data.h>
|
#include <libiptcdata/iptc-data.h>
|
||||||
|
|
||||||
#include "imageio.h"
|
#include "imageio.h"
|
||||||
|
|
||||||
|
namespace Glib
|
||||||
|
{
|
||||||
|
|
||||||
|
class ustring;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace rtexif
|
namespace rtexif
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -38,7 +44,7 @@ class TagDirectory;
|
|||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
class FrameData
|
class FrameData final
|
||||||
{
|
{
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -95,7 +101,7 @@ public:
|
|||||||
int getRating () const;
|
int getRating () const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FramesData : public FramesMetaData {
|
class FramesData final : public FramesMetaData {
|
||||||
private:
|
private:
|
||||||
// frame's root IFD, can be a file root IFD or a SUB-IFD
|
// frame's root IFD, can be a file root IFD or a SUB-IFD
|
||||||
std::vector<std::unique_ptr<FrameData>> frames;
|
std::vector<std::unique_ptr<FrameData>> frames;
|
||||||
|
@ -178,10 +178,10 @@ void Imagefloat::getStdImage (const ColorTemp &ctemp, int tran, Imagefloat* imag
|
|||||||
gm = dgm;
|
gm = dgm;
|
||||||
bm = dbm;
|
bm = dbm;
|
||||||
|
|
||||||
rm = 1.0 / rm;
|
rm = 1.f / rm;
|
||||||
gm = 1.0 / gm;
|
gm = 1.f / gm;
|
||||||
bm = 1.0 / bm;
|
bm = 1.f / bm;
|
||||||
float mul_lum = 0.299 * rm + 0.587 * gm + 0.114 * bm;
|
float mul_lum = 0.299f * rm + 0.587f * gm + 0.114f * bm;
|
||||||
rm /= mul_lum;
|
rm /= mul_lum;
|
||||||
gm /= mul_lum;
|
gm /= mul_lum;
|
||||||
bm /= mul_lum;
|
bm /= mul_lum;
|
||||||
@ -368,7 +368,7 @@ Imagefloat::to16() const
|
|||||||
void Imagefloat::normalizeFloat(float srcMinVal, float srcMaxVal)
|
void Imagefloat::normalizeFloat(float srcMinVal, float srcMaxVal)
|
||||||
{
|
{
|
||||||
|
|
||||||
float scale = MAXVALD / (srcMaxVal - srcMinVal);
|
float scale = MAXVALF / (srcMaxVal - srcMinVal);
|
||||||
int w = width;
|
int w = width;
|
||||||
int h = height;
|
int h = height;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class LabImage;
|
|||||||
/*
|
/*
|
||||||
* Image type used by most tools; expected range: [0.0 ; 65535.0]
|
* Image type used by most tools; expected range: [0.0 ; 65535.0]
|
||||||
*/
|
*/
|
||||||
class Imagefloat : public IImagefloat, public ImageIO
|
class Imagefloat final : public IImagefloat, public ImageIO
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include "coord2d.h"
|
#include "coord2d.h"
|
||||||
#include "imagedata.h"
|
#include "imagedata.h"
|
||||||
#include "LUT.h"
|
|
||||||
#include "rtengine.h"
|
#include "rtengine.h"
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -86,7 +85,7 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ImageSource () : references (1), redAWBMul(-1.), greenAWBMul(-1.), blueAWBMul(-1.),
|
ImageSource () : references (1), redAWBMul(-1.), greenAWBMul(-1.), blueAWBMul(-1.),
|
||||||
embProfile(nullptr), idata(nullptr), dirpyrdenoiseExpComp(INFINITY) {}
|
embProfile(nullptr), idata(nullptr), dirpyrdenoiseExpComp(RT_INFINITY) {}
|
||||||
|
|
||||||
~ImageSource () override {}
|
~ImageSource () override {}
|
||||||
virtual int load (const Glib::ustring &fname) = 0;
|
virtual int load (const Glib::ustring &fname) = 0;
|
||||||
@ -143,11 +142,11 @@ public:
|
|||||||
|
|
||||||
virtual void setProgressListener (ProgressListener* pl) {}
|
virtual void setProgressListener (ProgressListener* pl) {}
|
||||||
|
|
||||||
void increaseRef () override
|
void increaseRef () final
|
||||||
{
|
{
|
||||||
references++;
|
references++;
|
||||||
}
|
}
|
||||||
void decreaseRef () override
|
void decreaseRef () final
|
||||||
{
|
{
|
||||||
references--;
|
references--;
|
||||||
|
|
||||||
@ -175,15 +174,15 @@ public:
|
|||||||
return dirpyrdenoiseExpComp;
|
return dirpyrdenoiseExpComp;
|
||||||
}
|
}
|
||||||
// functions inherited from the InitialImage interface
|
// functions inherited from the InitialImage interface
|
||||||
Glib::ustring getFileName () override
|
Glib::ustring getFileName () final
|
||||||
{
|
{
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
cmsHPROFILE getEmbeddedProfile () override
|
cmsHPROFILE getEmbeddedProfile () final
|
||||||
{
|
{
|
||||||
return embProfile;
|
return embProfile;
|
||||||
}
|
}
|
||||||
const FramesMetaData* getMetaData () override
|
const FramesMetaData* getMetaData () final
|
||||||
{
|
{
|
||||||
return idata;
|
return idata;
|
||||||
}
|
}
|
||||||
|
@ -734,7 +734,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
|||||||
|
|
||||||
if (params->blackwhite.enabled && params->blackwhite.autoc && abwListener) {
|
if (params->blackwhite.enabled && params->blackwhite.autoc && abwListener) {
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
printf("ImProcCoordinator / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", bwAutoR, bwAutoG, bwAutoB);
|
printf("ImProcCoordinator / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", static_cast<double>(bwAutoR), static_cast<double>(bwAutoG), static_cast<double>(bwAutoB));
|
||||||
}
|
}
|
||||||
|
|
||||||
abwListener->BWChanged((float) rrm, (float) ggm, (float) bbm);
|
abwListener->BWChanged((float) rrm, (float) ggm, (float) bbm);
|
||||||
@ -871,7 +871,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
|||||||
double E_V = fcomp + log2(double ((fnum * fnum) / fspeed / (fiso / 100.f)));
|
double E_V = fcomp + log2(double ((fnum * fnum) / fspeed / (fiso / 100.f)));
|
||||||
E_V += params->toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV
|
E_V += params->toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV
|
||||||
E_V += log2(params->raw.expos); // exposure raw white point ; log2 ==> linear to EV
|
E_V += log2(params->raw.expos); // exposure raw white point ; log2 ==> linear to EV
|
||||||
adap = powf(2.f, E_V - 3.f); // cd / m2
|
adap = pow(2.0, E_V - 3.0); // cd / m2
|
||||||
// end calculation adaptation scene luminosity
|
// end calculation adaptation scene luminosity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#include "imagesource.h"
|
#include "imagesource.h"
|
||||||
#include "improcfun.h"
|
#include "improcfun.h"
|
||||||
#include "LUT.h"
|
#include "LUT.h"
|
||||||
#include "procevents.h"
|
|
||||||
#include "rtengine.h"
|
#include "rtengine.h"
|
||||||
|
|
||||||
#include "../rtgui/threadutils.h"
|
#include "../rtgui/threadutils.h"
|
||||||
@ -55,7 +54,7 @@ class Crop;
|
|||||||
* but using this class' LUT and other precomputed parameters. The main preview area is displaying a non framed Crop object,
|
* but using this class' LUT and other precomputed parameters. The main preview area is displaying a non framed Crop object,
|
||||||
* while detail windows are framed Crop objects.
|
* while detail windows are framed Crop objects.
|
||||||
*/
|
*/
|
||||||
class ImProcCoordinator : public StagedImageProcessor
|
class ImProcCoordinator final : public StagedImageProcessor
|
||||||
{
|
{
|
||||||
|
|
||||||
friend class Crop;
|
friend class Crop;
|
||||||
|
@ -31,15 +31,16 @@
|
|||||||
#include "cieimage.h"
|
#include "cieimage.h"
|
||||||
#include "clutstore.h"
|
#include "clutstore.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
|
#include "colortemp.h"
|
||||||
#include "curves.h"
|
#include "curves.h"
|
||||||
#include "dcp.h"
|
#include "dcp.h"
|
||||||
#include "EdgePreservingDecomposition.h"
|
#include "EdgePreservingDecomposition.h"
|
||||||
#include "iccmatrices.h"
|
#include "iccmatrices.h"
|
||||||
#include "iccstore.h"
|
#include "iccstore.h"
|
||||||
#include "imagesource.h"
|
#include "imagesource.h"
|
||||||
#include "improccoordinator.h"
|
|
||||||
#include "improcfun.h"
|
#include "improcfun.h"
|
||||||
#include "labimage.h"
|
#include "labimage.h"
|
||||||
|
#include "pipettebuffer.h"
|
||||||
#include "procparams.h"
|
#include "procparams.h"
|
||||||
#include "rt_math.h"
|
#include "rt_math.h"
|
||||||
#include "rtengine.h"
|
#include "rtengine.h"
|
||||||
@ -54,9 +55,6 @@
|
|||||||
#include "mytime.h"
|
#include "mytime.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef CLIPD
|
|
||||||
#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f)
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using namespace rtengine;
|
using namespace rtengine;
|
||||||
@ -137,7 +135,7 @@ void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, flo
|
|||||||
float b = btemp[ti * tileSize + tj + k];
|
float b = btemp[ti * tileSize + tj + k];
|
||||||
float tonefactor = ((r < MAXVALF ? hltonecurve[r] : CurveFactory::hlcurve(exp_scale, comp, hlrange, r)) +
|
float tonefactor = ((r < MAXVALF ? hltonecurve[r] : CurveFactory::hlcurve(exp_scale, comp, hlrange, r)) +
|
||||||
(g < MAXVALF ? hltonecurve[g] : CurveFactory::hlcurve(exp_scale, comp, hlrange, g)) +
|
(g < MAXVALF ? hltonecurve[g] : CurveFactory::hlcurve(exp_scale, comp, hlrange, g)) +
|
||||||
(b < MAXVALF ? hltonecurve[b] : CurveFactory::hlcurve(exp_scale, comp, hlrange, b))) / 3.0;
|
(b < MAXVALF ? hltonecurve[b] : CurveFactory::hlcurve(exp_scale, comp, hlrange, b))) / 3.f;
|
||||||
|
|
||||||
// note: tonefactor includes exposure scaling, that is here exposure slider and highlight compression takes place
|
// note: tonefactor includes exposure scaling, that is here exposure slider and highlight compression takes place
|
||||||
rtemp[ti * tileSize + tj + k] = r * tonefactor;
|
rtemp[ti * tileSize + tj + k] = r * tonefactor;
|
||||||
@ -165,7 +163,7 @@ void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, flo
|
|||||||
//float tonefactor = hltonecurve[(0.299f*r+0.587f*g+0.114f*b)];
|
//float tonefactor = hltonecurve[(0.299f*r+0.587f*g+0.114f*b)];
|
||||||
float tonefactor = ((r < MAXVALF ? hltonecurve[r] : CurveFactory::hlcurve(exp_scale, comp, hlrange, r)) +
|
float tonefactor = ((r < MAXVALF ? hltonecurve[r] : CurveFactory::hlcurve(exp_scale, comp, hlrange, r)) +
|
||||||
(g < MAXVALF ? hltonecurve[g] : CurveFactory::hlcurve(exp_scale, comp, hlrange, g)) +
|
(g < MAXVALF ? hltonecurve[g] : CurveFactory::hlcurve(exp_scale, comp, hlrange, g)) +
|
||||||
(b < MAXVALF ? hltonecurve[b] : CurveFactory::hlcurve(exp_scale, comp, hlrange, b))) / 3.0;
|
(b < MAXVALF ? hltonecurve[b] : CurveFactory::hlcurve(exp_scale, comp, hlrange, b))) / 3.f;
|
||||||
|
|
||||||
// note: tonefactor includes exposure scaling, that is here exposure slider and highlight compression takes place
|
// note: tonefactor includes exposure scaling, that is here exposure slider and highlight compression takes place
|
||||||
rtemp[ti * tileSize + tj] = r * tonefactor;
|
rtemp[ti * tileSize + tj] = r * tonefactor;
|
||||||
@ -518,8 +516,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw
|
|||||||
int width = lab->W, height = lab->H;
|
int width = lab->W, height = lab->H;
|
||||||
float minQ = 10000.f;
|
float minQ = 10000.f;
|
||||||
float maxQ = -1000.f;
|
float maxQ = -1000.f;
|
||||||
float Yw;
|
double Yw = 1.0;
|
||||||
Yw = 1.0;
|
|
||||||
double Xw, Zw;
|
double Xw, Zw;
|
||||||
float f = 0.f, nc = 0.f, la, c = 0.f, xw, yw, zw, f2 = 1.f, c2 = 1.f, nc2 = 1.f, yb2;
|
float f = 0.f, nc = 0.f, la, c = 0.f, xw, yw, zw, f2 = 1.f, c2 = 1.f, nc2 = 1.f, yb2;
|
||||||
float fl, n, nbb, ncb, aw; //d
|
float fl, n, nbb, ncb, aw; //d
|
||||||
@ -596,13 +593,13 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw
|
|||||||
algepd = true;
|
algepd = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
xwd = 100.f * Xwout;
|
xwd = 100.0 * Xwout;
|
||||||
zwd = 100.f * Zwout;
|
zwd = 100.0 * Zwout;
|
||||||
ywd = 100.f / params->colorappearance.greenout;//approximation to simplify
|
ywd = 100.0 / params->colorappearance.greenout;//approximation to simplify
|
||||||
|
|
||||||
xws = 100.f * Xwsc;
|
xws = 100.0 * Xwsc;
|
||||||
zws = 100.f * Zwsc;
|
zws = 100.0 * Zwsc;
|
||||||
yws = 100.f / params->colorappearance.greensc;//approximation to simplify
|
yws = 100.0 / params->colorappearance.greensc;//approximation to simplify
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -699,20 +696,20 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw
|
|||||||
if (alg == 3 || alg == 1) {
|
if (alg == 3 || alg == 1) {
|
||||||
schr = params->colorappearance.schroma;
|
schr = params->colorappearance.schroma;
|
||||||
|
|
||||||
if (schr > 0.0) {
|
if (schr > 0.f) {
|
||||||
schr = schr / 2.0f; //divide sensibility for saturation
|
schr = schr / 2.f; //divide sensibility for saturation
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alg == 3) {
|
if (alg == 3) {
|
||||||
if (schr == -100.0f) {
|
if (schr == -100.f) {
|
||||||
schr = -99.f;
|
schr = -99.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schr == 100.0f) {
|
if (schr == 100.f) {
|
||||||
schr = 98.f;
|
schr = 98.f;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (schr == -100.0f) {
|
if (schr == -100.f) {
|
||||||
schr = -99.8f;
|
schr = -99.8f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -751,7 +748,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw
|
|||||||
LUTu hist16J;
|
LUTu hist16J;
|
||||||
LUTu hist16Q;
|
LUTu hist16Q;
|
||||||
|
|
||||||
if ((needJ && CAMBrightCurveJ.dirty) || (needQ && CAMBrightCurveQ.dirty) || (std::isnan (mean) && settings->viewinggreySc != 0)) {
|
if ((needJ && CAMBrightCurveJ.dirty) || (needQ && CAMBrightCurveQ.dirty) || (std::isnan(mean) && settings->viewinggreySc != 0)) {
|
||||||
|
|
||||||
if (needJ) {
|
if (needJ) {
|
||||||
hist16J (32768);
|
hist16J (32768);
|
||||||
@ -788,7 +785,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < height; i++)
|
for (int i = 0; i < height; i++) {
|
||||||
for (int j = 0; j < width; j++) { //rough correspondence between L and J
|
for (int j = 0; j < width; j++) { //rough correspondence between L and J
|
||||||
float currL = lab->L[i][j] / 327.68f;
|
float currL = lab->L[i][j] / 327.68f;
|
||||||
float koef; //rough correspondence between L and J
|
float koef; //rough correspondence between L and J
|
||||||
@ -849,10 +846,11 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw
|
|||||||
//hist16Qthr[ (int) (sqrtf ((koef * (lab->L[i][j])) * 32768.f))]++; //for brightness Q : approximation for Q=wh*sqrt(J/100) J not equal L
|
//hist16Qthr[ (int) (sqrtf ((koef * (lab->L[i][j])) * 32768.f))]++; //for brightness Q : approximation for Q=wh*sqrt(J/100) J not equal L
|
||||||
}
|
}
|
||||||
|
|
||||||
sum += koef * lab->L[i][j]; //evaluate mean J to calculate Yb
|
sum += static_cast<double>(koef) * static_cast<double>(lab->L[i][j]); //evaluate mean J to calculate Yb
|
||||||
//sumQ += whestim * sqrt ((koef * (lab->L[i][j])) / 32768.f);
|
//sumQ += whestim * sqrt ((koef * (lab->L[i][j])) / 32768.f);
|
||||||
//can be used in case of...
|
//can be used in case of...
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp critical
|
#pragma omp critical
|
||||||
@ -868,8 +866,8 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::isnan (mean)) {
|
if (std::isnan(mean)) {
|
||||||
mean = (sum / ((height) * width)) / 327.68f; //for Yb for all image...if one day "pipette" we can adapt Yb for each zone
|
mean = (sum / ((height) * width)) / 327.68; //for Yb for all image...if one day "pipette" we can adapt Yb for each zone
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
@ -916,9 +914,9 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw
|
|||||||
const bool highlight = params->toneCurve.hrenabled; //Get the value if "highlight reconstruction" is activated
|
const bool highlight = params->toneCurve.hrenabled; //Get the value if "highlight reconstruction" is activated
|
||||||
|
|
||||||
const int gamu = (params->colorappearance.gamut) ? 1 : 0;
|
const int gamu = (params->colorappearance.gamut) ? 1 : 0;
|
||||||
xw = 100.0f * Xw;
|
xw = 100.0 * Xw;
|
||||||
yw = 100.0f * Yw;
|
yw = 100.0 * Yw;
|
||||||
zw = 100.0f * Zw;
|
zw = 100.0 * Zw;
|
||||||
float xw1 = 0.f, yw1 = 0.f, zw1 = 0.f, xw2 = 0.f, yw2 = 0.f, zw2 = 0.f;
|
float xw1 = 0.f, yw1 = 0.f, zw1 = 0.f, xw2 = 0.f, yw2 = 0.f, zw2 = 0.f;
|
||||||
|
|
||||||
// settings of WB: scene and viewing
|
// settings of WB: scene and viewing
|
||||||
@ -2002,9 +2000,9 @@ void ImProcFunctions::moyeqt (Imagefloat* working, float &moyS, float &eqty)
|
|||||||
|
|
||||||
for (int i = 0; i < tHh; i++) {
|
for (int i = 0; i < tHh; i++) {
|
||||||
for (int j = 0; j < tWw; j++) {
|
for (int j = 0; j < tWw; j++) {
|
||||||
float s = Color::rgb2s (CLIP (working->r (i, j)), CLIP (working->g (i, j)), CLIP (working->b (i, j)));
|
double s = Color::rgb2s (CLIP (working->r (i, j)), CLIP (working->g (i, j)), CLIP (working->b (i, j)));
|
||||||
moy += s;
|
moy += s;
|
||||||
sqrs += SQR (s);
|
sqrs += SQR(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2108,17 +2106,17 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
|
|||||||
|
|
||||||
float toxyz[3][3] = {
|
float toxyz[3][3] = {
|
||||||
{
|
{
|
||||||
static_cast<float> ( wprof[0][0] / Color::D50x),
|
static_cast<float>(wprof[0][0] / static_cast<double>(Color::D50x)),
|
||||||
static_cast<float> ( wprof[0][1] / Color::D50x),
|
static_cast<float>(wprof[0][1] / static_cast<double>(Color::D50x)),
|
||||||
static_cast<float> ( wprof[0][2] / Color::D50x)
|
static_cast<float>(wprof[0][2] / static_cast<double>(Color::D50x))
|
||||||
}, {
|
}, {
|
||||||
static_cast<float> ( wprof[1][0]),
|
static_cast<float>(wprof[1][0]),
|
||||||
static_cast<float> ( wprof[1][1]),
|
static_cast<float>(wprof[1][1]),
|
||||||
static_cast<float> ( wprof[1][2])
|
static_cast<float>(wprof[1][2])
|
||||||
}, {
|
}, {
|
||||||
static_cast<float> ( wprof[2][0] / Color::D50z),
|
static_cast<float>(wprof[2][0] / static_cast<double>(Color::D50z)),
|
||||||
static_cast<float> ( wprof[2][1] / Color::D50z),
|
static_cast<float>(wprof[2][1] / static_cast<double>(Color::D50z)),
|
||||||
static_cast<float> ( wprof[2][2] / Color::D50z)
|
static_cast<float>(wprof[2][2] / static_cast<double>(Color::D50z))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
float maxFactorToxyz = max (toxyz[1][0], toxyz[1][1], toxyz[1][2]);
|
float maxFactorToxyz = max (toxyz[1][0], toxyz[1][1], toxyz[1][2]);
|
||||||
@ -2238,10 +2236,10 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
|
|||||||
|
|
||||||
const float film_simulation_strength = static_cast<float> (params->filmSimulation.strength) / 100.0f;
|
const float film_simulation_strength = static_cast<float> (params->filmSimulation.strength) / 100.0f;
|
||||||
|
|
||||||
const float exp_scale = pow (2.0, expcomp);
|
const float exp_scale = pow(2.0, expcomp);
|
||||||
const float comp = (max (0.0, expcomp) + 1.0) * hlcompr / 100.0;
|
const float comp = (max(0.0, expcomp) + 1.0) * hlcompr / 100.0;
|
||||||
const float shoulder = ((65536.0 / max (1.0f, exp_scale)) * (hlcomprthresh / 200.0)) + 0.1;
|
const float shoulder = ((65536.f / max(1.0f, exp_scale)) * (hlcomprthresh / 200.f)) + 0.1f;
|
||||||
const float hlrange = 65536.0 - shoulder;
|
const float hlrange = 65536.f - shoulder;
|
||||||
const bool isProPhoto = (params->icm.workingProfile == "ProPhoto");
|
const bool isProPhoto = (params->icm.workingProfile == "ProPhoto");
|
||||||
// extracting data from 'params' to avoid cache flush (to be confirmed)
|
// extracting data from 'params' to avoid cache flush (to be confirmed)
|
||||||
ToneCurveMode curveMode = params->toneCurve.curveMode;
|
ToneCurveMode curveMode = params->toneCurve.curveMode;
|
||||||
@ -2303,43 +2301,43 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
float RedLow = params->colorToning.redlow / 100.f;
|
float RedLow = params->colorToning.redlow / 100.0;
|
||||||
float GreenLow = params->colorToning.greenlow / 100.f;
|
float GreenLow = params->colorToning.greenlow / 100.0;
|
||||||
float BlueLow = params->colorToning.bluelow / 100.f;
|
float BlueLow = params->colorToning.bluelow / 100.0;
|
||||||
float RedMed = params->colorToning.redmed / 100.f;
|
float RedMed = params->colorToning.redmed / 100.0;
|
||||||
float GreenMed = params->colorToning.greenmed / 100.f;
|
float GreenMed = params->colorToning.greenmed / 100.0;
|
||||||
float BlueMed = params->colorToning.bluemed / 100.f;
|
float BlueMed = params->colorToning.bluemed / 100.0;
|
||||||
float RedHigh = params->colorToning.redhigh / 100.f;
|
float RedHigh = params->colorToning.redhigh / 100.0;
|
||||||
float GreenHigh = params->colorToning.greenhigh / 100.f;
|
float GreenHigh = params->colorToning.greenhigh / 100.0;
|
||||||
float BlueHigh = params->colorToning.bluehigh / 100.f;
|
float BlueHigh = params->colorToning.bluehigh / 100.0;
|
||||||
float SatLow = float (params->colorToning.shadowsColSat.getBottom()) / 100.f;
|
float SatLow = params->colorToning.shadowsColSat.getBottom() / 100.f;
|
||||||
float SatHigh = float (params->colorToning.hlColSat.getBottom()) / 100.f;
|
float SatHigh = params->colorToning.hlColSat.getBottom() / 100.f;
|
||||||
|
|
||||||
float Balan = float (params->colorToning.balance);
|
float Balan = params->colorToning.balance;
|
||||||
|
|
||||||
float chMixRR = float (params->chmixer.red[0])/10.f;
|
float chMixRR = params->chmixer.red[0] / 10.f;
|
||||||
float chMixRG = float (params->chmixer.red[1])/10.f;
|
float chMixRG = params->chmixer.red[1] / 10.f;
|
||||||
float chMixRB = float (params->chmixer.red[2])/10.f;
|
float chMixRB = params->chmixer.red[2] / 10.f;
|
||||||
float chMixGR = float (params->chmixer.green[0])/10.f;
|
float chMixGR = params->chmixer.green[0] / 10.f;
|
||||||
float chMixGG = float (params->chmixer.green[1])/10.f;
|
float chMixGG = params->chmixer.green[1] / 10.f;
|
||||||
float chMixGB = float (params->chmixer.green[2])/10.f;
|
float chMixGB = params->chmixer.green[2] / 10.f;
|
||||||
float chMixBR = float (params->chmixer.blue[0])/10.f;
|
float chMixBR = params->chmixer.blue[0] / 10.f;
|
||||||
float chMixBG = float (params->chmixer.blue[1])/10.f;
|
float chMixBG = params->chmixer.blue[1] / 10.f;
|
||||||
float chMixBB = float (params->chmixer.blue[2])/10.f;
|
float chMixBB = params->chmixer.blue[2] / 10.f;
|
||||||
|
|
||||||
bool blackwhite = params->blackwhite.enabled;
|
bool blackwhite = params->blackwhite.enabled;
|
||||||
bool complem = params->blackwhite.enabledcc;
|
bool complem = params->blackwhite.enabledcc;
|
||||||
float bwr = float (params->blackwhite.mixerRed);
|
float bwr = params->blackwhite.mixerRed;
|
||||||
float bwg = float (params->blackwhite.mixerGreen);
|
float bwg = params->blackwhite.mixerGreen;
|
||||||
float bwb = float (params->blackwhite.mixerBlue);
|
float bwb = params->blackwhite.mixerBlue;
|
||||||
float bwrgam = float (params->blackwhite.gammaRed);
|
float bwrgam = params->blackwhite.gammaRed;
|
||||||
float bwggam = float (params->blackwhite.gammaGreen);
|
float bwggam = params->blackwhite.gammaGreen;
|
||||||
float bwbgam = float (params->blackwhite.gammaBlue);
|
float bwbgam = params->blackwhite.gammaBlue;
|
||||||
float mixerOrange = float (params->blackwhite.mixerOrange);
|
float mixerOrange = params->blackwhite.mixerOrange;
|
||||||
float mixerYellow = float (params->blackwhite.mixerYellow);
|
float mixerYellow = params->blackwhite.mixerYellow;
|
||||||
float mixerCyan = float (params->blackwhite.mixerCyan);
|
float mixerCyan = params->blackwhite.mixerCyan;
|
||||||
float mixerMagenta = float (params->blackwhite.mixerMagenta);
|
float mixerMagenta = params->blackwhite.mixerMagenta;
|
||||||
float mixerPurple = float (params->blackwhite.mixerPurple);
|
float mixerPurple = params->blackwhite.mixerPurple;
|
||||||
int algm = 0;
|
int algm = 0;
|
||||||
|
|
||||||
if (params->blackwhite.method == "Desaturation") {
|
if (params->blackwhite.method == "Desaturation") {
|
||||||
@ -2720,7 +2718,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
|
|||||||
|
|
||||||
//HSV equalizer
|
//HSV equalizer
|
||||||
if (hCurveEnabled) {
|
if (hCurveEnabled) {
|
||||||
h = (hCurve->getVal (double (h)) - 0.5) * 2.f + h;
|
h = (hCurve->getVal(h) - 0.5) * 2.0 + static_cast<double>(h);
|
||||||
|
|
||||||
if (h > 1.0f) {
|
if (h > 1.0f) {
|
||||||
h -= 1.0f;
|
h -= 1.0f;
|
||||||
@ -2751,7 +2749,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
|
|||||||
}
|
}
|
||||||
|
|
||||||
//shift value
|
//shift value
|
||||||
float valparam = vCurve->getVal ((double)h) - 0.5f;
|
float valparam = vCurve->getVal(h) - 0.5;
|
||||||
valparam *= (1.f - SQR (SQR (1.f - min (s, 1.0f))));
|
valparam *= (1.f - SQR (SQR (1.f - min (s, 1.0f))));
|
||||||
|
|
||||||
if (valparam > 0.00001f) {
|
if (valparam > 0.00001f) {
|
||||||
@ -3063,7 +3061,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
|
|||||||
if (bwlCurveEnabled) {
|
if (bwlCurveEnabled) {
|
||||||
L /= 32768.f;
|
L /= 32768.f;
|
||||||
double hr = Color::huelab_to_huehsv2 (HH);
|
double hr = Color::huelab_to_huehsv2 (HH);
|
||||||
float valparam = float ((bwlCurve->getVal (hr) - 0.5f) * 2.0f); //get l_r=f(H)
|
float valparam = (bwlCurve->getVal(hr) - 0.5) * 2.0; //get l_r=f(H)
|
||||||
float kcc = (CC / 70.f); //take Chroma into account...70 "middle" of chromaticity (arbitrary and simple), one can imagine other algorithme
|
float kcc = (CC / 70.f); //take Chroma into account...70 "middle" of chromaticity (arbitrary and simple), one can imagine other algorithme
|
||||||
//reduct action for low chroma and increase action for high chroma
|
//reduct action for low chroma and increase action for high chroma
|
||||||
valparam *= kcc;
|
valparam *= kcc;
|
||||||
@ -3317,9 +3315,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
|
|||||||
|
|
||||||
for (int i = 0; i < tH; i++) {
|
for (int i = 0; i < tH; i++) {
|
||||||
for (int j = 0; j < tW; j++) {
|
for (int j = 0; j < tW; j++) {
|
||||||
nr += tmpImage->r (i, j);
|
nr += static_cast<double>(tmpImage->r(i, j));
|
||||||
ng += tmpImage->g (i, j);
|
ng += static_cast<double>(tmpImage->g(i, j));
|
||||||
nb += tmpImage->b (i, j);
|
nb += static_cast<double>(tmpImage->b(i, j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4385,8 +4383,7 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW
|
|||||||
float factnoise = 1.f;
|
float factnoise = 1.f;
|
||||||
|
|
||||||
if (params->dirpyrDenoise.enabled) {
|
if (params->dirpyrDenoise.enabled) {
|
||||||
factnoise = (1.f + params->dirpyrDenoise.chroma / 500.f); //levels=5
|
factnoise = 1.0 + params->dirpyrDenoise.chroma / 500.0; //levels=5
|
||||||
// if(yyyy) factnoise=(1.f+params->dirpyrDenoise.chroma/100.f);//levels=7
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const float scaleConst = 100.0f / 100.1f;
|
const float scaleConst = 100.0f / 100.1f;
|
||||||
@ -4564,7 +4561,7 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW
|
|||||||
float l_r;//Luminance Lab in 0..1
|
float l_r;//Luminance Lab in 0..1
|
||||||
l_r = Lprov1 / 100.f;
|
l_r = Lprov1 / 100.f;
|
||||||
{
|
{
|
||||||
float valparam = float ((lhCurve->getVal (Color::huelab_to_huehsv2 (HH)) - 0.5f)); //get l_r=f(H)
|
float valparam = lhCurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5; //get l_r=f(H)
|
||||||
float valparamneg;
|
float valparamneg;
|
||||||
valparamneg = valparam;
|
valparamneg = valparam;
|
||||||
float kcc = (CC / amountchroma); //take Chroma into account...40 "middle low" of chromaticity (arbitrary and simple), one can imagine other algorithme
|
float kcc = (CC / amountchroma); //take Chroma into account...40 "middle low" of chromaticity (arbitrary and simple), one can imagine other algorithme
|
||||||
@ -4597,9 +4594,9 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW
|
|||||||
float fx = (0.002f * aprov1) + fy;
|
float fx = (0.002f * aprov1) + fy;
|
||||||
float fz = fy - (0.005f * bprov1);
|
float fz = fy - (0.005f * bprov1);
|
||||||
|
|
||||||
float x_ = 65535.0f * Color::f2xyz (fx) * Color::D50x;
|
float x_ = 65535.f * Color::f2xyz (fx) * Color::D50x;
|
||||||
float z_ = 65535.0f * Color::f2xyz (fz) * Color::D50z;
|
float z_ = 65535.f * Color::f2xyz (fz) * Color::D50z;
|
||||||
float y_ = (Lprov1 > Color::epskap) ? 65535.0 * fy * fy * fy : 65535.0 * Lprov1 / Color::kappa;
|
float y_ = Lprov1 > Color::epskapf ? 65535.f * fy * fy * fy : 65535.f * Lprov1 / Color::kappaf;
|
||||||
float R, G, B;
|
float R, G, B;
|
||||||
Color::xyz2rgb (x_, y_, z_, R, G, B, wip);
|
Color::xyz2rgb (x_, y_, z_, R, G, B, wip);
|
||||||
|
|
||||||
@ -4627,7 +4624,7 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW
|
|||||||
// calculate C=f(H)
|
// calculate C=f(H)
|
||||||
if (chutili) {
|
if (chutili) {
|
||||||
double hr = Color::huelab_to_huehsv2 (HH);
|
double hr = Color::huelab_to_huehsv2 (HH);
|
||||||
float chparam = float ((chCurve->getVal (hr) - 0.5f) * 2.0f); //get C=f(H)
|
float chparam = (chCurve->getVal(hr) - 0.5) * 2.0; //get C=f(H)
|
||||||
float chromaChfactor = 1.0f + chparam;
|
float chromaChfactor = 1.0f + chparam;
|
||||||
atmp *= chromaChfactor;//apply C=f(H)
|
atmp *= chromaChfactor;//apply C=f(H)
|
||||||
btmp *= chromaChfactor;
|
btmp *= chromaChfactor;
|
||||||
@ -4635,9 +4632,9 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW
|
|||||||
|
|
||||||
if (hhutili) { // H=f(H)
|
if (hhutili) { // H=f(H)
|
||||||
//hue Lab in -PI +PI
|
//hue Lab in -PI +PI
|
||||||
float valparam = float ((hhCurve->getVal (Color::huelab_to_huehsv2 (HH)) - 0.5f) * 1.7f) + HH; //get H=f(H) 1.7 optimisation !
|
float valparam = (hhCurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5) * 1.7 + static_cast<double>(HH); //get H=f(H) 1.7 optimisation !
|
||||||
HH = valparam;
|
HH = valparam;
|
||||||
sincosval = xsincosf (HH);
|
sincosval = xsincosf(HH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bwToning) {
|
if (!bwToning) {
|
||||||
@ -4713,11 +4710,11 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW
|
|||||||
|
|
||||||
deltaHH = protect_redhcur; //transition hue
|
deltaHH = protect_redhcur; //transition hue
|
||||||
|
|
||||||
if (chromaCfactor > 0.0) {
|
if (chromaCfactor > 0.f) {
|
||||||
Color::scalered ( rstprotection, chromaCfactor, 0.0, HH, deltaHH, scale, scaleext); //1.0
|
Color::scalered ( rstprotection, chromaCfactor, 0.0, HH, deltaHH, scale, scaleext); //1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chromaCfactor > 1.0) {
|
if (chromaCfactor > 1.f) {
|
||||||
float interm = (chromaCfactor - 1.0f) * 100.0f;
|
float interm = (chromaCfactor - 1.0f) * 100.0f;
|
||||||
factorskin = 1.0f + (interm * scale) / 100.0f;
|
factorskin = 1.0f + (interm * scale) / 100.0f;
|
||||||
factorskinext = 1.0f + (interm * scaleext) / 100.0f;
|
factorskinext = 1.0f + (interm * scaleext) / 100.0f;
|
||||||
@ -4774,11 +4771,11 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW
|
|||||||
|
|
||||||
deltaHH = protect_redhcur; //transition hue
|
deltaHH = protect_redhcur; //transition hue
|
||||||
|
|
||||||
if (chromaCfactor > 0.0) {
|
if (chromaCfactor > 0.f) {
|
||||||
Color::scalered ( rstprotection, chromaCfactor, 0.0, HH, deltaHH, scale, scaleext); //1.0
|
Color::scalered ( rstprotection, chromaCfactor, 0.0, HH, deltaHH, scale, scaleext); //1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chromaCfactor > 1.0) {
|
if (chromaCfactor > 1.f) {
|
||||||
float interm = (chromaCfactor - 1.0f) * 100.0f;
|
float interm = (chromaCfactor - 1.0f) * 100.0f;
|
||||||
factorskin = 1.0f + (interm * scale) / 100.0f;
|
factorskin = 1.0f + (interm * scale) / 100.0f;
|
||||||
factorskinext = 1.0f + (interm * scaleext) / 100.0f;
|
factorskinext = 1.0f + (interm * scaleext) / 100.0f;
|
||||||
@ -5061,7 +5058,7 @@ void ImProcFunctions::impulsedenoise (LabImage* lab)
|
|||||||
if (params->impulseDenoise.enabled && lab->W >= 8 && lab->H >= 8)
|
if (params->impulseDenoise.enabled && lab->W >= 8 && lab->H >= 8)
|
||||||
|
|
||||||
{
|
{
|
||||||
impulse_nr (lab, (float)params->impulseDenoise.thresh / 20.0 );
|
impulse_nr(lab, params->impulseDenoise.thresh / 20.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5071,7 +5068,7 @@ void ImProcFunctions::impulsedenoisecam (CieImage* ncie, float **buffers[3])
|
|||||||
if (params->impulseDenoise.enabled && ncie->W >= 8 && ncie->H >= 8)
|
if (params->impulseDenoise.enabled && ncie->W >= 8 && ncie->H >= 8)
|
||||||
|
|
||||||
{
|
{
|
||||||
impulse_nrcam (ncie, (float)params->impulseDenoise.thresh / 20.0, buffers );
|
impulse_nrcam(ncie, params->impulseDenoise.thresh / 20.0, buffers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5141,11 +5138,11 @@ void ImProcFunctions::EPDToneMapCIE (CieImage *ncie, float a_w, float c_, int Wi
|
|||||||
float sca = params->epd.scale;
|
float sca = params->epd.scale;
|
||||||
float gamm = params->epd.gamma;
|
float gamm = params->epd.gamma;
|
||||||
float rew = params->epd.reweightingIterates;
|
float rew = params->epd.reweightingIterates;
|
||||||
float Qpro = ( 4.0 / c_) * ( a_w + 4.0 ) ; //estimate Q max if J=100.0
|
float Qpro = (4.f / c_) * (a_w + 4.f) ; //estimate Q max if J=100.0
|
||||||
float *Qpr = ncie->Q_p[0];
|
float *Qpr = ncie->Q_p[0];
|
||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
printf ("minQ=%f maxQ=%f Qpro=%f\n", minQ, maxQ, Qpro);
|
printf ("minQ=%f maxQ=%f Qpro=%f\n", static_cast<double>(minQ), static_cast<double>(maxQ), static_cast<double>(Qpro));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxQ > Qpro) {
|
if (maxQ > Qpro) {
|
||||||
@ -5172,7 +5169,7 @@ void ImProcFunctions::EPDToneMapCIE (CieImage *ncie, float a_w, float c_, int Wi
|
|||||||
|
|
||||||
//Auto select number of iterates. Note that p->EdgeStopping = 0 makes a Gaussian blur.
|
//Auto select number of iterates. Note that p->EdgeStopping = 0 makes a Gaussian blur.
|
||||||
if (Iterates == 0) {
|
if (Iterates == 0) {
|
||||||
Iterates = (unsigned int) (edgest * 15.0);
|
Iterates = edgest * 15.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Jacques Desmis : always Iterates=5 for compatibility images between preview and output
|
//Jacques Desmis : always Iterates=5 for compatibility images between preview and output
|
||||||
@ -5399,7 +5396,7 @@ void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double
|
|||||||
octile[count] += histogram[j];
|
octile[count] += histogram[j];
|
||||||
|
|
||||||
if (octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f)) {
|
if (octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f)) {
|
||||||
octile[count] = xlog (1. + j) / log (2.f);
|
octile[count] = xlog(1. + j) / log(2.0);
|
||||||
count++;// = min(count+1,7);
|
count++;// = min(count+1,7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5412,7 +5409,7 @@ void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double
|
|||||||
octile[count] += histogram[j];
|
octile[count] += histogram[j];
|
||||||
|
|
||||||
if (octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f)) {
|
if (octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f)) {
|
||||||
octile[count] = xlog (1. + j) / log (2.f);
|
octile[count] = xlog(1. + j) / log(2.0);
|
||||||
count++;// = min(count+1,7);
|
count++;// = min(count+1,7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5487,7 +5484,7 @@ void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double
|
|||||||
}
|
}
|
||||||
|
|
||||||
//compute clipped white point
|
//compute clipped white point
|
||||||
unsigned int clippable = (int) (sum * clip / 100.f );
|
unsigned int clippable = (int) (static_cast<double>(sum) * clip / 100.0 );
|
||||||
clipped = 0;
|
clipped = 0;
|
||||||
int whiteclip = (imax) - 1;
|
int whiteclip = (imax) - 1;
|
||||||
|
|
||||||
@ -5546,8 +5543,8 @@ void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double
|
|||||||
hlcomprthresh = 0;
|
hlcomprthresh = 0;
|
||||||
//this is a series approximation of the actual formula for comp,
|
//this is a series approximation of the actual formula for comp,
|
||||||
//which is a transcendental equation
|
//which is a transcendental equation
|
||||||
float comp = (gain * ((float)whiteclip) / scale - 1.f) * 2.3f; // 2.3 instead of 2 to increase slightly comp
|
double comp = (gain * whiteclip / scale - 1.f) * 2.3f; // 2.3 instead of 2 to increase slightly comp
|
||||||
hlcompr = (int) (100.*comp / (max (0.0, expcomp) + 1.0));
|
hlcompr = 100.0 * comp / (max(0.0, expcomp) + 1.0);
|
||||||
hlcompr = max (0, min (100, hlcompr));
|
hlcompr = max (0, min (100, hlcompr));
|
||||||
|
|
||||||
//now find brightness if gain didn't bring ave to midgray using
|
//now find brightness if gain didn't bring ave to midgray using
|
||||||
@ -5555,9 +5552,9 @@ void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double
|
|||||||
float midtmp = gain * sqrt (median * ave) / scale;
|
float midtmp = gain * sqrt (median * ave) / scale;
|
||||||
|
|
||||||
if (midtmp < 0.1f) {
|
if (midtmp < 0.1f) {
|
||||||
bright = (midgray - midtmp) * 15.0 / (midtmp);
|
bright = (midgray - midtmp) * 15.f / (midtmp);
|
||||||
} else {
|
} else {
|
||||||
bright = (midgray - midtmp) * 15.0 / (0.10833 - 0.0833 * midtmp);
|
bright = (midgray - midtmp) * 15.f / (0.10833f - 0.0833f * midtmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bright = 0.25 */*(median/ave)*(hidev/lodev)*/max (0, bright);
|
bright = 0.25 */*(median/ave)*(hidev/lodev)*/max (0, bright);
|
||||||
@ -5566,7 +5563,7 @@ void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double
|
|||||||
contr = (int) 50.0f * (1.1f - ospread);
|
contr = (int) 50.0f * (1.1f - ospread);
|
||||||
contr = max (0, min (100, contr));
|
contr = max (0, min (100, contr));
|
||||||
//take gamma into account
|
//take gamma into account
|
||||||
double whiteclipg = (int) (CurveFactory::gamma2 (whiteclip * corr / 65536.0) * 65536.0);
|
double whiteclipg = (int) (CurveFactory::gamma2(whiteclip * static_cast<double>(corr) / 65536.0) * 65536.0);
|
||||||
|
|
||||||
float gavg = 0.;
|
float gavg = 0.;
|
||||||
|
|
||||||
@ -5588,7 +5585,7 @@ void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
whiteclipg = CurveFactory::igamma2 ((float) (whiteclipg / 65535.0)) * 65535.0; //need to inverse gamma transform to get correct exposure compensation parameter
|
whiteclipg = CurveFactory::igamma2(whiteclipg / 65535.0) * 65535.0; //need to inverse gamma transform to get correct exposure compensation parameter
|
||||||
|
|
||||||
//correction with gamma
|
//correction with gamma
|
||||||
black = (int) ((65535 * black) / whiteclipg);
|
black = (int) ((65535 * black) / whiteclipg);
|
||||||
@ -5823,8 +5820,8 @@ void ImProcFunctions::lab2rgb (const LabImage &src, Imagefloat &dst, const Glib:
|
|||||||
*/
|
*/
|
||||||
void ImProcFunctions::colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread)
|
void ImProcFunctions::colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread)
|
||||||
{
|
{
|
||||||
const float factor = ColorToningParams::LABGRID_CORR_MAX * 3.f;
|
const double factor = ColorToningParams::LABGRID_CORR_MAX * 3.0;
|
||||||
const float scaling = ColorToningParams::LABGRID_CORR_SCALE;
|
const double scaling = ColorToningParams::LABGRID_CORR_SCALE;
|
||||||
float a_scale = (params->colorToning.labgridAHigh - params->colorToning.labgridALow) / factor / scaling;
|
float a_scale = (params->colorToning.labgridAHigh - params->colorToning.labgridALow) / factor / scaling;
|
||||||
float a_base = params->colorToning.labgridALow / scaling;
|
float a_base = params->colorToning.labgridALow / scaling;
|
||||||
float b_scale = (params->colorToning.labgridBHigh - params->colorToning.labgridBLow) / factor / scaling;
|
float b_scale = (params->colorToning.labgridBHigh - params->colorToning.labgridBLow) / factor / scaling;
|
||||||
|
@ -19,11 +19,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "coord2d.h"
|
#include "coord2d.h"
|
||||||
#include "gamutwarning.h"
|
#include "gamutwarning.h"
|
||||||
#include "pipettebuffer.h"
|
|
||||||
|
|
||||||
|
namespace Glib
|
||||||
|
{
|
||||||
|
|
||||||
|
class ustring;
|
||||||
|
|
||||||
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class LUT;
|
class LUT;
|
||||||
|
|
||||||
@ -44,6 +50,7 @@ class FramesMetaData;
|
|||||||
class LensCorrection;
|
class LensCorrection;
|
||||||
class NoiseCurve;
|
class NoiseCurve;
|
||||||
class OpacityCurve;
|
class OpacityCurve;
|
||||||
|
class PipetteBuffer;
|
||||||
class ToneCurve;
|
class ToneCurve;
|
||||||
class WavCurve;
|
class WavCurve;
|
||||||
class WavOpacityCurveBY;
|
class WavOpacityCurveBY;
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "array2D.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "guidedfilter.h"
|
#include "guidedfilter.h"
|
||||||
#include "iccstore.h"
|
#include "iccstore.h"
|
||||||
@ -240,9 +241,9 @@ float estimate_ambient_light(const array2D<float> &R, const array2D<float> &G, c
|
|||||||
float g = G[y][x];
|
float g = G[y][x];
|
||||||
float b = B[y][x];
|
float b = B[y][x];
|
||||||
if (r + g + b >= bright_lim) {
|
if (r + g + b >= bright_lim) {
|
||||||
rr += r;
|
rr += static_cast<double>(r);
|
||||||
gg += g;
|
gg += static_cast<double>(g);
|
||||||
bb += b;
|
bb += static_cast<double>(b);
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ BENCHFUN
|
|||||||
auto &hm = hmask[i];
|
auto &hm = hmask[i];
|
||||||
auto &cm = cmask[i];
|
auto &cm = cmask[i];
|
||||||
auto &lm = lmask[i];
|
auto &lm = lmask[i];
|
||||||
float blend = LIM01((hm ? hm->getVal(h) : 1.f) * (cm ? cm->getVal(c) : 1.f) * (lm ? lm->getVal(l) : 1.f));
|
float blend = LIM01((hm ? hm->getVal(h) : 1.0) * (cm ? cm->getVal(c) : 1.0) * (lm ? lm->getVal(l) : 1.0));
|
||||||
Lmask[i][y][x] = abmask[i][y][x] = blend;
|
Lmask[i][y][x] = abmask[i][y][x] = blend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,8 +147,8 @@ BENCHFUN
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = begin_idx; i < end_idx; ++i) {
|
for (int i = begin_idx; i < end_idx; ++i) {
|
||||||
float blur = params->colorToning.labregions[i].maskBlur;
|
double blur = params->colorToning.labregions[i].maskBlur;
|
||||||
blur = blur < 0.f ? -1.f/blur : 1.f + blur;
|
blur = blur < 0.0 ? -1.0 / blur : 1.0 + blur;
|
||||||
int r1 = max(int(4 / scale * blur + 0.5), 1);
|
int r1 = max(int(4 / scale * blur + 0.5), 1);
|
||||||
int r2 = max(int(25 / scale * blur + 0.5), 1);
|
int r2 = max(int(25 / scale * blur + 0.5), 1);
|
||||||
rtengine::guidedFilter(guide, abmask[i], abmask[i], r1, 0.001, multiThread);
|
rtengine::guidedFilter(guide, abmask[i], abmask[i], r1, 0.001, multiThread);
|
||||||
@ -188,7 +188,7 @@ BENCHFUN
|
|||||||
auto &r = params->colorToning.labregions[i];
|
auto &r = params->colorToning.labregions[i];
|
||||||
abca[i] = abcoord(r.a);
|
abca[i] = abcoord(r.a);
|
||||||
abcb[i] = abcoord(r.b);
|
abcb[i] = abcoord(r.b);
|
||||||
rs[i] = 1.f + r.saturation / (SGN(r.saturation) > 0 ? 50.f : 100.f);
|
rs[i] = 1.0 + r.saturation / (SGN(r.saturation) > 0 ? 50.0 : 100.0);
|
||||||
slope[i] = r.slope;
|
slope[i] = r.slope;
|
||||||
offset[i] = r.offset;
|
offset[i] = r.offset;
|
||||||
power[i] = r.power;
|
power[i] = r.power;
|
||||||
|
@ -110,8 +110,8 @@ void mean_stddv2( float **dst, float &mean, float &stddv, int W_L, int H_L, floa
|
|||||||
|
|
||||||
for (int i = 0; i < H_L; i++ )
|
for (int i = 0; i < H_L; i++ )
|
||||||
for (int j = 0; j < W_L; j++) {
|
for (int j = 0; j < W_L; j++) {
|
||||||
sum += dst[i][j];
|
sum += static_cast<double>(dst[i][j]);
|
||||||
vsquared += (dst[i][j] * dst[i][j]);
|
vsquared += rtengine::SQR<double>(dst[i][j]);
|
||||||
|
|
||||||
lmax = dst[i][j] > lmax ? dst[i][j] : lmax;
|
lmax = dst[i][j] > lmax ? dst[i][j] : lmax;
|
||||||
lmin = dst[i][j] < lmin ? dst[i][j] : lmin;
|
lmin = dst[i][j] < lmin ? dst[i][j] : lmin;
|
||||||
@ -128,8 +128,8 @@ void mean_stddv2( float **dst, float &mean, float &stddv, int W_L, int H_L, floa
|
|||||||
}
|
}
|
||||||
mean = sum / (double) (W_L * H_L);
|
mean = sum / (double) (W_L * H_L);
|
||||||
vsquared /= (double) W_L * H_L;
|
vsquared /= (double) W_L * H_L;
|
||||||
stddv = ( vsquared - (mean * mean) );
|
stddv = vsquared - rtengine::SQR<double>(mean);
|
||||||
stddv = (float)sqrt(stddv);
|
stddv = std::sqrt(stddv);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -678,9 +678,9 @@ BENCHFUN
|
|||||||
float valparam;
|
float valparam;
|
||||||
|
|
||||||
if(useHsl || useHslLin) {
|
if(useHsl || useHslLin) {
|
||||||
valparam = shcurve->getVal(HH) - 0.5f;
|
valparam = shcurve->getVal(HH) - 0.5;
|
||||||
} else {
|
} else {
|
||||||
valparam = shcurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f;
|
valparam = shcurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
str *= (1.f + 2.f * valparam);
|
str *= (1.f + 2.f * valparam);
|
||||||
|
@ -46,7 +46,7 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab)
|
|||||||
|
|
||||||
array2D<float> mask(width, height);
|
array2D<float> mask(width, height);
|
||||||
array2D<float> L(width, height);
|
array2D<float> L(width, height);
|
||||||
const float radius = float(params->sh.radius) * 10 / scale;
|
const float radius = params->sh.radius * 10 / scale;
|
||||||
LUTf f(lab_mode ? 32768 : 65536);
|
LUTf f(lab_mode ? 32768 : 65536);
|
||||||
|
|
||||||
TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile);
|
TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile);
|
||||||
|
@ -103,7 +103,7 @@ void sharpenHaloCtrl (float** luminance, float** blurmap, float** base, float**
|
|||||||
void dcdamping (float** aI, float** aO, float damping, int W, int H)
|
void dcdamping (float** aI, float** aO, float damping, int W, int H)
|
||||||
{
|
{
|
||||||
|
|
||||||
const float dampingFac = -2.0 / (damping * damping);
|
const float dampingFac = -2.f / (damping * damping);
|
||||||
|
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
vfloat Iv, Ov, Uv, zerov, onev, fourv, fivev, dampingFacv, Tv, Wv, Lv;
|
vfloat Iv, Ov, Uv, zerov, onev, fourv, fivev, dampingFacv, Tv, Wv, Lv;
|
||||||
@ -163,7 +163,7 @@ namespace rtengine
|
|||||||
|
|
||||||
void ImProcFunctions::deconvsharpening (float** luminance, float** tmp, const float * const * blend, int W, int H, const procparams::SharpeningParams &sharpenParam, double Scale)
|
void ImProcFunctions::deconvsharpening (float** luminance, float** tmp, const float * const * blend, int W, int H, const procparams::SharpeningParams &sharpenParam, double Scale)
|
||||||
{
|
{
|
||||||
if (sharpenParam.deconvamount == 0 && sharpenParam.blurradius < 0.25f) {
|
if (sharpenParam.deconvamount == 0 && sharpenParam.blurradius < 0.25) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BENCHFUN
|
BENCHFUN
|
||||||
@ -180,7 +180,7 @@ BENCHFUN
|
|||||||
|
|
||||||
JaggedArray<float>* blurbuffer = nullptr;
|
JaggedArray<float>* blurbuffer = nullptr;
|
||||||
|
|
||||||
if (sharpenParam.blurradius >= 0.25f) {
|
if (sharpenParam.blurradius >= 0.25) {
|
||||||
blurbuffer = new JaggedArray<float>(W, H);
|
blurbuffer = new JaggedArray<float>(W, H);
|
||||||
JaggedArray<float> &blur = *blurbuffer;
|
JaggedArray<float> &blur = *blurbuffer;
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
@ -229,7 +229,7 @@ BENCHFUN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sharpenParam.blurradius >= 0.25f) {
|
if (sharpenParam.blurradius >= 0.25) {
|
||||||
JaggedArray<float> &blur = *blurbuffer;
|
JaggedArray<float> &blur = *blurbuffer;
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp for
|
#pragma omp for
|
||||||
@ -255,7 +255,7 @@ void ImProcFunctions::sharpening (LabImage* lab, const procparams::SharpeningPar
|
|||||||
|
|
||||||
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
||||||
JaggedArray<float> blend(W, H);
|
JaggedArray<float> blend(W, H);
|
||||||
float contrast = sharpenParam.contrast / 100.f;
|
float contrast = sharpenParam.contrast / 100.0;
|
||||||
buildBlendMask(lab->L, blend, W, H, contrast);
|
buildBlendMask(lab->L, blend, W, H, contrast);
|
||||||
|
|
||||||
if(showMask) {
|
if(showMask) {
|
||||||
@ -292,7 +292,7 @@ BENCHFUN
|
|||||||
|
|
||||||
JaggedArray<float> blur(W, H);
|
JaggedArray<float> blur(W, H);
|
||||||
|
|
||||||
if (sharpenParam.blurradius >= 0.25f) {
|
if (sharpenParam.blurradius >= 0.25) {
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
#endif
|
#endif
|
||||||
@ -372,7 +372,7 @@ BENCHFUN
|
|||||||
delete [] b3;
|
delete [] b3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sharpenParam.blurradius >= 0.25f) {
|
if (sharpenParam.blurradius >= 0.25) {
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
#endif
|
#endif
|
||||||
@ -385,241 +385,6 @@ BENCHFUN
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// To the extent possible under law, Manuel Llorens <manuelllorens@gmail.com>
|
|
||||||
// has waived all copyright and related or neighboring rights to this work.
|
|
||||||
// This work is published from: Spain.
|
|
||||||
|
|
||||||
// Thanks to Manuel for this excellent job (Jacques Desmis JDC or frej83)
|
|
||||||
void ImProcFunctions::MLsharpen (LabImage* lab)
|
|
||||||
{
|
|
||||||
// JD: this algorithm maximize clarity of images; it does not play on accutance. It can remove (partially) the effects of the AA filter)
|
|
||||||
// I think we can use this algorithm alone in most cases, or first to clarify image and if you want a very little USM (unsharp mask sharpening) after...
|
|
||||||
if (!params->sharpenEdge.enabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MyTime t1e, t2e;
|
|
||||||
t1e.set();
|
|
||||||
|
|
||||||
int offset, c, i, j, p, width2;
|
|
||||||
int width = lab->W, height = lab->H;
|
|
||||||
float *L, lumH, lumV, lumD1, lumD2, v, contrast, s;
|
|
||||||
float difL, difR, difT, difB, difLT, difRB, difLB, difRT, wH, wV, wD1, wD2, chmax[3];
|
|
||||||
float f1, f2, f3, f4;
|
|
||||||
float templab;
|
|
||||||
int iii, kkk;
|
|
||||||
width2 = 2 * width;
|
|
||||||
const float epsil = 0.01f; //prevent divide by zero
|
|
||||||
const float eps2 = 0.001f; //prevent divide by zero
|
|
||||||
float amount;
|
|
||||||
amount = params->sharpenEdge.amount / 100.0f;
|
|
||||||
|
|
||||||
if (amount < 0.00001f) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings->verbose) {
|
|
||||||
printf ("SharpenEdge amount %f\n", amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
L = new float[width * height];
|
|
||||||
|
|
||||||
chmax[0] = 8.0f;
|
|
||||||
chmax[1] = 3.0f;
|
|
||||||
chmax[2] = 3.0f;
|
|
||||||
|
|
||||||
int channels;
|
|
||||||
|
|
||||||
if (params->sharpenEdge.threechannels) {
|
|
||||||
channels = 0;
|
|
||||||
} else {
|
|
||||||
channels = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings->verbose) {
|
|
||||||
printf ("SharpenEdge channels %d\n", channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
int passes = params->sharpenEdge.passes;
|
|
||||||
|
|
||||||
if (settings->verbose) {
|
|
||||||
printf ("SharpenEdge passes %d\n", passes);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (p = 0; p < passes; p++)
|
|
||||||
for (c = 0; c <= channels; c++) { // c=0 Luminance only
|
|
||||||
|
|
||||||
#ifdef _OPENMP
|
|
||||||
#pragma omp parallel for private(offset) shared(L)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (offset = 0; offset < width * height; offset++) {
|
|
||||||
int ii = offset / width;
|
|
||||||
int kk = offset - ii * width;
|
|
||||||
|
|
||||||
if (c == 0) {
|
|
||||||
L[offset] = lab->L[ii][kk] / 327.68f; // adjust to RT and to 0..100
|
|
||||||
} else if (c == 1) {
|
|
||||||
L[offset] = lab->a[ii][kk] / 327.68f;
|
|
||||||
} else { /*if (c==2) */
|
|
||||||
L[offset] = lab->b[ii][kk] / 327.68f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _OPENMP
|
|
||||||
#pragma omp parallel for private(j,i,iii,kkk, templab,offset,wH,wV,wD1,wD2,s,lumH,lumV,lumD1,lumD2,v,contrast,f1,f2,f3,f4,difT,difB,difL,difR,difLT,difLB,difRT,difRB) shared(lab,L,amount)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for(j = 2; j < height - 2; j++)
|
|
||||||
for(i = 2, offset = j * width + i; i < width - 2; i++, offset++) {
|
|
||||||
// weight functions
|
|
||||||
wH = eps2 + fabs(L[offset + 1] - L[offset - 1]);
|
|
||||||
wV = eps2 + fabs(L[offset + width] - L[offset - width]);
|
|
||||||
|
|
||||||
s = 1.0f + fabs(wH - wV) / 2.0f;
|
|
||||||
wD1 = eps2 + fabs(L[offset + width + 1] - L[offset - width - 1]) / s;
|
|
||||||
wD2 = eps2 + fabs(L[offset + width - 1] - L[offset - width + 1]) / s;
|
|
||||||
s = wD1;
|
|
||||||
wD1 /= wD2;
|
|
||||||
wD2 /= s;
|
|
||||||
|
|
||||||
// initial values
|
|
||||||
int ii = offset / width;
|
|
||||||
int kk = offset - ii * width;
|
|
||||||
|
|
||||||
if (c == 0) {
|
|
||||||
lumH = lumV = lumD1 = lumD2 = v = lab->L[ii][kk] / 327.68f;
|
|
||||||
} else if (c == 1) {
|
|
||||||
lumH = lumV = lumD1 = lumD2 = v = lab->a[ii][kk] / 327.68f;
|
|
||||||
} else { /* if (c==2) */
|
|
||||||
lumH = lumV = lumD1 = lumD2 = v = lab->b[ii][kk] / 327.68f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// contrast detection
|
|
||||||
contrast = sqrt(fabs(L[offset + 1] - L[offset - 1]) * fabs(L[offset + 1] - L[offset - 1]) + fabs(L[offset + width] - L[offset - width]) * fabs(L[offset + width] - L[offset - width])) / chmax[c];
|
|
||||||
|
|
||||||
if (contrast > 1.0f) {
|
|
||||||
contrast = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// new possible values
|
|
||||||
if (((L[offset] < L[offset - 1]) && (L[offset] > L[offset + 1])) || ((L[offset] > L[offset - 1]) && (L[offset] < L[offset + 1]))) {
|
|
||||||
f1 = fabs(L[offset - 2] - L[offset - 1]);
|
|
||||||
f2 = fabs(L[offset - 1] - L[offset]);
|
|
||||||
f3 = fabs(L[offset - 1] - L[offset - width]) * fabs(L[offset - 1] - L[offset + width]);
|
|
||||||
f4 = sqrt(fabs(L[offset - 1] - L[offset - width2]) * fabs(L[offset - 1] - L[offset + width2]));
|
|
||||||
difL = f1 * f2 * f2 * f3 * f3 * f4;
|
|
||||||
f1 = fabs(L[offset + 2] - L[offset + 1]);
|
|
||||||
f2 = fabs(L[offset + 1] - L[offset]);
|
|
||||||
f3 = fabs(L[offset + 1] - L[offset - width]) * fabs(L[offset + 1] - L[offset + width]);
|
|
||||||
f4 = sqrt(fabs(L[offset + 1] - L[offset - width2]) * fabs(L[offset + 1] - L[offset + width2]));
|
|
||||||
difR = f1 * f2 * f2 * f3 * f3 * f4;
|
|
||||||
|
|
||||||
if ((difR > epsil) && (difL > epsil)) {
|
|
||||||
lumH = (L[offset - 1] * difR + L[offset + 1] * difL) / (difL + difR);
|
|
||||||
lumH = v * (1.f - contrast) + lumH * contrast;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((L[offset] < L[offset - width]) && (L[offset] > L[offset + width])) || ((L[offset] > L[offset - width]) && (L[offset] < L[offset + width]))) {
|
|
||||||
f1 = fabs(L[offset - width2] - L[offset - width]);
|
|
||||||
f2 = fabs(L[offset - width] - L[offset]);
|
|
||||||
f3 = fabs(L[offset - width] - L[offset - 1]) * fabs(L[offset - width] - L[offset + 1]);
|
|
||||||
f4 = sqrt(fabs(L[offset - width] - L[offset - 2]) * fabs(L[offset - width] - L[offset + 2]));
|
|
||||||
difT = f1 * f2 * f2 * f3 * f3 * f4;
|
|
||||||
f1 = fabs(L[offset + width2] - L[offset + width]);
|
|
||||||
f2 = fabs(L[offset + width] - L[offset]);
|
|
||||||
f3 = fabs(L[offset + width] - L[offset - 1]) * fabs(L[offset + width] - L[offset + 1]);
|
|
||||||
f4 = sqrt(fabs(L[offset + width] - L[offset - 2]) * fabs(L[offset + width] - L[offset + 2]));
|
|
||||||
difB = f1 * f2 * f2 * f3 * f3 * f4;
|
|
||||||
|
|
||||||
if ((difB > epsil) && (difT > epsil)) {
|
|
||||||
lumV = (L[offset - width] * difB + L[offset + width] * difT) / (difT + difB);
|
|
||||||
lumV = v * (1.f - contrast) + lumV * contrast;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((L[offset] < L[offset - 1 - width]) && (L[offset] > L[offset + 1 + width])) || ((L[offset] > L[offset - 1 - width]) && (L[offset] < L[offset + 1 + width]))) {
|
|
||||||
f1 = fabs(L[offset - 2 - width2] - L[offset - 1 - width]);
|
|
||||||
f2 = fabs(L[offset - 1 - width] - L[offset]);
|
|
||||||
f3 = fabs(L[offset - 1 - width] - L[offset - width + 1]) * fabs(L[offset - 1 - width] - L[offset + width - 1]);
|
|
||||||
f4 = sqrt(fabs(L[offset - 1 - width] - L[offset - width2 + 2]) * fabs(L[offset - 1 - width] - L[offset + width2 - 2]));
|
|
||||||
difLT = f1 * f2 * f2 * f3 * f3 * f4;
|
|
||||||
f1 = fabs(L[offset + 2 + width2] - L[offset + 1 + width]);
|
|
||||||
f2 = fabs(L[offset + 1 + width] - L[offset]);
|
|
||||||
f3 = fabs(L[offset + 1 + width] - L[offset - width + 1]) * fabs(L[offset + 1 + width] - L[offset + width - 1]);
|
|
||||||
f4 = sqrt(fabs(L[offset + 1 + width] - L[offset - width2 + 2]) * fabs(L[offset + 1 + width] - L[offset + width2 - 2]));
|
|
||||||
difRB = f1 * f2 * f2 * f3 * f3 * f4;
|
|
||||||
|
|
||||||
if ((difLT > epsil) && (difRB > epsil)) {
|
|
||||||
lumD1 = (L[offset - 1 - width] * difRB + L[offset + 1 + width] * difLT) / (difLT + difRB);
|
|
||||||
lumD1 = v * (1.f - contrast) + lumD1 * contrast;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((L[offset] < L[offset + 1 - width]) && (L[offset] > L[offset - 1 + width])) || ((L[offset] > L[offset + 1 - width]) && (L[offset] < L[offset - 1 + width]))) {
|
|
||||||
f1 = fabs(L[offset - 2 + width2] - L[offset - 1 + width]);
|
|
||||||
f2 = fabs(L[offset - 1 + width] - L[offset]);
|
|
||||||
f3 = fabs(L[offset - 1 + width] - L[offset - width - 1]) * fabs(L[offset - 1 + width] - L[offset + width + 1]);
|
|
||||||
f4 = sqrt(fabs(L[offset - 1 + width] - L[offset - width2 - 2]) * fabs(L[offset - 1 + width] - L[offset + width2 + 2]));
|
|
||||||
difLB = f1 * f2 * f2 * f3 * f3 * f4;
|
|
||||||
f1 = fabs(L[offset + 2 - width2] - L[offset + 1 - width]);
|
|
||||||
f2 = fabs(L[offset + 1 - width] - L[offset]) * fabs(L[offset + 1 - width] - L[offset]);
|
|
||||||
f3 = fabs(L[offset + 1 - width] - L[offset + width + 1]) * fabs(L[offset + 1 - width] - L[offset - width - 1]);
|
|
||||||
f4 = sqrt(fabs(L[offset + 1 - width] - L[offset + width2 + 2]) * fabs(L[offset + 1 - width] - L[offset - width2 - 2]));
|
|
||||||
difRT = f1 * f2 * f2 * f3 * f3 * f4;
|
|
||||||
|
|
||||||
if ((difLB > epsil) && (difRT > epsil)) {
|
|
||||||
lumD2 = (L[offset + 1 - width] * difLB + L[offset - 1 + width] * difRT) / (difLB + difRT);
|
|
||||||
lumD2 = v * (1.f - contrast) + lumD2 * contrast;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s = amount;
|
|
||||||
|
|
||||||
// avoid sharpening diagonals too much
|
|
||||||
if (((fabs(wH / wV) < 0.45f) && (fabs(wH / wV) > 0.05f)) || ((fabs(wV / wH) < 0.45f) && (fabs(wV / wH) > 0.05f))) {
|
|
||||||
s = amount / 3.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// final mix
|
|
||||||
if ((wH != 0.0f) && (wV != 0.0f) && (wD1 != 0.0f) && (wD2 != 0.0f)) {
|
|
||||||
iii = offset / width;
|
|
||||||
kkk = offset - iii * width;
|
|
||||||
float provL = lab->L[iii][kkk] / 327.68f;
|
|
||||||
|
|
||||||
if(c == 0) {
|
|
||||||
if(provL < 92.f) {
|
|
||||||
templab = v * (1.f - s) + (lumH * wH + lumV * wV + lumD1 * wD1 + lumD2 * wD2) / (wH + wV + wD1 + wD2) * s;
|
|
||||||
} else {
|
|
||||||
templab = provL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
templab = v * (1.f - s) + (lumH * wH + lumV * wV + lumD1 * wD1 + lumD2 * wD2) / (wH + wV + wD1 + wD2) * s;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == 0) {
|
|
||||||
lab->L[iii][kkk] = fabs(327.68f * templab); // fabs because lab->L always >0
|
|
||||||
} else if (c == 1) {
|
|
||||||
lab->a[iii][kkk] = 327.68f * templab ;
|
|
||||||
} else if (c == 2) {
|
|
||||||
lab->b[iii][kkk] = 327.68f * templab ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete [] L;
|
|
||||||
|
|
||||||
t2e.set();
|
|
||||||
|
|
||||||
if (settings->verbose) {
|
|
||||||
printf("SharpenEdge gradient %d usec\n", t2e.etime(t1e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// To the extent possible under law, Manuel Llorens <manuelllorens@gmail.com>
|
// To the extent possible under law, Manuel Llorens <manuelllorens@gmail.com>
|
||||||
// has waived all copyright and related or neighboring rights to this work.
|
// has waived all copyright and related or neighboring rights to this work.
|
||||||
// This code is licensed under CC0 v1.0, see license information at
|
// This code is licensed under CC0 v1.0, see license information at
|
||||||
@ -640,10 +405,10 @@ BENCHFUN
|
|||||||
// k=2 matrix 5x5 k=1 matrix 3x3
|
// k=2 matrix 5x5 k=1 matrix 3x3
|
||||||
const int width = W, height = H;
|
const int width = W, height = H;
|
||||||
const int unif = params->sharpenMicro.uniformity;
|
const int unif = params->sharpenMicro.uniformity;
|
||||||
const float amount = (k == 1 ? 2.7f : 1.f) * params->sharpenMicro.amount / 1500.0f; //amount 2000.0 quasi no artifacts ==> 1500 = maximum, after artifacts, 25/9 if 3x3
|
const float amount = (k == 1 ? 2.7 : 1.) * params->sharpenMicro.amount / 1500.0; //amount 2000.0 quasi no artifacts ==> 1500 = maximum, after artifacts, 25/9 if 3x3
|
||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
printf ("Micro-contrast amount %f\n", amount);
|
printf ("Micro-contrast amount %f\n", static_cast<double>(amount));
|
||||||
printf ("Micro-contrast uniformity %i\n", unif);
|
printf ("Micro-contrast uniformity %i\n", unif);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -674,7 +439,7 @@ BENCHFUN
|
|||||||
|
|
||||||
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
||||||
JaggedArray<float> blend(W, H);
|
JaggedArray<float> blend(W, H);
|
||||||
float contrast = params->sharpenMicro.contrast / 100.f;
|
float contrast = params->sharpenMicro.contrast / 100.0;
|
||||||
buildBlendMask(luminance, blend, W, H, contrast);
|
buildBlendMask(luminance, blend, W, H, contrast);
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
@ -883,7 +648,7 @@ void ImProcFunctions::sharpeningcam (CieImage* ncie, float** b2, bool showMask)
|
|||||||
|
|
||||||
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
||||||
JaggedArray<float> blend(W, H);
|
JaggedArray<float> blend(W, H);
|
||||||
float contrast = params->sharpening.contrast / 100.f;
|
float contrast = params->sharpening.contrast / 100.0;
|
||||||
buildBlendMask(ncie->sh_p, blend, W, H, contrast);
|
buildBlendMask(ncie->sh_p, blend, W, H, contrast);
|
||||||
if(showMask) {
|
if(showMask) {
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
|
217
rtengine/ipsharpenedges.cc
Normal file
217
rtengine/ipsharpenedges.cc
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RawTherapee.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004-2020 Gabor Horvath <hgabor@rawtherapee.com>
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include "improcfun.h"
|
||||||
|
#include "labimage.h"
|
||||||
|
#include "procparams.h"
|
||||||
|
#include "rt_math.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
#ifdef __SSE2__
|
||||||
|
bool inintervalLoRo(float a, float b, float c)
|
||||||
|
{
|
||||||
|
return a < std::max(b, c) && a > std::min(b, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
float selectweight(float a, float b, float low, float high)
|
||||||
|
{
|
||||||
|
const float minVal = std::min(a,b);
|
||||||
|
const float maxVal = std::max(a,b);
|
||||||
|
const float res = (minVal < 0.45f * maxVal) ? low : high;
|
||||||
|
return (minVal > 0.05f * maxVal) ? res : high;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
bool inintervalLoRo(float a, float b, float c)
|
||||||
|
{
|
||||||
|
return (a < b && a > c) || (a < c && a > b);
|
||||||
|
}
|
||||||
|
|
||||||
|
float selectweight(float a, float b, float low, float high)
|
||||||
|
{
|
||||||
|
if ((a < 0.45f * b && a > 0.05f * b) || (b < 0.45f * a && b > 0.05f * a)) {
|
||||||
|
return low;
|
||||||
|
} else {
|
||||||
|
return high;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
namespace rtengine
|
||||||
|
{
|
||||||
|
|
||||||
|
// To the extent possible under law, Manuel Llorens <manuelllorens@gmail.com>
|
||||||
|
// has waived all copyright and related or neighboring rights to this work.
|
||||||
|
// This work is published from: Spain.
|
||||||
|
|
||||||
|
// Thanks to Manuel for this excellent job (Jacques Desmis JDC or frej83)
|
||||||
|
void ImProcFunctions::MLsharpen (LabImage* lab)
|
||||||
|
{
|
||||||
|
// JD: this algorithm maximize clarity of images; it does not play on accutance. It can remove (partially) the effects of the AA filter)
|
||||||
|
// I think we can use this algorithm alone in most cases, or first to clarify image and if you want a very little USM (unsharp mask sharpening) after...
|
||||||
|
if (!params->sharpenEdge.enabled || params->sharpenEdge.amount == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int width = lab->W, height = lab->H;
|
||||||
|
constexpr float chmax[3] = {1.f / 8.f, 1.f / 3.f, 1.f / 3.f};
|
||||||
|
const int width2 = 2 * width;
|
||||||
|
constexpr float eps2 = 0.001f; //prevent divide by zero
|
||||||
|
const float amount = params->sharpenEdge.amount / 100.0;
|
||||||
|
const float amountby3 = params->sharpenEdge.amount / 300.0;
|
||||||
|
|
||||||
|
std::unique_ptr<float[]> L(new float[width * height]);
|
||||||
|
|
||||||
|
const int channels = params->sharpenEdge.threechannels ? 1 : 3;
|
||||||
|
const int passes = params->sharpenEdge.passes;
|
||||||
|
|
||||||
|
for (int c = 0; c < channels; ++c) { // c=0 Luminance only
|
||||||
|
float** channel = c == 0 ? lab->L : c == 1 ? lab->a : lab->b;
|
||||||
|
for (int p = 0; p < passes; ++p) {
|
||||||
|
#ifdef _OPENMP
|
||||||
|
#pragma omp parallel for
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i = 0; i < height; ++i) {
|
||||||
|
for (int j = 0; j < width; ++j) {
|
||||||
|
L[i * width + j] = channel[i][j] / 327.68f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _OPENMP
|
||||||
|
#pragma omp parallel for schedule(dynamic,16)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int j = 2; j < height - 2; j++) {
|
||||||
|
for (int i = 2, offset = j * width + i; i < width - 2; i++, offset++) {
|
||||||
|
// weight functions
|
||||||
|
const float wH = eps2 + std::fabs(L[offset + 1] - L[offset - 1]);
|
||||||
|
const float wV = eps2 + std::fabs(L[offset + width] - L[offset - width]);
|
||||||
|
|
||||||
|
float s = 2.f / (2.f + std::fabs(wH - wV));
|
||||||
|
float wD1 = eps2 + std::fabs(L[offset + width + 1] - L[offset - width - 1]) * s;
|
||||||
|
float wD2 = eps2 + std::fabs(L[offset + width - 1] - L[offset - width + 1]) * s;
|
||||||
|
s = wD1;
|
||||||
|
wD1 /= wD2;
|
||||||
|
wD2 /= s;
|
||||||
|
|
||||||
|
const float v = L[offset];
|
||||||
|
float lumH, lumV, lumD1, lumD2;
|
||||||
|
lumH = lumV = lumD1 = lumD2 = v;
|
||||||
|
|
||||||
|
// contrast detection
|
||||||
|
const float contrast = std::min(std::sqrt(SQR(L[offset + 1] - L[offset - 1]) + SQR(L[offset + width] - L[offset - width])) * chmax[c], 1.f);
|
||||||
|
|
||||||
|
// new possible values
|
||||||
|
if (inintervalLoRo(v, L[offset - 1], L[offset + 1])) {
|
||||||
|
float f1 = std::fabs(L[offset - 2] - L[offset - 1]);
|
||||||
|
float f2 = L[offset - 1] - v;
|
||||||
|
float f3 = (L[offset - 1] - L[offset - width]) * (L[offset - 1] - L[offset + width]);
|
||||||
|
float f4 = std::sqrt(std::fabs((L[offset - 1] - L[offset - width2]) * (L[offset - 1] - L[offset + width2])));
|
||||||
|
const float difL = f1 * SQR(f2 * f3) * f4;
|
||||||
|
if (difL > 0.f) {
|
||||||
|
f1 = std::fabs(L[offset + 2] - L[offset + 1]);
|
||||||
|
f2 = L[offset + 1] - v;
|
||||||
|
f3 = (L[offset + 1] - L[offset - width]) * (L[offset + 1] - L[offset + width]);
|
||||||
|
f4 = std::sqrt(std::fabs((L[offset + 1] - L[offset - width2]) * (L[offset + 1] - L[offset + width2])));
|
||||||
|
const float difR = f1 * SQR(f2 * f3) * f4;
|
||||||
|
if (difR > 0.f) {
|
||||||
|
lumH = (L[offset - 1] * difR + L[offset + 1] * difL) / (difL + difR);
|
||||||
|
lumH = intp(contrast, lumH, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inintervalLoRo(v, L[offset - width], L[offset + width])) {
|
||||||
|
float f1 = std::fabs(L[offset - width2] - L[offset - width]);
|
||||||
|
float f2 = L[offset - width] - v;
|
||||||
|
float f3 = (L[offset - width] - L[offset - 1]) * (L[offset - width] - L[offset + 1]);
|
||||||
|
float f4 = std::sqrt(std::fabs((L[offset - width] - L[offset - 2]) * (L[offset - width] - L[offset + 2])));
|
||||||
|
const float difT = f1 * SQR(f2 * f3) * f4;
|
||||||
|
if (difT > 0.f) {
|
||||||
|
f1 = std::fabs(L[offset + width2] - L[offset + width]);
|
||||||
|
f2 = L[offset + width] - v;
|
||||||
|
f3 = (L[offset + width] - L[offset - 1]) * (L[offset + width] - L[offset + 1]);
|
||||||
|
f4 = std::sqrt(std::fabs((L[offset + width] - L[offset - 2]) * (L[offset + width] - L[offset + 2])));
|
||||||
|
const float difB = f1 * SQR(f2 * f3) * f4;
|
||||||
|
if (difB > 0.f) {
|
||||||
|
lumV = (L[offset - width] * difB + L[offset + width] * difT) / (difT + difB);
|
||||||
|
lumV = intp(contrast, lumV, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inintervalLoRo(v, L[offset - 1 - width], L[offset + 1 + width])) {
|
||||||
|
float f1 = std::fabs(L[offset - 2 - width2] - L[offset - 1 - width]);
|
||||||
|
float f2 = L[offset - 1 - width] - v;
|
||||||
|
float f3 = (L[offset - 1 - width] - L[offset - width + 1]) * (L[offset - 1 - width] - L[offset + width - 1]);
|
||||||
|
float f4 = std::sqrt(std::fabs((L[offset - 1 - width] - L[offset - width2 + 2]) * (L[offset - 1 - width] - L[offset + width2 - 2])));
|
||||||
|
const float difLT = f1 * SQR(f2 * f3) * f4;
|
||||||
|
if (difLT > 0.f) {
|
||||||
|
f1 = std::fabs(L[offset + 2 + width2] - L[offset + 1 + width]);
|
||||||
|
f2 = L[offset + 1 + width] - v;
|
||||||
|
f3 = (L[offset + 1 + width] - L[offset - width + 1]) * (L[offset + 1 + width] - L[offset + width - 1]);
|
||||||
|
f4 = std::sqrt(std::fabs((L[offset + 1 + width] - L[offset - width2 + 2]) * (L[offset + 1 + width] - L[offset + width2 - 2])));
|
||||||
|
const float difRB = f1 * SQR(f2 * f3) * f4;
|
||||||
|
if (difRB > 0.f) {
|
||||||
|
lumD1 = (L[offset - 1 - width] * difRB + L[offset + 1 + width] * difLT) / (difLT + difRB);
|
||||||
|
lumD1 = intp(contrast, lumD1, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inintervalLoRo(v, L[offset + 1 - width], L[offset - 1 + width])) {
|
||||||
|
float f1 = std::fabs(L[offset - 2 + width2] - L[offset - 1 + width]);
|
||||||
|
float f2 = L[offset - 1 + width] - v;
|
||||||
|
float f3 = (L[offset - 1 + width] - L[offset - width - 1]) * (L[offset - 1 + width] - L[offset + width + 1]);
|
||||||
|
float f4 = std::sqrt(std::fabs((L[offset - 1 + width] - L[offset - width2 - 2]) * (L[offset - 1 + width] - L[offset + width2 + 2])));
|
||||||
|
const float difLB = f1 * SQR(f2 * f3) * f4;
|
||||||
|
if (difLB > 0.f) {
|
||||||
|
f1 = std::fabs(L[offset + 2 - width2] - L[offset + 1 - width]);
|
||||||
|
f2 = L[offset + 1 - width] - v;
|
||||||
|
f3 = (L[offset + 1 - width] - L[offset + width + 1]) * (L[offset + 1 - width] - L[offset - width - 1]);
|
||||||
|
f4 = std::sqrt(std::fabs((L[offset + 1 - width] - L[offset + width2 + 2]) * (L[offset + 1 - width] - L[offset - width2 - 2])));
|
||||||
|
const float difRT = f1 * SQR(f2 * f3) * f4;
|
||||||
|
if (difRT > 0.f) {
|
||||||
|
lumD2 = (L[offset + 1 - width] * difLB + L[offset - 1 + width] * difRT) / (difLB + difRT);
|
||||||
|
lumD2 = intp(contrast, lumD2, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// final mix
|
||||||
|
// avoid sharpening diagonals too much
|
||||||
|
const float weight = selectweight(wH, wV, amountby3, amount);
|
||||||
|
|
||||||
|
if (c == 0) {
|
||||||
|
if (v < 92.f) {
|
||||||
|
channel[j][i] = std::fabs(327.68f * intp(weight, (lumH * wH + lumV * wV + lumD1 * wD1 + lumD2 * wD2) / (wH + wV + wD1 + wD2), v)); // fabs because lab->L always > 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel[j][i] = 327.68f * intp(weight, (lumH * wH + lumV * wV + lumD1 * wD1 + lumD2 * wD2) / (wH + wV + wD1 + wD2), v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -689,11 +689,11 @@ static void calcGradientParams (int oW, int oH, const GradientParams& gradient,
|
|||||||
gp.ta = tan (gradient_angle);
|
gp.ta = tan (gradient_angle);
|
||||||
gp.xc = w * gradient_center_x;
|
gp.xc = w * gradient_center_x;
|
||||||
gp.yc = h * gradient_center_y;
|
gp.yc = h * gradient_center_y;
|
||||||
gp.ys = sqrt ((float)h * h + (float)w * w) * (gradient_span / cos (gradient_angle));
|
gp.ys = rtengine::norm2(static_cast<double>(h), static_cast<double>(w)) * (gradient_span / cos(gradient_angle));
|
||||||
gp.ys_inv = 1.0 / gp.ys;
|
gp.ys_inv = 1.f / gp.ys;
|
||||||
gp.top_edge_0 = gp.yc - gp.ys / 2.0;
|
gp.top_edge_0 = gp.yc - gp.ys / 2.f;
|
||||||
|
|
||||||
if (gp.ys < 1.0 / h) {
|
if (h * gp.ys < 1.f) {
|
||||||
gp.ys_inv = 0;
|
gp.ys_inv = 0;
|
||||||
gp.ys = 0;
|
gp.ys = 0;
|
||||||
}
|
}
|
||||||
@ -723,7 +723,7 @@ static float calcGradientFactor (const struct grad_params& gp, int x, int y)
|
|||||||
val = 1.f - pow3 (xcosf (val));
|
val = 1.f - pow3 (xcosf (val));
|
||||||
}
|
}
|
||||||
|
|
||||||
return gp.scale + val * (1.0 - gp.scale);
|
return gp.scale + val * (1.f - gp.scale);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int gy = gp.transpose ? x : y;
|
int gy = gp.transpose ? x : y;
|
||||||
@ -747,7 +747,7 @@ static float calcGradientFactor (const struct grad_params& gp, int x, int y)
|
|||||||
val = 1.f - pow3 (xcosf (val));
|
val = 1.f - pow3 (xcosf (val));
|
||||||
}
|
}
|
||||||
|
|
||||||
return gp.scale + val * (1.0 - gp.scale);
|
return gp.scale + val * (1.f - gp.scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -766,7 +766,7 @@ static void calcPCVignetteParams (int fW, int fH, int oW, int oH, const PCVignet
|
|||||||
{
|
{
|
||||||
|
|
||||||
// ellipse formula: (x/a)^2 + (y/b)^2 = 1
|
// ellipse formula: (x/a)^2 + (y/b)^2 = 1
|
||||||
double roundness = pcvignette.roundness / 100.0;
|
float roundness = pcvignette.roundness / 100.f;
|
||||||
pcv.feather = pcvignette.feather / 100.0;
|
pcv.feather = pcvignette.feather / 100.0;
|
||||||
|
|
||||||
if (crop.enabled) {
|
if (crop.enabled) {
|
||||||
@ -783,42 +783,40 @@ static void calcPCVignetteParams (int fW, int fH, int oW, int oH, const PCVignet
|
|||||||
pcv.h = oH;
|
pcv.h = oH;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcv.fadeout_mul = 1.0 / (0.05 * sqrtf (oW * oW + oH * oH));
|
pcv.fadeout_mul = 20.0 / rtengine::norm2(static_cast<double>(oW), static_cast<double>(oW));
|
||||||
float short_side = (pcv.w < pcv.h) ? pcv.w : pcv.h;
|
float short_side = (pcv.w < pcv.h) ? pcv.w : pcv.h;
|
||||||
float long_side = (pcv.w > pcv.h) ? pcv.w : pcv.h;
|
float long_side = (pcv.w > pcv.h) ? pcv.w : pcv.h;
|
||||||
|
|
||||||
pcv.sep = 2;
|
pcv.sep = 2;
|
||||||
pcv.sepmix = 0;
|
pcv.sepmix = 0;
|
||||||
pcv.oe_a = sqrt (2.0) * long_side * 0.5;
|
pcv.oe_a = std::sqrt(2.f) * long_side * 0.5f;
|
||||||
pcv.oe_b = pcv.oe_a * short_side / long_side;
|
pcv.oe_b = pcv.oe_a * short_side / long_side;
|
||||||
pcv.ie_mul = (1.0 / sqrt (2.0)) * (1.0 - pcv.feather);
|
pcv.ie_mul = (1.f - pcv.feather) / std::sqrt(2.f);
|
||||||
pcv.is_super_ellipse_mode = false;
|
pcv.is_super_ellipse_mode = false;
|
||||||
pcv.is_portrait = (pcv.w < pcv.h);
|
pcv.is_portrait = (pcv.w < pcv.h);
|
||||||
|
|
||||||
if (roundness < 0.5) {
|
if (roundness < 0.5f) {
|
||||||
// make super-ellipse of higher and higher degree
|
// make super-ellipse of higher and higher degree
|
||||||
pcv.is_super_ellipse_mode = true;
|
pcv.is_super_ellipse_mode = true;
|
||||||
float sepf = 2 + 4 * powf (1.0 - 2 * roundness, 1.3); // gamma 1.3 used to balance the effect in the 0.0...0.5 roundness range
|
float sepf = 2 + 4 * std::pow(1.f - 2 * roundness, 1.3f); // gamma 1.3 used to balance the effect in the 0.0...0.5 roundness range
|
||||||
pcv.sep = ((int)sepf) & ~0x1;
|
pcv.sep = ((int)sepf) & ~0x1;
|
||||||
pcv.sepmix = (sepf - pcv.sep) * 0.5; // 0.0 to 1.0
|
pcv.sepmix = (sepf - pcv.sep) * 0.5f; // 0.0 to 1.0
|
||||||
pcv.oe1_a = powf (2.0, 1.0 / pcv.sep) * long_side * 0.5;
|
pcv.oe1_a = std::pow(2.f, 1.f / pcv.sep) * long_side * 0.5f;
|
||||||
pcv.oe1_b = pcv.oe1_a * short_side / long_side;
|
pcv.oe1_b = pcv.oe1_a * short_side / long_side;
|
||||||
pcv.ie1_mul = (1.0 / powf (2.0, 1.0 / pcv.sep)) * (1.0 - pcv.feather);
|
pcv.ie1_mul = (1.f - pcv.feather) / std::pow(2.f, 1.f / pcv.sep);
|
||||||
pcv.oe2_a = powf (2.0, 1.0 / (pcv.sep + 2)) * long_side * 0.5;
|
pcv.oe2_a = std::pow(2.f, 1.f / (pcv.sep + 2)) * long_side * 0.5f;
|
||||||
pcv.oe2_b = pcv.oe2_a * short_side / long_side;
|
pcv.oe2_b = pcv.oe2_a * short_side / long_side;
|
||||||
pcv.ie2_mul = (1.0 / powf (2.0, 1.0 / (pcv.sep + 2))) * (1.0 - pcv.feather);
|
pcv.ie2_mul = (1.f - pcv.feather) / std::pow(2.f, 1.f / (pcv.sep + 2));
|
||||||
}
|
} else if (roundness > 0.5f) {
|
||||||
|
|
||||||
if (roundness > 0.5) {
|
|
||||||
// scale from fitted ellipse towards circle
|
// scale from fitted ellipse towards circle
|
||||||
float rad = sqrtf (pcv.w * pcv.w + pcv.h * pcv.h) / 2.0;
|
float rad = rtengine::norm2(static_cast<float>(pcv.w), static_cast<float>(pcv.h)) / 2.f;
|
||||||
float diff_a = rad - pcv.oe_a;
|
float diff_a = rad - pcv.oe_a;
|
||||||
float diff_b = rad - pcv.oe_b;
|
float diff_b = rad - pcv.oe_b;
|
||||||
pcv.oe_a = pcv.oe_a + diff_a * 2 * (roundness - 0.5);
|
pcv.oe_a = pcv.oe_a + diff_a * 2 * (roundness - 0.5f);
|
||||||
pcv.oe_b = pcv.oe_b + diff_b * 2 * (roundness - 0.5);
|
pcv.oe_b = pcv.oe_b + diff_b * 2 * (roundness - 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
pcv.scale = powf (2, -pcvignette.strength);
|
pcv.scale = std::pow(2, -pcvignette.strength);
|
||||||
|
|
||||||
if (pcvignette.strength >= 6.0) {
|
if (pcvignette.strength >= 6.0) {
|
||||||
pcv.scale = 0.0;
|
pcv.scale = 0.0;
|
||||||
@ -954,23 +952,23 @@ void ImProcFunctions::transformLuminanceOnly (Imagefloat* original, Imagefloat*
|
|||||||
double r = sqrt (vig_x_d * vig_x_d + vig_y_d * vig_y_d);
|
double r = sqrt (vig_x_d * vig_x_d + vig_y_d * vig_y_d);
|
||||||
|
|
||||||
if (darkening) {
|
if (darkening) {
|
||||||
factor /= std::max (v + mul * tanh (b * (maxRadius - r) / maxRadius), 0.001);
|
factor /= std::max (v + mul * tanh(b * (maxRadius - r) / maxRadius), 0.001);
|
||||||
} else {
|
} else {
|
||||||
factor = v + mul * tanh (b * (maxRadius - r) / maxRadius);
|
factor = v + mul * tanh(b * (maxRadius - r) / maxRadius);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applyGradient) {
|
if (applyGradient) {
|
||||||
factor *= calcGradientFactor (gp, cx + x, cy + y);
|
factor *= static_cast<double>(calcGradientFactor(gp, cx + x, cy + y));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applyPCVignetting) {
|
if (applyPCVignetting) {
|
||||||
factor *= calcPCVignetteFactor (pcv, cx + x, cy + y);
|
factor *= static_cast<double>(calcPCVignetteFactor(pcv, cx + x, cy + y));
|
||||||
}
|
}
|
||||||
|
|
||||||
transformed->r (y, x) = original->r (y, x) * factor;
|
transformed->r(y, x) = static_cast<double>(original->r(y, x)) * factor;
|
||||||
transformed->g (y, x) = original->g (y, x) * factor;
|
transformed->g(y, x) = static_cast<double>(original->g(y, x)) * factor;
|
||||||
transformed->b (y, x) = original->b (y, x) * factor;
|
transformed->b(y, x) = static_cast<double>(original->b(y, x)) * factor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1147,11 +1145,11 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (enableGradient) {
|
if (enableGradient) {
|
||||||
vignmul *= calcGradientFactor(gp, cx + x, cy + y);
|
vignmul *= static_cast<double>(calcGradientFactor(gp, cx + x, cy + y));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enablePCVignetting) {
|
if (enablePCVignetting) {
|
||||||
vignmul *= calcPCVignetteFactor(pcv, cx + x, cy + y);
|
vignmul *= static_cast<double>(calcPCVignetteFactor(pcv, cx + x, cy + y));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) {
|
if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) {
|
||||||
|
@ -48,7 +48,7 @@ void fillCurveArrayVib (DiagonalCurve* diagCurve, LUTf &outCurve)
|
|||||||
// change to [0,1] range
|
// change to [0,1] range
|
||||||
// apply custom/parametric/NURBS curve, if any
|
// apply custom/parametric/NURBS curve, if any
|
||||||
// and store result in a temporary array
|
// and store result in a temporary array
|
||||||
outCurve[i] = 65535.f * diagCurve->getVal ( double (i) / 65535.0 );
|
outCurve[i] = 65535.0 * diagCurve->getVal(i / 65535.0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
outCurve.makeIdentity();
|
outCurve.makeIdentity();
|
||||||
@ -606,7 +606,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
bool inGamut;
|
bool inGamut;
|
||||||
|
|
||||||
const float fyy = Color::c1By116 * Lprov + Color::c16By116;
|
const float fyy = Color::c1By116 * Lprov + Color::c16By116;
|
||||||
const float yy_ = (Lprov > Color::epskap) ? fyy * fyy*fyy : Lprov / Color::kappaf;
|
const float yy_ = (Lprov > static_cast<float>(Color::epskap)) ? fyy * fyy*fyy : Lprov / Color::kappaf;
|
||||||
float ChprovOld = std::numeric_limits<float>::min();
|
float ChprovOld = std::numeric_limits<float>::min();
|
||||||
do {
|
do {
|
||||||
inGamut = true;
|
inGamut = true;
|
||||||
|
@ -50,13 +50,6 @@
|
|||||||
|
|
||||||
#include "cplx_wavelet_dec.h"
|
#include "cplx_wavelet_dec.h"
|
||||||
|
|
||||||
#define TS 64 // Tile size
|
|
||||||
#define offset 25 // shift between tiles
|
|
||||||
#define fTS ((TS/2+1)) // second dimension of Fourier tiles
|
|
||||||
#define blkrad 1 // radius of block averaging
|
|
||||||
|
|
||||||
#define epsilon 0.001f/(TS*TS) //tolerance
|
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -904,10 +897,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
|
|||||||
//init for edge and denoise
|
//init for edge and denoise
|
||||||
float vari[4];
|
float vari[4];
|
||||||
|
|
||||||
vari[0] = 8.f * SQR((cp.lev0n / 125.0) * (1.0 + cp.lev0n / 25.0));
|
vari[0] = 8.f * SQR((cp.lev0n / 125.f) * (1.f + cp.lev0n / 25.f));
|
||||||
vari[1] = 8.f * SQR((cp.lev1n / 125.0) * (1.0 + cp.lev1n / 25.0));
|
vari[1] = 8.f * SQR((cp.lev1n / 125.f) * (1.f + cp.lev1n / 25.f));
|
||||||
vari[2] = 8.f * SQR((cp.lev2n / 125.0) * (1.0 + cp.lev2n / 25.0));
|
vari[2] = 8.f * SQR((cp.lev2n / 125.f) * (1.f + cp.lev2n / 25.f));
|
||||||
vari[3] = 8.f * SQR((cp.lev3n / 125.0) * (1.0 + cp.lev3n / 25.0));
|
vari[3] = 8.f * SQR((cp.lev3n / 125.f) * (1.f + cp.lev3n / 25.f));
|
||||||
|
|
||||||
if((cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f || cp.lev3n > 0.1f) && cp.noiseena) {
|
if((cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f || cp.lev3n > 0.1f) && cp.noiseena) {
|
||||||
int edge = 1;
|
int edge = 1;
|
||||||
@ -1123,7 +1116,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
|
|||||||
float Chprov1 = sqrtf(SQR(a) + SQR(b));
|
float Chprov1 = sqrtf(SQR(a) + SQR(b));
|
||||||
yBuffer[col] = (Chprov1 == 0.f) ? 1.f : a / Chprov1;
|
yBuffer[col] = (Chprov1 == 0.f) ? 1.f : a / Chprov1;
|
||||||
xBuffer[col] = (Chprov1 == 0.f) ? 0.f : b / Chprov1;
|
xBuffer[col] = (Chprov1 == 0.f) ? 0.f : b / Chprov1;
|
||||||
chprovBuffer[col] = Chprov1 / 327.68;
|
chprovBuffer[col] = Chprov1 / 327.68f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1287,7 +1280,7 @@ void ImProcFunctions::Aver( float * RESTRICT DataList, int datalen, float &aver
|
|||||||
|
|
||||||
for(int i = 0; i < datalen; i++) {
|
for(int i = 0; i < datalen; i++) {
|
||||||
if(DataList[i] >= thres) {
|
if(DataList[i] >= thres) {
|
||||||
averaP += DataList[i];
|
averaP += static_cast<double>(DataList[i]);
|
||||||
|
|
||||||
if(DataList[i] > lmax) {
|
if(DataList[i] > lmax) {
|
||||||
lmax = DataList[i];
|
lmax = DataList[i];
|
||||||
@ -1295,7 +1288,7 @@ void ImProcFunctions::Aver( float * RESTRICT DataList, int datalen, float &aver
|
|||||||
|
|
||||||
countP++;
|
countP++;
|
||||||
} else if(DataList[i] < -thres) {
|
} else if(DataList[i] < -thres) {
|
||||||
averaN += DataList[i];
|
averaN += static_cast<double>(DataList[i]);
|
||||||
|
|
||||||
if(DataList[i] < lmin) {
|
if(DataList[i] < lmin) {
|
||||||
lmin = DataList[i];
|
lmin = DataList[i];
|
||||||
@ -1341,10 +1334,10 @@ void ImProcFunctions::Sigma( float * RESTRICT DataList, int datalen, float aver
|
|||||||
|
|
||||||
for(int i = 0; i < datalen; i++) {
|
for(int i = 0; i < datalen; i++) {
|
||||||
if(DataList[i] >= thres) {
|
if(DataList[i] >= thres) {
|
||||||
variP += SQR(DataList[i] - averagePlus);
|
variP += static_cast<double>(SQR(DataList[i] - averagePlus));
|
||||||
countP++;
|
countP++;
|
||||||
} else if(DataList[i] <= -thres) {
|
} else if(DataList[i] <= -thres) {
|
||||||
variN += SQR(DataList[i] - averageNeg);
|
variN += static_cast<double>(SQR(DataList[i] - averageNeg));
|
||||||
countN++;
|
countN++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1620,7 +1613,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < W_L * H_L; i++) {
|
for (int i = 0; i < W_L * H_L; i++) {
|
||||||
avedbl += WavCoeffs_L0[i];
|
avedbl += static_cast<double>(WavCoeffs_L0[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
@ -1709,7 +1702,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
|
|||||||
#pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1)
|
#pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if(contrast != 0.f && cp.resena && max0 > 0.0) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step
|
if(contrast != 0.f && cp.resena && max0 > 0.f) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step
|
||||||
{
|
{
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp for
|
#pragma omp for
|
||||||
@ -2018,7 +2011,7 @@ void ImProcFunctions::WaveletAandBAllAB(wavelet_decomposition &WaveletCoeffs_a,
|
|||||||
editWhatever->v(i,j) = valpar;
|
editWhatever->v(i,j) = valpar;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
float valparam = float((hhCurve->getVal(Color::huelab_to_huehsv2(hueR)) - 0.5f) * 1.7f) + hueR; //get H=f(H) 1.7 optimisation !
|
float valparam = (static_cast<float>(hhCurve->getVal(Color::huelab_to_huehsv2(hueR))) - 0.5f) * 1.7f + hueR; //get H=f(H) 1.7 optimisation !
|
||||||
float2 sincosval = xsincosf(valparam);
|
float2 sincosval = xsincosf(valparam);
|
||||||
WavCoeffs_a0[i * W_L + j] = chR * sincosval.y;
|
WavCoeffs_a0[i * W_L + j] = chR * sincosval.y;
|
||||||
WavCoeffs_b0[i * W_L + j] = chR * sincosval.x;
|
WavCoeffs_b0[i * W_L + j] = chR * sincosval.x;
|
||||||
@ -3023,9 +3016,8 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit
|
|||||||
if(Chutili) {
|
if(Chutili) {
|
||||||
int i_i = i / W_L;
|
int i_i = i / W_L;
|
||||||
int j_j = i - i_i * W_L;
|
int j_j = i - i_i * W_L;
|
||||||
double lr;
|
|
||||||
float modhue2 = varhue[i_i][j_j];
|
float modhue2 = varhue[i_i][j_j];
|
||||||
float valparam = float((ChCurve->getVal(lr = Color::huelab_to_huehsv2(modhue2)) - 0.5f)); //get valparam=f(H)
|
float valparam = static_cast<float>(ChCurve->getVal(Color::huelab_to_huehsv2(modhue2))) - 0.5f; //get valparam=f(H)
|
||||||
|
|
||||||
if(valparam > 0.f) {
|
if(valparam > 0.f) {
|
||||||
scale2 = 1.f + 3.f * valparam; //arbitrary value
|
scale2 = 1.f + 3.f * valparam; //arbitrary value
|
||||||
|
@ -25,11 +25,6 @@
|
|||||||
|
|
||||||
#define JFREAD(file,buf,sizeofbuf) \
|
#define JFREAD(file,buf,sizeofbuf) \
|
||||||
((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
|
((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
|
||||||
#define JFWRITE(file,buf,sizeofbuf) \
|
|
||||||
((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Expanded data source object for stdio input */
|
/* Expanded data source object for stdio input */
|
||||||
namespace
|
namespace
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include <cstdio> /* fflush() */
|
#include <cstdio> /* fflush() */
|
||||||
#include <cstring> /* memset() */
|
#include <cstring> /* memset() */
|
||||||
#include <cmath> /* fsqrt() */
|
#include <cmath> /* fsqrt() */
|
||||||
#define fsqrt(X) sqrt(X)
|
|
||||||
|
|
||||||
/* Our includes */
|
/* Our includes */
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
class LabImage
|
class LabImage final
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
void allocLab(size_t w, size_t h);
|
void allocLab(size_t w, size_t h);
|
||||||
|
130
rtengine/lcp.cc
130
rtengine/lcp.cc
@ -42,7 +42,6 @@ class rtengine::LCPProfile::LCPPersModel
|
|||||||
public:
|
public:
|
||||||
LCPPersModel();
|
LCPPersModel();
|
||||||
bool hasModeData(LCPCorrectionMode mode) const;
|
bool hasModeData(LCPCorrectionMode mode) const;
|
||||||
void print() const;
|
|
||||||
|
|
||||||
float focLen;
|
float focLen;
|
||||||
float focDist;
|
float focDist;
|
||||||
@ -82,27 +81,18 @@ bool rtengine::LCPModelCommon::empty() const
|
|||||||
&& param[2] == 0.0f;
|
&& param[2] == 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtengine::LCPModelCommon::print() const
|
|
||||||
{
|
|
||||||
std::printf("focLen %g/%g; imgCenter %g/%g; scale %g; err %g\n", foc_len_x, foc_len_y, img_center_x, img_center_y, scale_factor, mean_error);
|
|
||||||
std::printf("xy0 %g/%g fxy %g/%g\n", x0, y0, fx, fy);
|
|
||||||
std::printf("param: %g/%g/%g/%g/%g\n", param[0], param[1], param[2], param[3], param[4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// weighted merge two parameters
|
// weighted merge two parameters
|
||||||
void rtengine::LCPModelCommon::merge(const LCPModelCommon& a, const LCPModelCommon& b, float facA)
|
void rtengine::LCPModelCommon::merge(const LCPModelCommon& a, const LCPModelCommon& b, float facA)
|
||||||
{
|
{
|
||||||
const float facB = 1.0f - facA;
|
foc_len_x = rtengine::intp<float>(facA, a.foc_len_x, b.foc_len_x);
|
||||||
|
foc_len_y = rtengine::intp<float>(facA, a.foc_len_y, b.foc_len_y);
|
||||||
foc_len_x = facA * a.foc_len_x + facB * b.foc_len_x;
|
img_center_x = rtengine::intp<float>(facA, a.img_center_x, b.img_center_x);
|
||||||
foc_len_y = facA * a.foc_len_y + facB * b.foc_len_y;
|
img_center_y = rtengine::intp<float>(facA, a.img_center_y, b.img_center_y);
|
||||||
img_center_x = facA * a.img_center_x + facB * b.img_center_x;
|
scale_factor = rtengine::intp<float>(facA, a.scale_factor, b.scale_factor);
|
||||||
img_center_y = facA * a.img_center_y + facB * b.img_center_y;
|
mean_error = rtengine::intp<float>(facA, a.mean_error, b.mean_error);
|
||||||
scale_factor = facA * a.scale_factor + facB * b.scale_factor;
|
|
||||||
mean_error = facA * a.mean_error + facB * b.mean_error;
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
param[i] = facA * a.param[i] + facB * b.param[i];
|
param[i] = rtengine::intp<float>(facA, a.param[i], b.param[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float param0Sqr = param[0] * param[0];
|
const float param0Sqr = param[0] * param[0];
|
||||||
@ -152,7 +142,6 @@ void rtengine::LCPModelCommon::prepareParams(
|
|||||||
rfx = 1.0f / fx;
|
rfx = 1.0f / fx;
|
||||||
rfy = 1.0f / fy;
|
rfy = 1.0f / fy;
|
||||||
|
|
||||||
//std::printf("FW %i /X0 %g FH %i /Y0 %g %g\n",fullWidth,x0,fullHeight,y0, imgYCenter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rtengine::LCPProfile::LCPPersModel::LCPPersModel() :
|
rtengine::LCPProfile::LCPPersModel::LCPPersModel() :
|
||||||
@ -188,35 +177,6 @@ bool rtengine::LCPProfile::LCPPersModel::hasModeData(LCPCorrectionMode mode) con
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtengine::LCPProfile::LCPPersModel::print() const
|
|
||||||
{
|
|
||||||
std::printf("--- PersModel focLen %g; focDist %g; aperture %g\n", focLen, focDist, aperture);
|
|
||||||
std::printf("Base:\n");
|
|
||||||
base.print();
|
|
||||||
|
|
||||||
if (!chromRG.empty()) {
|
|
||||||
std::printf("ChromRG:\n");
|
|
||||||
chromRG.print();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!chromG.empty()) {
|
|
||||||
std::printf("ChromG:\n");
|
|
||||||
chromG.print();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!chromBG.empty()) {
|
|
||||||
std::printf("ChromBG:\n");
|
|
||||||
chromBG.print();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vignette.empty()) {
|
|
||||||
std::printf("Vignette:\n");
|
|
||||||
vignette.print();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
rtengine::LCPProfile::LCPProfile(const Glib::ustring& fname) :
|
rtengine::LCPProfile::LCPProfile(const Glib::ustring& fname) :
|
||||||
isFisheye(false),
|
isFisheye(false),
|
||||||
sensorFormatFactor(1.f),
|
sensorFormatFactor(1.f),
|
||||||
@ -522,7 +482,7 @@ void rtengine::LCPProfile::calcParams(
|
|||||||
) {
|
) {
|
||||||
// Mix in aperture
|
// Mix in aperture
|
||||||
const float facAperLow = (pHigh->aperture - aperture) / (pHigh->aperture - pLow->aperture);
|
const float facAperLow = (pHigh->aperture - aperture) / (pHigh->aperture - pLow->aperture);
|
||||||
facLow = focLenOnSpot ? facAperLow : (0.5 * facLow + 0.5 * facAperLow);
|
facLow = focLenOnSpot ? facAperLow : (0.5f * (facLow + facAperLow));
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mode != LCPCorrectionMode::VIGNETTE
|
mode != LCPCorrectionMode::VIGNETTE
|
||||||
@ -532,7 +492,7 @@ void rtengine::LCPProfile::calcParams(
|
|||||||
) {
|
) {
|
||||||
// focus distance for all else (if focus distance is given)
|
// focus distance for all else (if focus distance is given)
|
||||||
const float facDistLow = (std::log(pHigh->focDist) + euler - focusDistLog) / (std::log(pHigh->focDist) - std::log(pLow->focDist));
|
const float facDistLow = (std::log(pHigh->focDist) + euler - focusDistLog) / (std::log(pHigh->focDist) - std::log(pLow->focDist));
|
||||||
facLow = focLenOnSpot ? facDistLow : (0.8 * facLow + 0.2 * facDistLow);
|
facLow = focLenOnSpot ? facDistLow : (0.8f * facLow + 0.2f * facDistLow);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
@ -555,7 +515,16 @@ void rtengine::LCPProfile::calcParams(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
std::printf("LCP mode=%i, dist: %g found frames: Fno %g-%g; FocLen %g-%g; Dist %g-%g with weight %g\n", toUnderlying(mode), focusDist, pLow->aperture, pHigh->aperture, pLow->focLen, pHigh->focLen, pLow->focDist, pHigh->focDist, facLow);
|
std::printf("LCP mode=%i, dist: %g found frames: Fno %g-%g; FocLen %g-%g; Dist %g-%g with weight %g\n",
|
||||||
|
toUnderlying(mode),
|
||||||
|
static_cast<double>(focusDist),
|
||||||
|
static_cast<double>(pLow->aperture),
|
||||||
|
static_cast<double>(pHigh->aperture),
|
||||||
|
static_cast<double>(pLow->focLen),
|
||||||
|
static_cast<double>(pHigh->focLen),
|
||||||
|
static_cast<double>(pLow->focDist),
|
||||||
|
static_cast<double>(pHigh->focDist),
|
||||||
|
static_cast<double>(facLow));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
@ -564,15 +533,6 @@ void rtengine::LCPProfile::calcParams(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtengine::LCPProfile::print() const
|
|
||||||
{
|
|
||||||
std::printf("=== Profile %s\n", profileName.c_str());
|
|
||||||
std::printf("Frames: %i, RAW: %i; Fisheye: %i; Sensorformat: %f\n", persModelCount, isRaw, isFisheye, sensorFormatFactor);
|
|
||||||
|
|
||||||
for (int pm = 0; pm < persModelCount; ++pm) {
|
|
||||||
aPersModel[pm]->print();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// from all frames not marked as bad already, take average and filter out frames with higher deviation than this if there are enough values
|
// from all frames not marked as bad already, take average and filter out frames with higher deviation than this if there are enough values
|
||||||
int rtengine::LCPProfile::filterBadFrames(LCPCorrectionMode mode, double maxAvgDevFac, int minFramesLeft)
|
int rtengine::LCPProfile::filterBadFrames(LCPCorrectionMode mode, double maxAvgDevFac, int minFramesLeft)
|
||||||
@ -649,7 +609,7 @@ int rtengine::LCPProfile::filterBadFrames(LCPCorrectionMode mode, double maxAvgD
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (settings->verbose && count) {
|
if (settings->verbose && count) {
|
||||||
std::printf("Filtered %.1f%% frames for maxAvgDevFac %g leaving %i\n", filtered * 100.f / count, maxAvgDevFac, count - filtered);
|
std::printf("Filtered %.1f%% frames for maxAvgDevFac %g leaving %i\n", filtered * 100.0 / count, maxAvgDevFac, count - filtered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1007,7 +967,7 @@ rtengine::LCPMapper::LCPMapper(
|
|||||||
const bool mirrorX = (rot == 90 || rot == 180);
|
const bool mirrorX = (rot == 90 || rot == 180);
|
||||||
const bool mirrorY = (rot == 180 || rot == 270);
|
const bool mirrorY = (rot == 180 || rot == 270);
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
std::printf("Vign: %i, fullWidth: %i/%i, focLen %g SwapXY: %i / MirX/Y %i / %i on rot:%i from %i\n",vignette, fullWidth, fullHeight, focalLength, swapXY, mirrorX, mirrorY, rot, rawRotationDeg);
|
std::printf("Vign: %i, fullWidth: %i/%i, focLen %g SwapXY: %i / MirX/Y %i / %i on rot:%i from %i\n",vignette, fullWidth, fullHeight, static_cast<double>(focalLength), swapXY, mirrorX, mirrorY, rot, rawRotationDeg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pProf->calcParams(vignette ? LCPCorrectionMode::VIGNETTE : LCPCorrectionMode::DISTORTION, focalLength, focusDist, aperture, &mc, nullptr, nullptr);
|
pProf->calcParams(vignette ? LCPCorrectionMode::VIGNETTE : LCPCorrectionMode::DISTORTION, focalLength, focusDist, aperture, &mc, nullptr, nullptr);
|
||||||
@ -1038,8 +998,8 @@ void rtengine::LCPMapper::correctDistortion(double &x, double &y, int cx, int cy
|
|||||||
if (isFisheye) {
|
if (isFisheye) {
|
||||||
const double u = x * scale;
|
const double u = x * scale;
|
||||||
const double v = y * scale;
|
const double v = y * scale;
|
||||||
const double u0 = mc.x0 * scale;
|
const double u0 = static_cast<double>(mc.x0) * scale;
|
||||||
const double v0 = mc.y0 * scale;
|
const double v0 = static_cast<double>(mc.y0) * scale;
|
||||||
const double du = (u - u0);
|
const double du = (u - u0);
|
||||||
const double dv = (v - v0);
|
const double dv = (v - v0);
|
||||||
const double fx = mc.fx;
|
const double fx = mc.fx;
|
||||||
@ -1059,22 +1019,22 @@ void rtengine::LCPMapper::correctDistortion(double &x, double &y, int cx, int cy
|
|||||||
} else {
|
} else {
|
||||||
x *= scale;
|
x *= scale;
|
||||||
y *= scale;
|
y *= scale;
|
||||||
const double x0 = mc.x0 * scale;
|
const double x0 = static_cast<double>(mc.x0) * scale;
|
||||||
const double y0 = mc.y0 * scale;
|
const double y0 = static_cast<double>(mc.y0) * scale;
|
||||||
const double xd = (x - x0) / mc.fx, yd = (y - y0) / mc.fy;
|
const double xd = (x - x0) / static_cast<double>(mc.fx), yd = (y - y0) / static_cast<double>(mc.fy);
|
||||||
|
|
||||||
const LCPModelCommon::Param aDist = mc.param;
|
const auto& aDist = mc.param;
|
||||||
const double rsqr = xd * xd + yd * yd;
|
const double rsqr = xd * xd + yd * yd;
|
||||||
const double xfac = aDist[swapXY ? 3 : 4], yfac = aDist[swapXY ? 4 : 3];
|
const double xfac = static_cast<double>(aDist[swapXY ? 3 : 4]), yfac = static_cast<double>(aDist[swapXY ? 4 : 3]);
|
||||||
|
|
||||||
const double commonFac = (((aDist[2] * rsqr + aDist[1]) * rsqr + aDist[0]) * rsqr + 1.)
|
const double commonFac = (((static_cast<double>(aDist[2]) * rsqr + static_cast<double>(aDist[1])) * rsqr + static_cast<double>(aDist[0])) * rsqr + 1.)
|
||||||
+ 2. * (yfac * yd + xfac * xd);
|
+ 2. * (yfac * yd + xfac * xd);
|
||||||
|
|
||||||
const double xnew = xd * commonFac + xfac * rsqr;
|
const double xnew = xd * commonFac + xfac * rsqr;
|
||||||
const double ynew = yd * commonFac + yfac * rsqr;
|
const double ynew = yd * commonFac + yfac * rsqr;
|
||||||
|
|
||||||
x = xnew * mc.fx + x0;
|
x = xnew * static_cast<double>(mc.fx) + x0;
|
||||||
y = ynew * mc.fy + y0;
|
y = ynew * static_cast<double>(mc.fy) + y0;
|
||||||
}
|
}
|
||||||
|
|
||||||
x -= cx * scale;
|
x -= cx * scale;
|
||||||
@ -1094,20 +1054,20 @@ void rtengine::LCPMapper::correctCA(double& x, double& y, int cx, int cy, int ch
|
|||||||
|
|
||||||
// First calc the green channel like normal distortion
|
// First calc the green channel like normal distortion
|
||||||
// the other are just deviations from it
|
// the other are just deviations from it
|
||||||
double xd = (x - chrom[1].x0) / chrom[1].fx;
|
double xd = (x - static_cast<double>(chrom[1].x0)) / static_cast<double>(chrom[1].fx);
|
||||||
double yd = (y - chrom[1].y0) / chrom[1].fy;
|
double yd = (y - static_cast<double>(chrom[1].y0)) / static_cast<double>(chrom[1].fy);
|
||||||
|
|
||||||
// Green contains main distortion, just like base
|
// Green contains main distortion, just like base
|
||||||
if (useCADist) {
|
if (useCADist) {
|
||||||
const LCPModelCommon::Param aDist = chrom[1].param;
|
const auto& aDist = chrom[1].param;
|
||||||
double rsqr = xd * xd + yd * yd;
|
double rsqr = xd * xd + yd * yd;
|
||||||
double xfac = aDist[swapXY ? 3 : 4], yfac = aDist[swapXY ? 4 : 3];
|
double xfac = static_cast<double>(aDist[swapXY ? 3 : 4]), yfac = static_cast<double>(aDist[swapXY ? 4 : 3]);
|
||||||
|
|
||||||
double commonFac = (((aDist[2] * rsqr + aDist[1]) * rsqr + aDist[0]) * rsqr + 1.)
|
double commonFac = (((static_cast<double>(aDist[2]) * rsqr + static_cast<double>(aDist[1])) * rsqr + static_cast<double>(aDist[0])) * rsqr + 1.)
|
||||||
+ 2. * (yfac * yd + xfac * xd);
|
+ 2. * (yfac * yd + xfac * xd);
|
||||||
|
|
||||||
xgreen = xd * commonFac + aDist[4] * rsqr;
|
xgreen = xd * commonFac + static_cast<double>(aDist[4]) * rsqr;
|
||||||
ygreen = yd * commonFac + aDist[3] * rsqr;
|
ygreen = yd * commonFac + static_cast<double>(aDist[3]) * rsqr;
|
||||||
} else {
|
} else {
|
||||||
xgreen = xd;
|
xgreen = xd;
|
||||||
ygreen = yd;
|
ygreen = yd;
|
||||||
@ -1115,20 +1075,20 @@ void rtengine::LCPMapper::correctCA(double& x, double& y, int cx, int cy, int ch
|
|||||||
|
|
||||||
if (channel == 1) {
|
if (channel == 1) {
|
||||||
// green goes directly
|
// green goes directly
|
||||||
x = xgreen * chrom[1].fx + chrom[1].x0;
|
x = xgreen * static_cast<double>(chrom[1].fx) + static_cast<double>(chrom[1].x0);
|
||||||
y = ygreen * chrom[1].fy + chrom[1].y0;
|
y = ygreen * static_cast<double>(chrom[1].fy) + static_cast<double>(chrom[1].y0);
|
||||||
} else {
|
} else {
|
||||||
// others are diffs from green
|
// others are diffs from green
|
||||||
xd = xgreen;
|
xd = xgreen;
|
||||||
yd = ygreen;
|
yd = ygreen;
|
||||||
const double rsqr = xd * xd + yd * yd;
|
const double rsqr = xd * xd + yd * yd;
|
||||||
|
|
||||||
const LCPModelCommon::Param aCA = chrom[channel].param;
|
const auto& aCA = chrom[channel].param;
|
||||||
const double xfac = aCA[swapXY ? 3 : 4], yfac = aCA[swapXY ? 4 : 3];
|
const double xfac = static_cast<double>(aCA[swapXY ? 3 : 4]), yfac = static_cast<double>(aCA[swapXY ? 4 : 3]);
|
||||||
const double commonSum = 1. + rsqr * (aCA[0] + rsqr * (aCA[1] + aCA[2] * rsqr)) + 2. * (yfac * yd + xfac * xd);
|
const double commonSum = 1. + rsqr * (static_cast<double>(aCA[0]) + rsqr * (static_cast<double>(aCA[1]) + static_cast<double>(aCA[2] )* rsqr)) + 2. * (yfac * yd + xfac * xd);
|
||||||
|
|
||||||
x = (chrom[channel].scale_factor * ( xd * commonSum + xfac * rsqr )) * chrom[channel].fx + chrom[channel].x0;
|
x = (static_cast<double>(chrom[channel].scale_factor) * ( xd * commonSum + xfac * rsqr )) * static_cast<double>(chrom[channel].fx) + static_cast<double>(chrom[channel].x0);
|
||||||
y = (chrom[channel].scale_factor * ( yd * commonSum + yfac * rsqr )) * chrom[channel].fy + chrom[channel].y0;
|
y = (static_cast<double>(chrom[channel].scale_factor) * ( yd * commonSum + yfac * rsqr )) * static_cast<double>(chrom[channel].fy) + static_cast<double>(chrom[channel].y0);
|
||||||
}
|
}
|
||||||
|
|
||||||
x -= cx;
|
x -= cx;
|
||||||
|
@ -54,7 +54,6 @@ public:
|
|||||||
LCPModelCommon();
|
LCPModelCommon();
|
||||||
|
|
||||||
bool empty() const; // is it empty
|
bool empty() const; // is it empty
|
||||||
void print() const; // printf all values
|
|
||||||
void merge(const LCPModelCommon& a, const LCPModelCommon& b, float facA);
|
void merge(const LCPModelCommon& a, const LCPModelCommon& b, float facA);
|
||||||
void prepareParams(
|
void prepareParams(
|
||||||
int fullWidth,
|
int fullWidth,
|
||||||
@ -106,7 +105,6 @@ public:
|
|||||||
LCPModelCommon *pCorr3
|
LCPModelCommon *pCorr3
|
||||||
) const; // Interpolates between the persModels frames
|
) const; // Interpolates between the persModels frames
|
||||||
|
|
||||||
void print() const;
|
|
||||||
|
|
||||||
//private:
|
//private:
|
||||||
// Common data
|
// Common data
|
||||||
|
@ -334,7 +334,7 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, const array2D<flo
|
|||||||
float p8 = rix[2][ 3];
|
float p8 = rix[2][ 3];
|
||||||
float p9 = rix[2][ 4];
|
float p9 = rix[2][ 4];
|
||||||
float mu = (p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) / 9.f;
|
float mu = (p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) / 9.f;
|
||||||
float vx = 1e-7 + SQR(p1 - mu) + SQR(p2 - mu) + SQR(p3 - mu) + SQR(p4 - mu) + SQR(p5 - mu) + SQR(p6 - mu) + SQR(p7 - mu) + SQR(p8 - mu) + SQR(p9 - mu);
|
float vx = 1e-7f + SQR(p1 - mu) + SQR(p2 - mu) + SQR(p3 - mu) + SQR(p4 - mu) + SQR(p5 - mu) + SQR(p6 - mu) + SQR(p7 - mu) + SQR(p8 - mu) + SQR(p9 - mu);
|
||||||
p1 -= rix[0][-4];
|
p1 -= rix[0][-4];
|
||||||
p2 -= rix[0][-3];
|
p2 -= rix[0][-3];
|
||||||
p3 -= rix[0][-2];
|
p3 -= rix[0][-2];
|
||||||
@ -344,7 +344,7 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, const array2D<flo
|
|||||||
p7 -= rix[0][ 2];
|
p7 -= rix[0][ 2];
|
||||||
p8 -= rix[0][ 3];
|
p8 -= rix[0][ 3];
|
||||||
p9 -= rix[0][ 4];
|
p9 -= rix[0][ 4];
|
||||||
float vn = 1e-7 + SQR(p1) + SQR(p2) + SQR(p3) + SQR(p4) + SQR(p5) + SQR(p6) + SQR(p7) + SQR(p8) + SQR(p9);
|
float vn = 1e-7f + SQR(p1) + SQR(p2) + SQR(p3) + SQR(p4) + SQR(p5) + SQR(p6) + SQR(p7) + SQR(p8) + SQR(p9);
|
||||||
float xh = (rix[0][0] * vx + rix[2][0] * vn) / (vx + vn);
|
float xh = (rix[0][0] * vx + rix[2][0] * vn) / (vx + vn);
|
||||||
float vh = vx * vn / (vx + vn);
|
float vh = vx * vn / (vx + vn);
|
||||||
|
|
||||||
@ -359,7 +359,7 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, const array2D<flo
|
|||||||
p8 = rix[3][ w3];
|
p8 = rix[3][ w3];
|
||||||
p9 = rix[3][ w4];
|
p9 = rix[3][ w4];
|
||||||
mu = (p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) / 9.f;
|
mu = (p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) / 9.f;
|
||||||
vx = 1e-7 + SQR(p1 - mu) + SQR(p2 - mu) + SQR(p3 - mu) + SQR(p4 - mu) + SQR(p5 - mu) + SQR(p6 - mu) + SQR(p7 - mu) + SQR(p8 - mu) + SQR(p9 - mu);
|
vx = 1e-7f + SQR(p1 - mu) + SQR(p2 - mu) + SQR(p3 - mu) + SQR(p4 - mu) + SQR(p5 - mu) + SQR(p6 - mu) + SQR(p7 - mu) + SQR(p8 - mu) + SQR(p9 - mu);
|
||||||
p1 -= rix[1][-w4];
|
p1 -= rix[1][-w4];
|
||||||
p2 -= rix[1][-w3];
|
p2 -= rix[1][-w3];
|
||||||
p3 -= rix[1][-w2];
|
p3 -= rix[1][-w2];
|
||||||
@ -369,7 +369,7 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, const array2D<flo
|
|||||||
p7 -= rix[1][ w2];
|
p7 -= rix[1][ w2];
|
||||||
p8 -= rix[1][ w3];
|
p8 -= rix[1][ w3];
|
||||||
p9 -= rix[1][ w4];
|
p9 -= rix[1][ w4];
|
||||||
vn = 1e-7 + SQR(p1) + SQR(p2) + SQR(p3) + SQR(p4) + SQR(p5) + SQR(p6) + SQR(p7) + SQR(p8) + SQR(p9);
|
vn = 1e-7f + SQR(p1) + SQR(p2) + SQR(p3) + SQR(p4) + SQR(p5) + SQR(p6) + SQR(p7) + SQR(p8) + SQR(p9);
|
||||||
float xv = (rix[1][0] * vx + rix[3][0] * vn) / (vx + vn);
|
float xv = (rix[1][0] * vx + rix[3][0] * vn) / (vx + vn);
|
||||||
float vv = vx * vn / (vx + vn);
|
float vv = vx * vn / (vx + vn);
|
||||||
// interpolated G-R(B)
|
// interpolated G-R(B)
|
||||||
|
1232
rtengine/munselllch.cc
Normal file
1232
rtengine/munselllch.cc
Normal file
File diff suppressed because it is too large
Load Diff
@ -18,27 +18,24 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#ifndef OPTHELPER_H
|
#define pow_F(a,b) (xexpf(b*xlogf(a)))
|
||||||
#define OPTHELPER_H
|
|
||||||
|
|
||||||
#define pow_F(a,b) (xexpf(b*xlogf(a)))
|
#ifdef __SSE2__
|
||||||
|
#include "sleefsseavx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __SSE2__
|
#ifdef __GNUC__
|
||||||
#include "sleefsseavx.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define RESTRICT __restrict__
|
#define RESTRICT __restrict__
|
||||||
#define LIKELY(x) __builtin_expect (!!(x), 1)
|
#define LIKELY(x) __builtin_expect (!!(x), 1)
|
||||||
#define UNLIKELY(x) __builtin_expect (!!(x), 0)
|
#define UNLIKELY(x) __builtin_expect (!!(x), 0)
|
||||||
#define ALIGNED64 __attribute__ ((aligned (64)))
|
#define ALIGNED64 __attribute__ ((aligned (64)))
|
||||||
#define ALIGNED16 __attribute__ ((aligned (16)))
|
#define ALIGNED16 __attribute__ ((aligned (16)))
|
||||||
#else
|
#else
|
||||||
#define RESTRICT
|
#define RESTRICT
|
||||||
#define LIKELY(x) (x)
|
#define LIKELY(x) (x)
|
||||||
#define UNLIKELY(x) (x)
|
#define UNLIKELY(x) (x)
|
||||||
#define ALIGNED64
|
#define ALIGNED64
|
||||||
#define ALIGNED16
|
#define ALIGNED16
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,10 +18,16 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <glibmm/ustring.h>
|
|
||||||
|
|
||||||
#include <cairomm/cairomm.h>
|
#include <cairomm/cairomm.h>
|
||||||
|
|
||||||
|
namespace Glib
|
||||||
|
{
|
||||||
|
|
||||||
|
class ustring;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
class ProcessingJobImpl : public ProcessingJob
|
class ProcessingJobImpl final : public ProcessingJob
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -4289,7 +4289,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
|
|||||||
|
|
||||||
if (keyFile.has_key("Shadows & Highlights", "LocalContrast") && ppVersion < 329) {
|
if (keyFile.has_key("Shadows & Highlights", "LocalContrast") && ppVersion < 329) {
|
||||||
int lc = keyFile.get_integer("Shadows & Highlights", "LocalContrast");
|
int lc = keyFile.get_integer("Shadows & Highlights", "LocalContrast");
|
||||||
localContrast.amount = float(lc) / 30.;
|
localContrast.amount = float(lc) / 30.f;
|
||||||
|
|
||||||
if (pedited) {
|
if (pedited) {
|
||||||
pedited->localContrast.amount = true;
|
pedited->localContrast.amount = true;
|
||||||
@ -4606,8 +4606,9 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
|
|||||||
Glib::ustring temp;
|
Glib::ustring temp;
|
||||||
assignFromKeyfile(keyFile, "Wavelet", "LevMethod", pedited, temp, pedited->wavelet.Lmethod);
|
assignFromKeyfile(keyFile, "Wavelet", "LevMethod", pedited, temp, pedited->wavelet.Lmethod);
|
||||||
|
|
||||||
if (!temp.empty()) {
|
try {
|
||||||
wavelet.Lmethod = std::stoi(temp);
|
wavelet.Lmethod = std::stoi(temp);
|
||||||
|
} catch (...) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assignFromKeyfile(keyFile, "Wavelet", "LevMethod", pedited, wavelet.Lmethod, pedited->wavelet.Lmethod);
|
assignFromKeyfile(keyFile, "Wavelet", "LevMethod", pedited, wavelet.Lmethod, pedited->wavelet.Lmethod);
|
||||||
|
@ -171,7 +171,7 @@ void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblac
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int c = 0; c < 4; c++) {
|
for (int c = 0; c < 4; c++) {
|
||||||
dsumthr[c] += sum[c];
|
dsumthr[c] += static_cast<double>(sum[c]);
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_block2:
|
skip_block2:
|
||||||
@ -195,7 +195,7 @@ skip_block2:
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(int c = 0; c < 4; c++) {
|
for(int c = 0; c < 4; c++) {
|
||||||
dsum[c] -= cblack_[c] * dsum[c + 4];
|
dsum[c] -= static_cast<double>(cblack_[c]) * dsum[c + 4];
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(isXtrans()) {
|
} else if(isXtrans()) {
|
||||||
@ -241,7 +241,7 @@ skip_block2:
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int c = 0; c < 8; c++) {
|
for (int c = 0; c < 8; c++) {
|
||||||
dsumthr[c] += sum[c];
|
dsumthr[c] += static_cast<double>(sum[c]);
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_block3:
|
skip_block3:
|
||||||
@ -365,18 +365,14 @@ skip_block:
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (dmin = DBL_MAX, dmax = c = 0; c < 4; c++) {
|
for (dmin = DBL_MAX, dmax = c = 0; c < 4; c++) {
|
||||||
if (dmin > pre_mul_[c]) {
|
dmin = rtengine::min<double>(dmin, pre_mul_[c]);
|
||||||
dmin = pre_mul_[c];
|
dmax = rtengine::max<double>(dmax, pre_mul_[c]);
|
||||||
}
|
|
||||||
|
|
||||||
if (dmax < pre_mul_[c]) {
|
|
||||||
dmax = pre_mul_[c];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c = 0; c < 4; c++) {
|
for (c = 0; c < 4; c++) {
|
||||||
int sat = this->get_white(c) - cblack_[c];
|
int sat = this->get_white(c) - cblack_[c];
|
||||||
scale_mul_[c] = (pre_mul_[c] /= dmax) * 65535.0 / sat;
|
pre_mul_[c] /= static_cast<float>(dmax);
|
||||||
|
scale_mul_[c] = pre_mul_[c] * 65535.f / sat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
@ -387,25 +383,30 @@ skip_block:
|
|||||||
asn[c] = 0;
|
asn[c] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asn[c] > dmax) {
|
if (asn[c] > static_cast<float>(dmax)) {
|
||||||
dmax = asn[c];
|
dmax = asn[c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c = 0; c < 4; c++) {
|
for (c = 0; c < 4; c++) {
|
||||||
asn[c] /= dmax;
|
asn[c] /= static_cast<float>(dmax);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("cam_mul:[%f %f %f %f], AsShotNeutral:[%f %f %f %f]\n",
|
printf("cam_mul:[%f %f %f %f], AsShotNeutral:[%f %f %f %f]\n",
|
||||||
cam_mul[0], cam_mul[1], cam_mul[2], cam_mul[3], asn[0], asn[1], asn[2], asn[3]);
|
static_cast<double>(cam_mul[0]), static_cast<double>(cam_mul[1]),
|
||||||
|
static_cast<double>(cam_mul[2]), static_cast<double>(cam_mul[3]),
|
||||||
|
static_cast<double>(asn[0]), static_cast<double>(asn[1]), static_cast<double>(asn[2]), static_cast<double>(asn[3]));
|
||||||
printf("pre_mul:[%f %f %f %f], scale_mul:[%f %f %f %f], cblack:[%f %f %f %f]\n",
|
printf("pre_mul:[%f %f %f %f], scale_mul:[%f %f %f %f], cblack:[%f %f %f %f]\n",
|
||||||
pre_mul_[0], pre_mul_[1], pre_mul_[2], pre_mul_[3],
|
static_cast<double>(pre_mul_[0]), static_cast<double>(pre_mul_[1]),
|
||||||
scale_mul_[0], scale_mul_[1], scale_mul_[2], scale_mul_[3],
|
static_cast<double>(pre_mul_[2]), static_cast<double>(pre_mul_[3]),
|
||||||
cblack_[0], cblack_[1], cblack_[2], cblack_[3]);
|
static_cast<double>(scale_mul_[0]), static_cast<double>(scale_mul_[1]),
|
||||||
|
static_cast<double>(scale_mul_[2]), static_cast<double>(scale_mul_[3]),
|
||||||
|
static_cast<double>(cblack_[0]), static_cast<double>(cblack_[1]),
|
||||||
|
static_cast<double>(cblack_[2]), static_cast<double>(cblack_[3]));
|
||||||
printf("rgb_cam:[ [ %f %f %f], [%f %f %f], [%f %f %f] ]%s\n",
|
printf("rgb_cam:[ [ %f %f %f], [%f %f %f], [%f %f %f] ]%s\n",
|
||||||
rgb_cam[0][0], rgb_cam[1][0], rgb_cam[2][0],
|
static_cast<double>(rgb_cam[0][0]), static_cast<double>(rgb_cam[1][0]), static_cast<double>(rgb_cam[2][0]),
|
||||||
rgb_cam[0][1], rgb_cam[1][1], rgb_cam[2][1],
|
static_cast<double>(rgb_cam[0][1]), static_cast<double>(rgb_cam[1][1]), static_cast<double>(rgb_cam[2][1]),
|
||||||
rgb_cam[0][2], rgb_cam[1][2], rgb_cam[2][2],
|
static_cast<double>(rgb_cam[0][2]), static_cast<double>(rgb_cam[1][2]), static_cast<double>(rgb_cam[2][2]),
|
||||||
(!this->isBayer()) ? " (not bayer)" : "");
|
(!this->isBayer()) ? " (not bayer)" : "");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "camconst.h"
|
#include "camconst.h"
|
||||||
@ -25,6 +26,7 @@
|
|||||||
#include "dcp.h"
|
#include "dcp.h"
|
||||||
#include "dfmanager.h"
|
#include "dfmanager.h"
|
||||||
#include "ffmanager.h"
|
#include "ffmanager.h"
|
||||||
|
#include "iccmatrices.h"
|
||||||
#include "iccstore.h"
|
#include "iccstore.h"
|
||||||
#include "imagefloat.h"
|
#include "imagefloat.h"
|
||||||
#include "improcfun.h"
|
#include "improcfun.h"
|
||||||
@ -49,10 +51,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "opthelper.h"
|
#include "opthelper.h"
|
||||||
#define clipretinex( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val )
|
|
||||||
|
|
||||||
#undef CLIPD
|
|
||||||
#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f)
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -101,7 +99,7 @@ void transLineFuji (const float* const red, const float* const green, const floa
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Fuji SuperCCD rotation + coarse rotation
|
// Fuji SuperCCD rotation + coarse rotation
|
||||||
int start = ABS(fw - i);
|
int start = std::abs(fw - i);
|
||||||
int w = fw * 2 + 1;
|
int w = fw * 2 + 1;
|
||||||
int h = (imheight - fw) * 2 + 1;
|
int h = (imheight - fw) * 2 + 1;
|
||||||
int end = min(h + fw - i, w - fw + i);
|
int end = min(h + fw - i, w - fw + i);
|
||||||
@ -425,12 +423,6 @@ void transLineD1x (const float* const red, const float* const green, const float
|
|||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
#undef ABS
|
|
||||||
#undef DIST
|
|
||||||
|
|
||||||
#define ABS(a) ((a)<0?-(a):(a))
|
|
||||||
#define DIST(a,b) (ABS(a-b))
|
|
||||||
|
|
||||||
RawImageSource::RawImageSource ()
|
RawImageSource::RawImageSource ()
|
||||||
: ImageSource()
|
: ImageSource()
|
||||||
, W(0), H(0)
|
, W(0), H(0)
|
||||||
@ -620,7 +612,7 @@ float calculate_scale_mul(float scale_mul[4], const float pre_mul_[4], const flo
|
|||||||
{
|
{
|
||||||
if (isMono || colors == 1) {
|
if (isMono || colors == 1) {
|
||||||
for (int c = 0; c < 4; c++) {
|
for (int c = 0; c < 4; c++) {
|
||||||
scale_mul[c] = 65535.0 / (c_white[c] - c_black[c]);
|
scale_mul[c] = 65535.f / (c_white[c] - c_black[c]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
float pre_mul[4];
|
float pre_mul[4];
|
||||||
@ -636,7 +628,7 @@ float calculate_scale_mul(float scale_mul[4], const float pre_mul_[4], const flo
|
|||||||
float maxpremul = max(pre_mul[0], pre_mul[1], pre_mul[2], pre_mul[3]);
|
float maxpremul = max(pre_mul[0], pre_mul[1], pre_mul[2], pre_mul[3]);
|
||||||
|
|
||||||
for (int c = 0; c < 4; c++) {
|
for (int c = 0; c < 4; c++) {
|
||||||
scale_mul[c] = (pre_mul[c] / maxpremul) * 65535.0 / (c_white[c] - c_black[c]);
|
scale_mul[c] = (pre_mul[c] / maxpremul) * 65535.f / (c_white[c] - c_black[c]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,7 +667,7 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima
|
|||||||
|| (ri->getSensorType() == ST_BAYER && raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO));
|
|| (ri->getSensorType() == ST_BAYER && raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO));
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
c_white[i] = (ri->get_white(i) - cblacksom[i]) / raw.expos + cblacksom[i];
|
c_white[i] = (ri->get_white(i) - cblacksom[i]) / static_cast<float>(raw.expos) + cblacksom[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
float gain = calculate_scale_mul(new_scale_mul, new_pre_mul, c_white, cblacksom, isMono, ri->get_colors());
|
float gain = calculate_scale_mul(new_scale_mul, new_pre_mul, c_white, cblacksom, isMono, ri->get_colors());
|
||||||
@ -684,21 +676,21 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima
|
|||||||
bm = new_scale_mul[2] / scale_mul[2] * gain;
|
bm = new_scale_mul[2] / scale_mul[2] * gain;
|
||||||
//fprintf(stderr, "camera gain: %f, current wb gain: %f, diff in stops %f\n", camInitialGain, gain, log2(camInitialGain) - log2(gain));
|
//fprintf(stderr, "camera gain: %f, current wb gain: %f, diff in stops %f\n", camInitialGain, gain, log2(camInitialGain) - log2(gain));
|
||||||
} else {
|
} else {
|
||||||
// old scaling: used a fixed reference gain based on camera (as-shot) white balance
|
// // old scaling: used a fixed reference gain based on camera (as-shot) white balance
|
||||||
|
//
|
||||||
// how much we need to scale each channel to get our new white balance
|
// // how much we need to scale each channel to get our new white balance
|
||||||
rm = refwb_red / rm;
|
// rm = refwb_red / rm;
|
||||||
gm = refwb_green / gm;
|
// gm = refwb_green / gm;
|
||||||
bm = refwb_blue / bm;
|
// bm = refwb_blue / bm;
|
||||||
// normalize so larger multiplier becomes 1.0
|
// // normalize so larger multiplier becomes 1.0
|
||||||
float minval = min(rm, gm, bm);
|
// float minval = min(rm, gm, bm);
|
||||||
rm /= minval;
|
// rm /= minval;
|
||||||
gm /= minval;
|
// gm /= minval;
|
||||||
bm /= minval;
|
// bm /= minval;
|
||||||
// multiply with reference gain, ie as-shot WB
|
// // multiply with reference gain, ie as-shot WB
|
||||||
rm *= camInitialGain;
|
// rm *= camInitialGain;
|
||||||
gm *= camInitialGain;
|
// gm *= camInitialGain;
|
||||||
bm *= camInitialGain;
|
// bm *= camInitialGain;
|
||||||
}
|
}
|
||||||
|
|
||||||
defGain = 0.0;
|
defGain = 0.0;
|
||||||
@ -877,13 +869,13 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima
|
|||||||
for (int i = 1; i < image->getHeight() - 1; i++) {
|
for (int i = 1; i < image->getHeight() - 1; i++) {
|
||||||
for (int j = 2 - (a + i + 1) % 2; j < image->getWidth() - 1; j += 2) {
|
for (int j = 2 - (a + i + 1) % 2; j < image->getWidth() - 1; j += 2) {
|
||||||
// edge-adaptive interpolation
|
// edge-adaptive interpolation
|
||||||
double dh = (ABS(image->r(i, j + 1) - image->r(i, j - 1)) + ABS(image->g(i, j + 1) - image->g(i, j - 1)) + ABS(image->b(i, j + 1) - image->b(i, j - 1))) / 1.0;
|
float dh = (std::fabs(image->r(i, j + 1) - image->r(i, j - 1)) + std::fabs(image->g(i, j + 1) - image->g(i, j - 1)) + std::fabs(image->b(i, j + 1) - image->b(i, j - 1)));
|
||||||
double dv = (ABS(image->r(i + 1, j) - image->r(i - 1, j)) + ABS(image->g(i + 1, j) - image->g(i - 1, j)) + ABS(image->b(i + 1, j) - image->b(i - 1, j))) / 1.0;
|
float dv = (std::fabs(image->r(i + 1, j) - image->r(i - 1, j)) + std::fabs(image->g(i + 1, j) - image->g(i - 1, j)) + std::fabs(image->b(i + 1, j) - image->b(i - 1, j)));
|
||||||
double eh = 1.0 / (1.0 + dh);
|
float eh = 1.f / (1.f + dh);
|
||||||
double ev = 1.0 / (1.0 + dv);
|
float ev = 1.f / (1.f + dv);
|
||||||
image->r(i, j) = (eh * (image->r(i, j + 1) + image->r(i, j - 1)) + ev * (image->r(i + 1, j) + image->r(i - 1, j))) / (2.0 * (eh + ev));
|
image->r(i, j) = (eh * (image->r(i, j + 1) + image->r(i, j - 1)) + ev * (image->r(i + 1, j) + image->r(i - 1, j))) / (2.f * (eh + ev));
|
||||||
image->g(i, j) = (eh * (image->g(i, j + 1) + image->g(i, j - 1)) + ev * (image->g(i + 1, j) + image->g(i - 1, j))) / (2.0 * (eh + ev));
|
image->g(i, j) = (eh * (image->g(i, j + 1) + image->g(i, j - 1)) + ev * (image->g(i + 1, j) + image->g(i - 1, j))) / (2.f * (eh + ev));
|
||||||
image->b(i, j) = (eh * (image->b(i, j + 1) + image->b(i, j - 1)) + ev * (image->b(i + 1, j) + image->b(i - 1, j))) / (2.0 * (eh + ev));
|
image->b(i, j) = (eh * (image->b(i, j + 1) + image->b(i, j - 1)) + ev * (image->b(i + 1, j) + image->b(i - 1, j))) / (2.f * (eh + ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
// first pixel
|
// first pixel
|
||||||
@ -1547,7 +1539,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(prepareDenoise && dirpyrdenoiseExpComp == INFINITY) {
|
if(prepareDenoise && dirpyrdenoiseExpComp == RT_INFINITY) {
|
||||||
LUTu aehist;
|
LUTu aehist;
|
||||||
int aehistcompr;
|
int aehistcompr;
|
||||||
double clip = 0;
|
double clip = 0;
|
||||||
@ -2916,7 +2908,7 @@ lab2ProphotoRgbD50(float L, float A, float B, float& r, float& g, float& b)
|
|||||||
float X;
|
float X;
|
||||||
float Y;
|
float Y;
|
||||||
float Z;
|
float Z;
|
||||||
#define CLIP01(a) ((a)>0?((a)<1?(a):1):0)
|
|
||||||
{
|
{
|
||||||
// convert from Lab to XYZ
|
// convert from Lab to XYZ
|
||||||
float x, y, z, fx, fy, fz;
|
float x, y, z, fx, fy, fz;
|
||||||
@ -2951,9 +2943,6 @@ lab2ProphotoRgbD50(float L, float A, float B, float& r, float& g, float& b)
|
|||||||
r = prophoto_xyz[0][0] * X + prophoto_xyz[0][1] * Y + prophoto_xyz[0][2] * Z;
|
r = prophoto_xyz[0][0] * X + prophoto_xyz[0][1] * Y + prophoto_xyz[0][2] * Z;
|
||||||
g = prophoto_xyz[1][0] * X + prophoto_xyz[1][1] * Y + prophoto_xyz[1][2] * Z;
|
g = prophoto_xyz[1][0] * X + prophoto_xyz[1][1] * Y + prophoto_xyz[1][2] * Z;
|
||||||
b = prophoto_xyz[2][0] * X + prophoto_xyz[2][1] * Y + prophoto_xyz[2][2] * Z;
|
b = prophoto_xyz[2][0] * X + prophoto_xyz[2][1] * Y + prophoto_xyz[2][2] * Z;
|
||||||
// r = CLIP01(r);
|
|
||||||
// g = CLIP01(g);
|
|
||||||
// b = CLIP01(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts raw image including ICC input profile to working space - floating point version
|
// Converts raw image including ICC input profile to working space - floating point version
|
||||||
@ -3881,7 +3870,7 @@ void RawImageSource::getRowStartEnd (int x, int &start, int &end)
|
|||||||
{
|
{
|
||||||
if (fuji) {
|
if (fuji) {
|
||||||
int fw = ri->get_FujiWidth();
|
int fw = ri->get_FujiWidth();
|
||||||
start = ABS(fw - x) + border;
|
start = std::abs(fw - x) + border;
|
||||||
end = min(H + W - fw - x, fw + x) - border;
|
end = min(H + W - fw - x, fw + x) - border;
|
||||||
} else {
|
} else {
|
||||||
start = border;
|
start = border;
|
||||||
@ -3922,7 +3911,7 @@ void RawImageSource::getAutoWBMultipliers (double &rm, double &gm, double &bm)
|
|||||||
if (fuji) {
|
if (fuji) {
|
||||||
for (int i = 32; i < H - 32; i++) {
|
for (int i = 32; i < H - 32; i++) {
|
||||||
int fw = ri->get_FujiWidth();
|
int fw = ri->get_FujiWidth();
|
||||||
int start = ABS(fw - i) + 32;
|
int start = std::abs(fw - i) + 32;
|
||||||
int end = min(H + W - fw - i, fw + i) - 32;
|
int end = min(H + W - fw - i, fw + i) - 32;
|
||||||
|
|
||||||
for (int j = start; j < end; j++) {
|
for (int j = start; j < end; j++) {
|
||||||
|
@ -37,7 +37,7 @@ class DiagonalCurve;
|
|||||||
class RetinextransmissionCurve;
|
class RetinextransmissionCurve;
|
||||||
class RetinexgaintransmissionCurve;
|
class RetinexgaintransmissionCurve;
|
||||||
|
|
||||||
class RawImageSource : public ImageSource
|
class RawImageSource final : public ImageSource
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static DiagonalCurve *phaseOneIccCurve;
|
static DiagonalCurve *phaseOneIccCurve;
|
||||||
|
@ -20,9 +20,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "array2D.h"
|
|
||||||
#include "rt_math.h"
|
#include "rt_math.h"
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class array2D;
|
||||||
|
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include "imageformat.h"
|
#include "imageformat.h"
|
||||||
#include "procevents.h"
|
#include "procevents.h"
|
||||||
#include "rawmetadatalocation.h"
|
#include "rawmetadatalocation.h"
|
||||||
#include "rt_math.h"
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
#include "../rtgui/threadutils.h"
|
#include "../rtgui/threadutils.h"
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "colortemp.h"
|
#include "colortemp.h"
|
||||||
#include "curves.h"
|
#include "curves.h"
|
||||||
#include "dcp.h"
|
#include "dcp.h"
|
||||||
|
#include "iccmatrices.h"
|
||||||
#include "iccstore.h"
|
#include "iccstore.h"
|
||||||
#include "image8.h"
|
#include "image8.h"
|
||||||
#include "improcfun.h"
|
#include "improcfun.h"
|
||||||
@ -511,8 +512,6 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL
|
|||||||
((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==0 || !filter)
|
((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==0 || !filter)
|
||||||
#define FISGREEN(filter,row,col) \
|
#define FISGREEN(filter,row,col) \
|
||||||
((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==1 || !filter)
|
((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==1 || !filter)
|
||||||
#define FISBLUE(filter,row,col) \
|
|
||||||
((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==2 || !filter)
|
|
||||||
|
|
||||||
RawMetaDataLocation Thumbnail::loadMetaDataFromRaw (const Glib::ustring& fname)
|
RawMetaDataLocation Thumbnail::loadMetaDataFromRaw (const Glib::ustring& fname)
|
||||||
{
|
{
|
||||||
@ -2254,44 +2253,6 @@ bool Thumbnail::writeEmbProfile (const Glib::ustring& fname)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Thumbnail::readAEHistogram (const Glib::ustring& fname)
|
|
||||||
{
|
|
||||||
|
|
||||||
FILE* f = g_fopen(fname.c_str(), "rb");
|
|
||||||
|
|
||||||
if (!f) {
|
|
||||||
aeHistogram.reset();
|
|
||||||
} else {
|
|
||||||
aeHistogram(65536 >> aeHistCompression);
|
|
||||||
const size_t histoBytes = (65536 >> aeHistCompression) * sizeof(aeHistogram[0]);
|
|
||||||
const size_t bytesRead = fread(&aeHistogram[0], 1, histoBytes, f);
|
|
||||||
fclose (f);
|
|
||||||
if (bytesRead != histoBytes) {
|
|
||||||
aeHistogram.reset();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Thumbnail::writeAEHistogram (const Glib::ustring& fname)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (aeHistogram) {
|
|
||||||
FILE* f = g_fopen (fname.c_str (), "wb");
|
|
||||||
|
|
||||||
if (f) {
|
|
||||||
fwrite (&aeHistogram[0], 1, (65536 >> aeHistCompression)*sizeof (aeHistogram[0]), f);
|
|
||||||
fclose (f);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char* Thumbnail::getImage8Data()
|
unsigned char* Thumbnail::getImage8Data()
|
||||||
{
|
{
|
||||||
if (thumbImg && thumbImg->getType() == rtengine::sImage8) {
|
if (thumbImg && thumbImg->getType() == rtengine::sImage8) {
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <glibmm/ustring.h>
|
|
||||||
|
|
||||||
#include <lcms2.h>
|
#include <lcms2.h>
|
||||||
|
|
||||||
#include "image16.h"
|
#include "image16.h"
|
||||||
@ -30,6 +28,13 @@
|
|||||||
|
|
||||||
#include "../rtgui/threadutils.h"
|
#include "../rtgui/threadutils.h"
|
||||||
|
|
||||||
|
namespace Glib
|
||||||
|
{
|
||||||
|
|
||||||
|
class ustring;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -108,10 +113,6 @@ public:
|
|||||||
bool readEmbProfile (const Glib::ustring& fname);
|
bool readEmbProfile (const Glib::ustring& fname);
|
||||||
bool writeEmbProfile (const Glib::ustring& fname);
|
bool writeEmbProfile (const Glib::ustring& fname);
|
||||||
|
|
||||||
bool readAEHistogram (const Glib::ustring& fname);
|
|
||||||
bool writeAEHistogram (const Glib::ustring& fname);
|
|
||||||
|
|
||||||
bool isAeValid() { return aeValid; };
|
|
||||||
unsigned char* getImage8Data(); // accessor to the 8bit image if it is one, which should be the case for the "Inspector" mode.
|
unsigned char* getImage8Data(); // accessor to the 8bit image if it is one, which should be the case for the "Inspector" mode.
|
||||||
|
|
||||||
// Hombre: ... let's hope that proper template can make this cleaner
|
// Hombre: ... let's hope that proper template can make this cleaner
|
||||||
|
@ -27,6 +27,37 @@
|
|||||||
#undef THREAD_PRIORITY_NORMAL
|
#undef THREAD_PRIORITY_NORMAL
|
||||||
#include "opthelper.h"
|
#include "opthelper.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void fillLuminance(rtengine::Imagefloat* img, float** luminance, const float lumi[3], int W, int H) // fill with luminance
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef _OPENMP
|
||||||
|
#pragma omp parallel for
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i = 0; i < H; i++)
|
||||||
|
for (int j = 0; j < W; j++) {
|
||||||
|
luminance[i][j] = lumi[0] * std::max(img->r(i, j), 0.f) + lumi[1] * std::max(img->g(i, j), 0.f) + lumi[2] * std::max(img->b(i, j), 0.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void fillLuminanceL(float** L, float** luminance, int W, int H) // fill with luminance
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef _OPENMP
|
||||||
|
#pragma omp parallel for
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i = 0; i < H; i++)
|
||||||
|
for (int j = 0; j < W; j++) {
|
||||||
|
luminance[i][j] = std::max(L[i][j], 0.f) ;//we can put here some enhancements Gamma, compression data,...
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -51,39 +82,13 @@ SHMap::~SHMap ()
|
|||||||
delete [] map;
|
delete [] map;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHMap::fillLuminance( Imagefloat * img, float **luminance, double lumi[3] ) // fill with luminance
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef _OPENMP
|
|
||||||
#pragma omp parallel for
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (int i = 0; i < H; i++)
|
|
||||||
for (int j = 0; j < W; j++) {
|
|
||||||
luminance[i][j] = lumi[0] * std::max(img->r(i, j), 0.f) + lumi[1] * std::max(img->g(i, j), 0.f) + lumi[2] * std::max(img->b(i, j), 0.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHMap::fillLuminanceL( float ** L, float **luminance) // fill with luminance
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef _OPENMP
|
|
||||||
#pragma omp parallel for
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (int i = 0; i < H; i++)
|
|
||||||
for (int j = 0; j < W; j++) {
|
|
||||||
luminance[i][j] = std::max(L[i][j], 0.f) ;//we can put here some enhancements Gamma, compression data,...
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int skip)
|
void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int skip)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
const float lumif[3] = { static_cast<float>(lumi[0]), static_cast<float>(lumi[1]), static_cast<float>(lumi[2]) };
|
||||||
|
|
||||||
if (!hq) {
|
if (!hq) {
|
||||||
fillLuminance( img, map, lumi);
|
fillLuminance(img, map, lumif, W, H);
|
||||||
|
|
||||||
const bool useBoxBlur = radius > 40.0; // boxblur is less prone to artifacts for large radi
|
const bool useBoxBlur = radius > 40.0; // boxblur is less prone to artifacts for large radi
|
||||||
|
|
||||||
@ -91,7 +96,7 @@ void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int
|
|||||||
#pragma omp parallel if (!useBoxBlur)
|
#pragma omp parallel if (!useBoxBlur)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
gaussianBlur (map, map, W, H, radius, useBoxBlur);
|
gaussianBlur(map, map, W, H, radius, useBoxBlur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +104,7 @@ void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int
|
|||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
//experimental dirpyr shmap
|
//experimental dirpyr shmap
|
||||||
|
|
||||||
float thresh = (100.f * radius); //1000;
|
float thresh = 100.0 * radius; //1000;
|
||||||
|
|
||||||
// set up range function
|
// set up range function
|
||||||
// calculate size of Lookup table. That's possible because from a value k for all i>=k rangefn[i] will be exp(-10)
|
// calculate size of Lookup table. That's possible because from a value k for all i>=k rangefn[i] will be exp(-10)
|
||||||
@ -142,7 +147,7 @@ void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int
|
|||||||
dirpyrlo[1] = buffer;
|
dirpyrlo[1] = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
fillLuminance( img, dirpyrlo[0], lumi);
|
fillLuminance(img, dirpyrlo[0], lumif, W, H);
|
||||||
|
|
||||||
scale = 1;
|
scale = 1;
|
||||||
int level = 0;
|
int level = 0;
|
||||||
@ -181,28 +186,18 @@ void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int
|
|||||||
for (int j = 0; j < W; j++) {
|
for (int j = 0; j < W; j++) {
|
||||||
_val = map[i][j];
|
_val = map[i][j];
|
||||||
|
|
||||||
if (_val < _min_f) {
|
_min_f = std::min(_min_f, _val);
|
||||||
_min_f = _val;
|
_max_f = std::max(_max_f, _val);
|
||||||
}
|
|
||||||
|
|
||||||
if (_val > _max_f) {
|
_avg += static_cast<double>(_val);
|
||||||
_max_f = _val;
|
|
||||||
}
|
|
||||||
|
|
||||||
_avg += _val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp critical
|
#pragma omp critical
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if(_min_f < min_f ) {
|
min_f = std::min(min_f, _min_f);
|
||||||
min_f = _min_f;
|
max_f = std::max(max_f, _max_f);
|
||||||
}
|
|
||||||
|
|
||||||
if(_max_f > max_f ) {
|
|
||||||
max_f = _max_f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_avg /= ((H) * (W));
|
_avg /= ((H) * (W));
|
||||||
@ -214,7 +209,7 @@ void SHMap::updateL (float** L, double radius, bool hq, int skip)
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (!hq) {
|
if (!hq) {
|
||||||
fillLuminanceL( L, map);
|
fillLuminanceL(L, map, W, H);
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
#endif
|
#endif
|
||||||
@ -228,7 +223,7 @@ void SHMap::updateL (float** L, double radius, bool hq, int skip)
|
|||||||
{
|
{
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
//experimental dirpyr shmap
|
//experimental dirpyr shmap
|
||||||
float thresh = (100.f * radius); //1000;
|
float thresh = 100.0 * radius; //1000;
|
||||||
int levrad; // = 16;
|
int levrad; // = 16;
|
||||||
levrad = 2; //for retinex - otherwise levrad = 16
|
levrad = 2; //for retinex - otherwise levrad = 16
|
||||||
// set up range function
|
// set up range function
|
||||||
@ -274,7 +269,7 @@ void SHMap::updateL (float** L, double radius, bool hq, int skip)
|
|||||||
dirpyrlo[1] = buffer;
|
dirpyrlo[1] = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
fillLuminanceL( L, dirpyrlo[0]);
|
fillLuminanceL(L, dirpyrlo[0], W, H);
|
||||||
|
|
||||||
scale = 1;
|
scale = 1;
|
||||||
int level = 0;
|
int level = 0;
|
||||||
@ -313,28 +308,18 @@ void SHMap::updateL (float** L, double radius, bool hq, int skip)
|
|||||||
for (int j = 0; j < W; j++) {
|
for (int j = 0; j < W; j++) {
|
||||||
_val = map[i][j];
|
_val = map[i][j];
|
||||||
|
|
||||||
if (_val < _min_f) {
|
_min_f = std::min(_min_f, _val);
|
||||||
_min_f = _val;
|
_max_f = std::max(_max_f, _val);
|
||||||
}
|
|
||||||
|
|
||||||
if (_val > _max_f) {
|
_avg += static_cast<double>(_val);
|
||||||
_max_f = _val;
|
|
||||||
}
|
|
||||||
|
|
||||||
_avg += _val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp critical
|
#pragma omp critical
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if(_min_f < min_f ) {
|
min_f = std::min(min_f, _min_f);
|
||||||
min_f = _min_f;
|
max_f = std::max(max_f, _max_f);
|
||||||
}
|
|
||||||
|
|
||||||
if(_max_f > max_f ) {
|
|
||||||
max_f = _max_f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_avg /= ((H) * (W));
|
_avg /= ((H) * (W));
|
||||||
|
@ -48,8 +48,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
int W, H;
|
int W, H;
|
||||||
|
|
||||||
void fillLuminance( Imagefloat * img, float **luminance, double lumi[3] );
|
|
||||||
void fillLuminanceL( float ** L, float **luminance );
|
|
||||||
void dirpyr_shmap(float ** data_fine, float ** data_coarse, int width, int height, const LUTf& rangefn, int level, int scale);
|
void dirpyr_shmap(float ** data_fine, float ** data_coarse, int width, int height, const LUTf& rangefn, int level, int scale);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -994,7 +994,7 @@ private:
|
|||||||
ipf.rgbProc (baseImg, labView, nullptr, curve1, curve2, curve, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf, as, histToneCurve, options.chunkSizeRGB, options.measure);
|
ipf.rgbProc (baseImg, labView, nullptr, curve1, curve2, curve, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf, as, histToneCurve, options.chunkSizeRGB, options.measure);
|
||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
printf ("Output image / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", autor, autog, autob);
|
printf ("Output image / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", static_cast<double>(autor), static_cast<double>(autog), static_cast<double>(autob));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if clut was used and size of clut cache == 1 we free the memory used by the clutstore (default clut cache size = 1 for 32 bit OS)
|
// if clut was used and size of clut cache == 1 we free the memory used by the clutstore (default clut cache size = 1 for 32 bit OS)
|
||||||
@ -1162,10 +1162,10 @@ private:
|
|||||||
adap = 2000.;
|
adap = 2000.;
|
||||||
}//if no exif data or wrong
|
}//if no exif data or wrong
|
||||||
else {
|
else {
|
||||||
float E_V = fcomp + log2 ((fnum * fnum) / fspeed / (fiso / 100.f));
|
double E_V = fcomp + log2 ((fnum * fnum) / fspeed / (fiso / 100.f));
|
||||||
E_V += params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV
|
E_V += params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV
|
||||||
E_V += log2 (params.raw.expos); // exposure raw white point ; log2 ==> linear to EV
|
E_V += log2(params.raw.expos); // exposure raw white point ; log2 ==> linear to EV
|
||||||
adap = powf (2.f, E_V - 3.f); //cd / m2
|
adap = std::pow(2.0, E_V - 3.0); //cd / m2
|
||||||
}
|
}
|
||||||
|
|
||||||
LUTf CAMBrightCurveJ;
|
LUTf CAMBrightCurveJ;
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -53,7 +53,6 @@ template<class T> T** allocArray (int W, int H)
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HR_SCALE 2
|
|
||||||
StdImageSource::StdImageSource () : ImageSource(), img(nullptr), plistener(nullptr), full(false), max{}, rgbSourceModified(false)
|
StdImageSource::StdImageSource () : ImageSource(), img(nullptr), plistener(nullptr), full(false), max{}, rgbSourceModified(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -308,7 +308,7 @@ float calculateGradients (Array2Df* H, Array2Df* G, int k, bool multithread)
|
|||||||
// however, the impact is not visible so we ignore this here
|
// however, the impact is not visible so we ignore this here
|
||||||
|
|
||||||
(*G) (x, y) = sqrt (gx * gx + gy * gy) / divider;
|
(*G) (x, y) = sqrt (gx * gx + gy * gy) / divider;
|
||||||
avgGrad += (*G) (x, y);
|
avgGrad += static_cast<double>((*G) (x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +381,7 @@ void calculateFiMatrix (Array2Df* FI, Array2Df* gradients[],
|
|||||||
#endif
|
#endif
|
||||||
for ( int y = 0; y < height; y++ ) {
|
for ( int y = 0; y < height; y++ ) {
|
||||||
for ( int x = 0; x < width; x++ ) {
|
for ( int x = 0; x < width; x++ ) {
|
||||||
float grad = ((*gradients[k]) (x, y) < 1e-4f) ? 1e-4 : (*gradients[k]) (x, y);
|
float grad = ((*gradients[k]) (x, y) < 1e-4f) ? 1e-4f : (*gradients[k]) (x, y);
|
||||||
float a = alfa * avgGrad[k];
|
float a = alfa * avgGrad[k];
|
||||||
float value = pow ((grad + noise) / a, beta - 1.0f);
|
float value = pow ((grad + noise) / a, beta - 1.0f);
|
||||||
|
|
||||||
@ -603,8 +603,8 @@ void tmo_fattal02 (size_t width,
|
|||||||
// sets index+1 based on the boundary assumption H(N+1)=H(N-1)
|
// sets index+1 based on the boundary assumption H(N+1)=H(N-1)
|
||||||
unsigned int xp1 = (x + 1 >= width ? width - 2 : x + 1);
|
unsigned int xp1 = (x + 1 >= width ? width - 2 : x + 1);
|
||||||
// forward differences in H, so need to use between-points approx of FI
|
// forward differences in H, so need to use between-points approx of FI
|
||||||
(*Gx) (x, y) = ((*H) (xp1, y) - (*H) (x, y)) * 0.5 * ((*FI) (xp1, y) + (*FI) (x, y));
|
(*Gx) (x, y) = ((*H) (xp1, y) - (*H) (x, y)) * 0.5f * ((*FI) (xp1, y) + (*FI) (x, y));
|
||||||
(*Gy) (x, y) = ((*H) (x, yp1) - (*H) (x, y)) * 0.5 * ((*FI) (x, yp1) + (*FI) (x, y));
|
(*Gy) (x, y) = ((*H) (x, yp1) - (*H) (x, y)) * 0.5f * ((*FI) (x, yp1) + (*FI) (x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -747,7 +747,7 @@ void transform_ev2normal (Array2Df *A, Array2Df *T, bool multithread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int y = 1 ; y < height - 1 ; y++ ) {
|
for (int y = 1 ; y < height - 1 ; y++ ) {
|
||||||
(*A) (0, y) *= 0.5;
|
(*A) (0, y) *= 0.5f;
|
||||||
(*A) (width - 1, y) *= 0.5f;
|
(*A) (width - 1, y) *= 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -912,7 +912,7 @@ void solve_pde_fft (Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread)/*
|
|||||||
|
|
||||||
for (int y = 0 ; y < height ; y++ ) {
|
for (int y = 0 ; y < height ; y++ ) {
|
||||||
for (int x = 0 ; x < width ; x++ ) {
|
for (int x = 0 ; x < width ; x++ ) {
|
||||||
(*F_tr) (x, y) = (*F_tr) (x, y) / (l1[y] + l2[x]);
|
(*F_tr) (x, y) = static_cast<double>((*F_tr) (x, y)) / (l1[y] + l2[x]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include "rt_math.h"
|
#include "rt_math.h"
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "rt_math.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
const double xyz_rgb[3][3] = { // XYZ from RGB
|
const float xyz_rgb[3][3] = { // XYZ from RGB
|
||||||
{ 0.412453, 0.357580, 0.180423 },
|
{ 0.412453, 0.357580, 0.180423 },
|
||||||
{ 0.212671, 0.715160, 0.072169 },
|
{ 0.212671, 0.715160, 0.072169 },
|
||||||
{ 0.019334, 0.119193, 0.950227 }
|
{ 0.019334, 0.119193, 0.950227 }
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#ifndef _CANONATTRIBS_
|
|
||||||
#define _CANONATTRIBS_
|
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -1231,7 +1229,7 @@ public:
|
|||||||
int a = Interpreter::toInt (t, ofs, astype);
|
int a = Interpreter::toInt (t, ofs, astype);
|
||||||
|
|
||||||
if (a > 1) {
|
if (a > 1) {
|
||||||
int i = int (double (powf (2.f, float (a) / 32.f - 4.f)) * 50.f + 0.5f);
|
int i = static_cast<double>(powf (2.f, static_cast<float>(a) / 32.f - 4.f)) * 50.0 + 0.5;
|
||||||
return i;
|
return i;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
@ -2142,5 +2140,4 @@ const TagAttrib canonAttribs[] = {
|
|||||||
{ -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr}
|
{ -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user