diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bab7397a6..e483ace01 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,69 +1,96 @@ name: macOS build - on: - push - + push: + branches: + - dev + - patch** + - newlocallab + pull_request: + branches: + - dev + - newlocallab + release: + types: + - created jobs: build: - - runs-on: macos-latest - + runs-on: macos-10.15 steps: - - uses: actions/checkout@v1 - - name: Install dependencies - run: brew install gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++ little-cms2 libiptcdata fftw lensfun llvm expat pkgconfig libomp shared-mime-info - - name: patch libiconv - run: | - mkdir libiconv && cd libiconv - wget https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.16.tar.gz - tar xf libiconv-1.16.tar.gz - cd libiconv-1.16 - patch -p1 < "${GITHUB_WORKSPACE}/tools/osx/libiconv_1.16_rt.patch" - mkdir build && cd build - destDir="$(pwd)" - ../configure --prefix=/opt/local --disable-static 'CFLAGS=-arch x86_64 -mmacosx-version-min=10.9' 'LDFLAGS=-arch x86_64 -mmacosx-version-min=10.9' CXXFLAGS="-arch x86_64 -mmacosx-version-min=10.9" - make --jobs - make DESTDIR="${destDir}" install - sudo mv opt/local /usr/local/opt/libiconv - - name: cmake - env: - CMAKE_CXX_STANDARD: 11 - PKG_CONFIG_PATH: /usr/local/opt/libffi/lib/pkgconfig:/usr/local/opt/expat/lib/pkgconfig - RAW_THERAPEE_MAJOR: '5' - RAW_THERAPEE_MINOR: '7' - C_FLAGS: -Xpreprocessor -fopenmp /usr/local/lib/libomp.dylib -I/usr/local/include -I/usr/local/opt/gdk-pixbuf/include -I/usr/local/opt/libiconv/include -I/usr/local/opt/libxml2/include -I/usr/local/opt/expat/include -I/usr/local/opt/llvm/include - run: | - # GITHUB_REF is the ref that triggered the build, like refs/heads/new-feature - the next line parses that to REF: the branch name only (new-feature) - REF=${GITHUB_REF##*/} - mkdir build && cd build - cmake \ - -DCMAKE_BUILD_TYPE="release" \ - -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ - -DCMAKE_EXE_LINKER_FLAGS="-L/usr/local/lib -L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib -L/usr/local/opt/gdk-pixbuf/lib -L/usr/local/opt/libiconv/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/libxml2/lib -L/usr/local/opt/expat/lib" \ - -DCACHE_NAME_SUFFIX="${RAW_THERAPEE_MAJOR}.${RAW_THERAPEE_MINOR}-${REF}" \ - -DPROC_TARGET_NUMBER="2" \ - -DPROC_LABEL="generic processor" \ - -DWITH_LTO="OFF" \ - -DLENSFUNDBDIR="./share/lensfun" \ - -DOpenMP_C_FLAGS=-fopenmp=libomp \ - -DOpenMP_CXX_FLAGS=-fopenmp=libomp \ - -DOpenMP_C_LIB_NAMES="libomp" \ - -DOpenMP_CXX_LIB_NAMES="libomp" \ - -DOpenMP_libomp_LIBRARY="/usr/local/lib/libomp.dylib" \ - -DOpenMP_C_FLAGS="${C_FLAGS}" \ - -DOpenMP_CXX_FLAGS="${C_FLAGS}" \ - -DCMAKE_AR="/usr/local/opt/llvm/bin/llvm-ar" \ - -DCMAKE_RANLIB="/usr/local/opt/llvm/bin/llvm-ranlib" \ - .. - make --jobs - make install - sudo make macosx_bundle - ARTIFACT=(RawTherapee*.zip) - echo "=== artifact: ${ARTIFACT}" - # defining environment variables for next step as per https://github.com/actions/starter-workflows/issues/68 - echo "::set-env name=ARTIFACT_PATH::${GITHUB_WORKSPACE}/build/${ARTIFACT}" - echo "::set-env name=ARTIFACT_FILE::${ARTIFACT}" - - uses: actions/upload-artifact@v1 - with: - name: ${{env.ARTIFACT_FILE}} - path: ${{env.ARTIFACT_PATH}} + - uses: actions/checkout@v1 + - name: Install dependencies + run: | + date -u + mkdir build + date +%s > build/stamp + brew uninstall --ignore-dependencies libtiff + brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++ little-cms2 libiptcdata fftw lensfun expat pkgconfig libomp shared-mime-info | tee -a depslog + date -u + echo "----====Pourage====----" + cat depslog | grep Pouring + zsh -c 'echo "Completed installation of dependencies in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' + - name: Configure build system + env: + CMAKE_CXX_STANDARD: 11 + PKG_CONFIG_PATH: /usr/local/opt/libtiff/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig:/usr/local/opt/expat/lib/pkgconfig + RAW_THERAPEE_MAJOR: '5' + RAW_THERAPEE_MINOR: '8' + C_FLAGS: > + -arch x86_64 -mtune=generic -Xpreprocessor -fopenmp /usr/local/lib/libomp.dylib -I/usr/local/include -I/usr/local/opt/gdk-pixbuf/include -I/usr/local/opt/libiconv/include -I/usr/local/opt/libxml2/include -I/usr/local/opt/expat/include -I/usr/local/opt/libtiff/include + run: | + # GITHUB_REF is the ref that triggered the build, like + # refs/heads/new-feature - the next line parses that to REF: the branch + # name only (new-feature) + export REF=${GITHUB_REF##*/} + export C_FLAGS=$(echo -e $C_FLAGS | tr -d '\n') + cd build && date -u && date +%s > configstamp + cmake \ + -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ + -DCMAKE_EXE_LINKER_FLAGS="-L. -L/usr/local/lib -Wl,-rpath -Wl,/usr/local/lib -L/usr/local/opt/gdk-pixbuf/lib -L/usr/local/opt/libiconv/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/libxml2/lib -L/usr/local/opt/expat/lib" \ + -DCACHE_NAME_SUFFIX="${RAW_THERAPEE_MAJOR}.${RAW_THERAPEE_MINOR}-${REF}" \ + -DPROC_TARGET_NUMBER="1" \ + -DPROC_LABEL="generic processor" \ + -DWITH_LTO="OFF" \ + -DLENSFUNDBDIR="/Applications/RawTherapee.app/Contents/Resources/share/lensfun" \ + -DCMAKE_C_COMPILER=/usr/local/opt/llvm/bin/clang \ + -DCMAKE_CXX_COMPILER=/usr/local/opt/llvm/bin/clang++ \ + -DCMAKE_C_FLAGS="-arch x86_64 -Wno-pass-failed -Wno-deprecated-register -Wno-unused-command-line-argument" \ + -DCMAKE_CXX_FLAGS="-arch x86_64 -Wno-pass-failed -Wno-deprecated-register -Wno-unused-command-line-argument" \ + -DOpenMP_C_FLAGS="${C_FLAGS}" \ + -DOpenMP_CXX_FLAGS="${C_FLAGS}" \ + -DOpenMP_C_LIB_NAMES=libomp \ + -DOpenMP_CXX_LIB_NAMES=libomp \ + -DOpenMP_libomp_LIBRARY=/usr/local/lib/libomp.dylib \ + -DCMAKE_AR=/usr/bin/ar \ + -DCMAKE_RANLIB=/usr/bin/ranlib \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 \ + .. + zsh -c 'echo "Configured in $(printf "%0.2f" $(($[$(date +%s)-$(cat configstamp)]/$((60.))))) minutes"' + - name: Compile RawTherapee + run: | + date -u && date +%s > build/compilestamp + cd build + export REF=${GITHUB_REF##*/} + make -j$(sysctl -a | grep machdep.cpu.thread_count | tail -c 2) install + zsh -c 'echo "Compiled in $(printf "%0.2f" $(($[$(date +%s)-$(cat compilestamp)]/$((60.))))) minutes"' + - name: Create application bundle + run: | + zsh + date +%s > build/bundlestamp && date -u && cd build + export REF=${GITHUB_REF##*/} && export LOCAL_PREFIX=/usr && sudo make macosx_bundle + export ARTIFACT=(RawTherapee*.zip) + echo "=== artifact: ${ARTIFACT}" + # defining environment variables for next step as per + # https://github.com/actions/starter-workflows/issues/68 + echo "::set-env name=ARTIFACT_PATH::${GITHUB_WORKSPACE}/build/${ARTIFACT}" + echo "::set-env name=ARTIFACT_FILE::${ARTIFACT}" + zsh -c 'echo "Bundled in $(printf "%0.2f" $(($[$(date +%s)-$(cat bundlestamp)]/$((60.))))) minutes"' + exit + - uses: actions/upload-artifact@v1 + with: + name: ${{env.ARTIFACT_FILE}} + path: ${{env.ARTIFACT_PATH}} + - name: Finish build + run: | + date -u + zsh -c 'echo "Build completed in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' diff --git a/AboutThisBuild.txt.in b/AboutThisBuild.txt.in index f48d39b50..4d8f4f3fe 100644 --- a/AboutThisBuild.txt.in +++ b/AboutThisBuild.txt.in @@ -13,3 +13,7 @@ Build flags: ${CXX_FLAGS} Link flags: ${LFLAGS} OpenMP support: ${OPTION_OMP} MMAP support: ${WITH_MYFILE_MMAP} +Build OS: ${BUILDINFO_OS} +Build date: ${BUILDINFO_DATE} UTC +Build epoch: ${BUILDINFO_EPOCH} +Build UUID: ${BUILDINFO_UUID} diff --git a/CMakeLists.txt b/CMakeLists.txt index 13c648de0..e3ae3b7ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,23 +1,34 @@ -cmake_minimum_required(VERSION 3.5) +# Use of SOURCE_DIR target property begins at cmake 3.7 +if(APPLE) + cmake_minimum_required(VERSION 3.7) +else() + cmake_minimum_required(VERSION 3.5) +endif() # Compiler id for Apple Clang if(APPLE) cmake_policy(SET CMP0025 NEW) + cmake_policy(SET CMP0037 NEW) endif() # Must stay before the project() command: if(${CMAKE_EXTRA_GENERATOR} MATCHES "Eclipse CDT4") - set(CMAKE_CXX_COMPILER_ARG1 "-std=c++11" CACHE STRING "C++ version for eclipse" FORCE) + set(CMAKE_CXX_COMPILER_ARG1 + "-std=c++11" + CACHE STRING "C++ version for eclipse" FORCE) # Users building with Eclipse should set CMAKE_ECLIPSE_VERSION through the # command line to their current version of Eclipse: - #set(CMAKE_ECLIPSE_VERSION "4.6.0" CACHE STRING "Eclipse version" FORCE) + # set(CMAKE_ECLIPSE_VERSION "4.6.0" CACHE STRING "Eclipse version" FORCE) endif() project(RawTherapee) # The default target is Debug: if(CMAKE_BUILD_TYPE STREQUAL "") - set(CMAKE_BUILD_TYPE Debug CACHE STRING "One of: None Debug Release RelWithDebInfo MinSizeRel" FORCE) + set(CMAKE_BUILD_TYPE + Debug + CACHE STRING "One of: None Debug Release RelWithDebInfo MinSizeRel" + FORCE) endif() string(TOUPPER ${CMAKE_BUILD_TYPE} UPPER_CMAKE_BUILD_TYPE) @@ -26,11 +37,15 @@ string(TOUPPER ${CMAKE_BUILD_TYPE} UPPER_CMAKE_BUILD_TYPE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9") - message(FATAL_ERROR "Building RawTherapee requires using GCC version 4.9 or higher!") +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION + VERSION_LESS "4.9") + message( + FATAL_ERROR + "Building RawTherapee requires using GCC version 4.9 or higher!") endif() -# We might want to build using the old C++ ABI, even when using a new GCC version: +# We might want to build using the old C++ ABI, even when using a new GCC +# version: if(USE_OLD_CXX_ABI) add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) endif() @@ -46,30 +61,50 @@ message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/") -# Cache name suffix examples: "" = ~/.config/RawTherapee, "5" = ~/.config/RawTherapee-5, "_testing" = ~/.config/RawTherapee_testing -# Use "" for stable releases and "5-dev" for anything else. -set(CACHE_NAME_SUFFIX "" CACHE STRING "RawTherapee's cache folder suffix") +# Cache name suffix examples: "" = ~/.config/RawTherapee, "5" = +# ~/.config/RawTherapee-5, "_testing" = ~/.config/RawTherapee_testing Use "" for +# stable releases and "5-dev" for anything else. +set(CACHE_NAME_SUFFIX + "" + CACHE STRING "RawTherapee's cache folder suffix") -# By default we don't use a specific processor target, so PROC_TARGET_NUMBER is set to 0. -# Specify other values to optimize for specific processor architecture as listed in ProcessorTargets.cmake: -set(PROC_TARGET_NUMBER 0 CACHE STRING "Selected target processor from the list above (taken from ProcessorTargets.cmake)") +# By default we don't use a specific processor target, so PROC_TARGET_NUMBER is +# set to 0. Specify other values to optimize for specific processor architecture +# as listed in ProcessorTargets.cmake: +set(PROC_TARGET_NUMBER + 0 + CACHE + STRING + "Selected target processor from the list above (taken from ProcessorTargets.cmake)" +) # Set special compilation flags for rtengine which get added to CMAKE_CXX_FLAGS: -# Some Linux distros build with -O2 instead of -O3. We explicitly enable auto vectorization by using -ftree-vectorize -set(RTENGINE_CXX_FLAGS "-ftree-vectorize" CACHE STRING "Special compilation flags for RTEngine") +# Some Linux distros build with -O2 instead of -O3. We explicitly enable auto +# vectorization by using -ftree-vectorize +set(RTENGINE_CXX_FLAGS + "-ftree-vectorize" + CACHE STRING "Special compilation flags for RTEngine") # Loads the ProcessorTargets list: include(ProcessorTargets.cmake) -set(PROC_LABEL "undefined" CACHE STRING "Target processor label, unused if PROC_TARGET_NUMBER = 0 or 2") -set(PROC_FLAGS "" CACHE STRING "Target processor related build/link flags") +set(PROC_LABEL + "undefined" + CACHE STRING + "Target processor label, unused if PROC_TARGET_NUMBER = 0 or 2") +set(PROC_FLAGS + "" + CACHE STRING "Target processor related build/link flags") if((NOT (PROC_TARGET_NUMBER EQUAL 0)) AND (NOT (PROC_TARGET_NUMBER EQUAL 2))) set(PROC_LABEL ${PROC_TARGET_${PROC_TARGET_NUMBER}_LABEL}) endif() -if(NOT(PROC_TARGET_NUMBER EQUAL 0)) +if(NOT (PROC_TARGET_NUMBER EQUAL 0)) set(PROC_FLAGS ${PROC_TARGET_${PROC_TARGET_NUMBER}_FLAGS}) endif() if(UNIX AND PROC_LABEL STREQUAL "undefined") - execute_process(COMMAND uname -p OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE cpu) + execute_process( + COMMAND uname -p + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE cpu) if("${cpu}" STREQUAL "unknown") set(PROC_LABEL "${CMAKE_SYSTEM_PROCESSOR}") else() @@ -77,7 +112,8 @@ if(UNIX AND PROC_LABEL STREQUAL "undefined") endif() endif() -# If PROC_FORCED_LABEL exists, its value is loaded in PROC_LABEL to override the one from ProcessorTargets: +# If PROC_FORCED_LABEL exists, its value is loaded in PROC_LABEL to override the +# one from ProcessorTargets: if(DEFINED PROC_FORCED_LABEL) set(PROC_LABEL ${PROC_FORCED_LABEL}) endif() @@ -87,7 +123,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PROC_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PROC_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PROC_FLAGS}") -# Stop compilation on typos such as std:swap (missing colon will be detected as unused label): +# Stop compilation on typos such as std:swap (missing colon will be detected as +# unused label): set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=unused-label") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=delete-incomplete") @@ -106,21 +143,35 @@ endif() include(FindUnalignedMalloc) if(WIN32) - # Add additional paths. Look in the MinGW path first, then in the Gtkmm path. - # If you wish to build some dependent libraries, you have to install them in MinGW to use them: - set(CMAKE_PREFIX_PATH $ENV{MINGW_BASEPATH} $ENV{GTKMM_BASEPATH} CACHE STRING "Additional search paths") + # Add additional paths. Look in the MinGW path first, then in the Gtkmm + # path. If you wish to build some dependent libraries, you have to install + # them in MinGW to use them: + set(CMAKE_PREFIX_PATH + $ENV{MINGW_BASEPATH} $ENV{GTKMM_BASEPATH} + CACHE STRING "Additional search paths") endif() -if(APPLE) - if(CMAKE_CXX_COMPILER MATCHES "g\\+\\+-mp-4.[5-8]" OR CMAKE_CXX_COMPILER_ARG1 MATCHES "g\\+\\+-mp-4.[5-8]") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /usr/lib/libstdc++.6.dylib") - message(STATUS "CMAKE_CXX_COMPILER is MacPorts GCC.\n CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") +if(APPLE) # TODO make -mtune generic conditional and/or specifiable. + if(CMAKE_CXX_COMPILER MATCHES "g\\+\\+-mp-4.[5-8]" + OR CMAKE_CXX_COMPILER_ARG1 MATCHES "g\\+\\+-mp-4.[5-8]") + set(CMAKE_EXE_LINKER_FLAGS + "${CMAKE_EXE_LINKER_FLAGS} /usr/lib/libstdc++.6.dylib -Wl,-headerpad_max_install_names -mtune=generic" + ) + message( + STATUS + "CMAKE_CXX_COMPILER is MacPorts GCC.\n CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}" + ) endif() # Set minimum system version - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.9") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.9") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -headerpad_max_install_names") + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}" + ) + set(CMAKE_C_FLAGS + "${CMAKE_C_FLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + set(CMAKE_EXE_LINKER_FLAGS + "${CMAKE_EXE_LINKER_FLAGS} -Wl,-headerpad_max_install_names -mtune=generic" + ) endif() option(USE_EXPERIMENTAL_LANG_VERSIONS "Build with -std=c++0x" OFF) @@ -132,33 +183,53 @@ option(WITH_SAN "Build with run-time sanitizer" OFF) option(WITH_PROF "Build with profiling instrumentation" OFF) option(WITH_SYSTEM_KLT "Build using system KLT library." OFF) option(OPTION_OMP "Build with OpenMP support" ON) -option(STRICT_MUTEX "True (recommended): MyMutex will behave like POSIX Mutex; False: MyMutex will behave like POSIX RecMutex; Note: forced to ON for Debug builds" ON) -option(TRACE_MYRWMUTEX "Trace custom R/W Mutex (Debug builds only); redirecting std::out to a file is strongly recommended!" OFF) -option(AUTO_GDK_FLUSH "Use gdk_flush on all gdk_thread_leave other than the GUI thread; set it ON if you experience X Server warning/errors" OFF) -#option(TARGET32BIT "Build for 32-bit architecture when ON, otherwise 64-bit. Default is OFF" OFF) +option( + STRICT_MUTEX + "True (recommended): MyMutex will behave like POSIX Mutex; False: MyMutex will behave like POSIX RecMutex; Note: forced to ON for Debug builds" + ON) +option( + TRACE_MYRWMUTEX + "Trace custom R/W Mutex (Debug builds only); redirecting std::out to a file is strongly recommended!" + OFF) +option( + AUTO_GDK_FLUSH + "Use gdk_flush on all gdk_thread_leave other than the GUI thread; set it ON if you experience X Server warning/errors" + OFF) +# option(TARGET32BIT "Build for 32-bit architecture when ON, otherwise 64-bit. +# Default is OFF" OFF) option(ENABLE_TCMALLOC "Use the tcmalloc library if available" OFF) -set(TCMALLOC_LIB_DIR "" CACHE PATH "Custom path for the tcmalloc library") +set(TCMALLOC_LIB_DIR + "" + CACHE PATH "Custom path for the tcmalloc library") # Set installation directories: if(WIN32 OR APPLE) if(BUILD_BUNDLE) - message(STATUS "You have set BUILD_BUNDLE=ON but this is not necessary - the option is forced to ON for Windows and macOS.") + message( + STATUS + "You have set BUILD_BUNDLE=ON but this is not necessary - the option is forced to ON for Windows and macOS." + ) endif() set(BUILD_BUNDLE ON FORCE) endif() if(NOT DEFINED BUNDLE_BASE_INSTALL_DIR) if(APPLE) - set(BUNDLE_BASE_INSTALL_DIR "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/MacOS") + set(BUNDLE_BASE_INSTALL_DIR "${PROJECT_SOURCE_DIR}/build/${CMAKE_BUILD_TYPE}/MacOS") else() set(BUNDLE_BASE_INSTALL_DIR "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}") endif() endif() if(BUILD_BUNDLE) - set(BINDIR .) - set(CMAKE_INSTALL_PREFIX "${BUNDLE_BASE_INSTALL_DIR}") + if(APPLE) + set(BINDIR "${BUNDLE_BASE_INSTALL_DIR}") + set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/build") + else() + set(BINDIR .) + set(CMAKE_INSTALL_PREFIX "${BUNDLE_BASE_INSTALL_DIR}") + endif() endif() if(NOT DEFINED BINDIR) @@ -168,7 +239,7 @@ endif() if(NOT DEFINED DATADIR) if(BUILD_BUNDLE) if(APPLE) - set(DATADIR "../../Resources") + set(DATADIR "${PROJECT_SOURCE_DIR}/build/${CMAKE_BUILD_TYPE}/Resources/share") else() set(DATADIR .) endif() @@ -180,7 +251,7 @@ endif() if(NOT DEFINED LIBDIR) if(BUILD_BUNDLE) if(APPLE) - set(LIBDIR "../../Frameworks") + set(LIBDIR "${PROJECT_SOURCE_DIR}/build/${CMAKE_BUILD_TYPE}/Frameworks") else() set(LIBDIR .) endif() @@ -200,7 +271,11 @@ endif() if(NOT DEFINED DOCDIR) if(BUILD_BUNDLE) - set(DOCDIR "${DATADIR}/share/doc") + if(APPLE) + set(DOCDIR "${DATADIR}/doc") + else() + set(DOCDIR "${DATADIR}/share/doc") + endif() else() set(DOCDIR "${CMAKE_INSTALL_PREFIX}/share/doc/rawtherapee") endif() @@ -208,7 +283,11 @@ endif() if(NOT DEFINED CREDITSDIR) if(BUILD_BUNDLE) - set(CREDITSDIR "${DATADIR}") + if(APPLE) + set(CREDITSDIR "${DATADIR}") + else() + set(CREDITSDIR "${DATADIR}") + endif() else() set(CREDITSDIR "${CMAKE_INSTALL_PREFIX}/share/doc/rawtherapee") endif() @@ -216,7 +295,11 @@ endif() if(NOT DEFINED LICENCEDIR) if(BUILD_BUNDLE) - set(LICENCEDIR "${DATADIR}") + if(APPLE) + set(LICENCEDIR "${CREDITSDIR}") + else() + set(LICENCEDIR "${DATADIR}") + endif() else() set(LICENCEDIR "${CMAKE_INSTALL_PREFIX}/share/doc/rawtherapee") endif() @@ -225,7 +308,11 @@ endif() if(NOT DEFINED DESKTOPDIR) if(UNIX) if(BUILD_BUNDLE) - set(DESKTOPDIR "${DATADIR}/share/applications") + if(APPLE) + set(DESKTOPDIR "${DATADIR}/applications") + else() + set(DESKTOPDIR "${DATADIR}/share/applications") + endif() else() set(DESKTOPDIR "${CMAKE_INSTALL_PREFIX}/share/applications") endif() @@ -235,7 +322,11 @@ endif() if(NOT DEFINED ICONSDIR) if(UNIX) if(BUILD_BUNDLE) - set(ICONSDIR "${DATADIR}/share/icons") + if(APPLE) + set(ICONSDIR "${DATADIR}/icons") + else() + set(ICONSDIR "${DATADIR}/share/icons") + endif() else() set(ICONSDIR "${CMAKE_INSTALL_PREFIX}/share/icons") endif() @@ -245,30 +336,48 @@ endif() if(NOT DEFINED APPDATADIR) if(UNIX) if(BUILD_BUNDLE) - set(APPDATADIR "${DATADIR}/share/metainfo") + if(APPLE) + set(APPDATADIR "${DATADIR}/metainfo") + else() + set(APPDATADIR "${DATADIR}/share/metainfo") + endif() else() set(APPDATADIR "${CMAKE_INSTALL_PREFIX}/share/metainfo") endif() endif() endif() -if (NOT APPLE) - if(DEFINED LENSFUNDBDIR AND NOT IS_ABSOLUTE "${LENSFUNDBDIR}") - set(LENSFUNDBDIR "${DATADIR}/${LENSFUNDBDIR}") +if(NOT APPLE) + if(DEFINED LENSFUNDBDIR AND NOT IS_ABSOLUTE "${LENSFUNDBDIR}") + set(LENSFUNDBDIR "${DATADIR}/${LENSFUNDBDIR}") endif() endif() if(APPLE) if("${CODESIGNID}") - set(CODESIGNID "${CODESIGNID}" CACHE STRING "Codesigning Identity") + set(CODESIGNID + "${CODESIGNID}" + CACHE STRING "Codesigning Identity") endif() if("${NOTARY}") - set(NOTARY "${NOTARY}" CACHE STRING "Notarization Identity") + set(NOTARY + "${NOTARY}" + CACHE STRING "Notarization Identity") endif() if("${LOCAL_PREFIX}") - set(LOCAL_PREFIX "${LOCAL_PREFIX}" CACHE STRING "macos/gtk parent directory ie /usr or /opt") - elseif(NOT DEFINED LOCAL_PREFIX) - set(LOCAL_PREFIX "/usr") + set(LOCAL_PREFIX + "${LOCAL_PREFIX}" + CACHE STRING "macos/gtk parent directory ie /usr or /opt") + else() + set(LOCAL_PREFIX + /usr + CACHE STRING "macos/gtk parent directory ie /usr or /opt") + endif() + if("${FANCY_DMG}") + set(FANCY_DMG + ON + CACHE BOOL + "Use the andreyvit/create-dmg script to make a fancy .dmg") endif() endif() @@ -276,7 +385,10 @@ endif() if(NOT BUILD_BUNDLE) foreach(path BINDIR DATADIR LIBDIR DOCDIR CREDITSDIR LICENCEDIR) if(NOT (IS_ABSOLUTE "${${path}}")) - message(FATAL_ERROR "The ${path} path has to be absolute when using -DBUILD_BUNDLE=OFF") + message( + FATAL_ERROR + "The ${path} path has to be absolute when using -DBUILD_BUNDLE=OFF" + ) endif() endforeach() endif() @@ -305,11 +417,11 @@ endif() find_package(PkgConfig) if(WIN32) - pkg_check_modules (GTK REQUIRED gtk+-3.0>=3.22.24) - pkg_check_modules (GTKMM REQUIRED gtkmm-3.0>=3.22) + pkg_check_modules(GTK REQUIRED gtk+-3.0>=3.22.24) + pkg_check_modules(GTKMM REQUIRED gtkmm-3.0>=3.22) else() - pkg_check_modules (GTK REQUIRED gtk+-3.0>=3.16) - pkg_check_modules (GTKMM REQUIRED gtkmm-3.0>=3.16) + pkg_check_modules(GTK REQUIRED gtk+-3.0>=3.16) + pkg_check_modules(GTKMM REQUIRED gtkmm-3.0>=3.16) endif() if(GTK_VERSION VERSION_GREATER "3.24.1" AND GTK_VERSION VERSION_LESS "3.24.7") @@ -318,19 +430,26 @@ if(GTK_VERSION VERSION_GREATER "3.24.1" AND GTK_VERSION VERSION_LESS "3.24.7") else() set(CERTAINTY "likely to") endif() - message(WARNING "\nWarning! You are using GTK+ version " ${GTK_VERSION} " which is " ${CERTAINTY} " have an issue where combobox menu scroll-arrows are missing when a Gtk::ComboBox list does not fit vertically on the screen. As a result, users of your build will not be able to select items in the following comboboxes: Processing Profiles, Film Simulation, and the camera and lens profiles in Profiled Lens Correction.\nIt is recommended that you either downgrade GTK+ to <= 3.24.1 or upgrade to >= 3.24.7.") + message( + WARNING + "\nWarning! You are using GTK+ version " + ${GTK_VERSION} + " which is " + ${CERTAINTY} + " have an issue where combobox menu scroll-arrows are missing when a Gtk::ComboBox list does not fit vertically on the screen. As a result, users of your build will not be able to select items in the following comboboxes: Processing Profiles, Film Simulation, and the camera and lens profiles in Profiled Lens Correction.\nIt is recommended that you either downgrade GTK+ to <= 3.24.1 or upgrade to >= 3.24.7." + ) endif() -pkg_check_modules (GLIB2 REQUIRED glib-2.0>=2.44) -pkg_check_modules (GLIBMM REQUIRED glibmm-2.4>=2.44) -pkg_check_modules (CAIROMM REQUIRED cairomm-1.0) -pkg_check_modules (GIO REQUIRED gio-2.0>=2.44) -pkg_check_modules (GIOMM REQUIRED giomm-2.4>=2.44) -pkg_check_modules (GTHREAD REQUIRED gthread-2.0>=2.44) -pkg_check_modules (GOBJECT REQUIRED gobject-2.0>=2.44) -pkg_check_modules (SIGC REQUIRED sigc++-2.0>=2.3.1) -pkg_check_modules (LENSFUN REQUIRED lensfun>=0.2) -pkg_check_modules (RSVG REQUIRED librsvg-2.0>=2.40) +pkg_check_modules(GLIB2 REQUIRED glib-2.0>=2.44) +pkg_check_modules(GLIBMM REQUIRED glibmm-2.4>=2.44) +pkg_check_modules(CAIROMM REQUIRED cairomm-1.0) +pkg_check_modules(GIO REQUIRED gio-2.0>=2.44) +pkg_check_modules(GIOMM REQUIRED giomm-2.4>=2.44) +pkg_check_modules(GTHREAD REQUIRED gthread-2.0>=2.44) +pkg_check_modules(GOBJECT REQUIRED gobject-2.0>=2.44) +pkg_check_modules(SIGC REQUIRED sigc++-2.0>=2.3.1) +pkg_check_modules(LENSFUN REQUIRED lensfun>=0.2) +pkg_check_modules(RSVG REQUIRED librsvg-2.0>=2.40) if(WIN32) add_definitions(-DWIN32) @@ -357,7 +476,7 @@ if(WITH_SYSTEM_KLT) endif() # Check for libcanberra-gtk3 (sound events on Linux): -if(UNIX AND(NOT APPLE)) +if(UNIX AND (NOT APPLE)) pkg_check_modules(CANBERRA-GTK REQUIRED libcanberra-gtk3) endif() @@ -368,9 +487,12 @@ endif() if(WITH_LTO) # Using LTO with older versions of binutils requires setting extra flags set(BINUTILS_VERSION_MININUM "2.29") - execute_process(COMMAND ar --version OUTPUT_VARIABLE BINUTILS_VERSION_DETECTED) - string(REGEX REPLACE ".* ([0-9.]+)\n.*" "\\1" BINUTILS_VERSION_DETECTED "${BINUTILS_VERSION_DETECTED}") - if("${BINUTILS_VERSION_DETECTED}" VERSION_LESS "${BINUTILS_VERSION_MININUM}") + execute_process(COMMAND ar --version + OUTPUT_VARIABLE BINUTILS_VERSION_DETECTED) + string(REGEX REPLACE ".* ([0-9.]+)\n.*" "\\1" BINUTILS_VERSION_DETECTED + "${BINUTILS_VERSION_DETECTED}") + if("${BINUTILS_VERSION_DETECTED}" VERSION_LESS + "${BINUTILS_VERSION_MININUM}") if(APPLE) if(!CMAKE_AR) set(CMAKE_AR "/opt/local/bin/ar") @@ -382,7 +504,15 @@ if(WITH_LTO) set(CMAKE_AR "/usr/bin/gcc-ar") set(CMAKE_RANLIB "/usr/bin/gcc-ranlib") endif() - message(STATUS "Binutils version detected as less than " ${BINUTILS_VERSION_MININUM} " - setting CMake parameters to enable LTO linking:\n CMAKE_AR=\"" ${CMAKE_AR} "\"\n CMAKE_RANLIB=\"" ${CMAKE_RANLIB} "\"") + message( + STATUS + "Binutils version detected as less than " + ${BINUTILS_VERSION_MININUM} + " - setting CMake parameters to enable LTO linking:\n CMAKE_AR=\"" + ${CMAKE_AR} + "\"\n CMAKE_RANLIB=\"" + ${CMAKE_RANLIB} + "\"") endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto") @@ -393,7 +523,8 @@ endif() if(WITH_SAN) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=${WITH_SAN}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=${WITH_SAN}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=${WITH_SAN}") + set(CMAKE_EXE_LINKER_FLAGS + "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=${WITH_SAN}") endif() if(WITH_PROF) @@ -402,11 +533,14 @@ if(WITH_PROF) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg") endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wuninitialized -Wcast-qual -Wno-deprecated-declarations -Wno-unused-result -Wunused-macros") +set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -Wall -Wuninitialized -Wcast-qual -Wno-deprecated-declarations -Wno-unused-result -Wunused-macros" +) if(OPTION_OMP) find_package(OpenMP) if(OPENMP_FOUND) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} -Werror=unknown-pragmas") + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} -Werror=unknown-pragmas") endif() endif() @@ -420,13 +554,14 @@ if(OPENMP_FOUND) set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${_f}) endforeach() check_c_source_compiles( -"#include + "#include int main() { fftwf_init_threads(); fftwf_plan_with_nthreads(1); return 0; -}" _fftw3f_multithread) +}" + _fftw3f_multithread) if(_fftw3f_multithread) add_definitions(-DRT_FFTW3F_OMP) else() @@ -444,30 +579,41 @@ get_filename_component(ABS_BINARY_DIR "${CMAKE_BINARY_DIR}" ABSOLUTE) set(OUT_OF_SOURCE_BUILD TRUE) if(ABS_SOURCE_DIR STREQUAL ABS_BINARY_DIR) set(OUT_OF_SOURCE_BUILD FALSE) - message(WARNING "You are performing an in-source build. This is discouraged. For an explanation and the advantages of out-of-source builds, please refer to http://www.cmake.org/Wiki/CMake_FAQ#What_is_an_.22out-of-source.22_build.3F") + message( + WARNING + "You are performing an in-source build. This is discouraged. For an explanation and the advantages of out-of-source builds, please refer to http://www.cmake.org/Wiki/CMake_FAQ#What_is_an_.22out-of-source.22_build.3F" + ) endif() -# Remove files which could require manual work. -# We will remove this after some time to have a clean build system without file modifications in the source tree again. (?) -set(OOSB_FILES "${PROJECT_SOURCE_DIR}/rtdata/rawtherapee.desktop" "${PROJECT_SOURCE_DIR}/rtgui/version.h" "${PROJECT_SOURCE_DIR}/rtgui/config.h" "${PROJECT_SOURCE_DIR}/AboutThisBuild.txt") +# Remove files which could require manual work. We will remove this after some +# time to have a clean build system without file modifications in the source +# tree again. (?) +set(OOSB_FILES + "${PROJECT_SOURCE_DIR}/rtdata/rawtherapee.desktop" + "${PROJECT_SOURCE_DIR}/rtgui/version.h" + "${PROJECT_SOURCE_DIR}/rtgui/config.h" + "${PROJECT_SOURCE_DIR}/AboutThisBuild.txt") if(OUT_OF_SOURCE_BUILD) foreach(f ${OOSB_FILES}) file(REMOVE "${f}") endforeach() endif() -# Check for generated files in the source tree which should not be there when doing an out-of-source build. -# Without checking for this it might happen that old versions are used for the compilation: +# Check for generated files in the source tree which should not be there when +# doing an out-of-source build. Without checking for this it might happen that +# old versions are used for the compilation: if(OUT_OF_SOURCE_BUILD) foreach(f ${OOSB_FILES}) if(EXISTS "${f}") - message(SEND_ERROR "Generated \"${f}\" found inside the source tree. Please remove it as it is a relic of the old build system and prevents valid compilation now.") + message( + SEND_ERROR + "Generated \"${f}\" found inside the source tree. Please remove it as it is a relic of the old build system and prevents valid compilation now." + ) endif() endforeach() endif() -### Start generating AboutThisBuild.txt -# Set the platform bit-depth: +# Start generating AboutThisBuild.txt Set the platform bit-depth: if(CMAKE_SIZEOF_VOID_P EQUAL 4) set(PROC_BIT_DEPTH 32 bits) else() @@ -475,68 +621,91 @@ else() endif() # Get compiler name and version. -# Only CMake > 2.8.7 knows CMAKE_*_COMPILER_VERSION -if(CMAKE_VERSION VERSION_GREATER 2.8.7) get_filename_component(COMPILER_INFO ${CMAKE_C_COMPILER} NAME_WE) set(COMPILER_INFO "${COMPILER_INFO} ${CMAKE_C_COMPILER_VERSION}") -else() - execute_process(COMMAND gcc -dumpversion OUTPUT_VARIABLE GCC_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) +if(NOT APPLE) + execute_process( + COMMAND gcc -dumpversion + OUTPUT_VARIABLE GCC_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) set(COMPILER_INFO "gcc ${GCC_VERSION}") endif() -# Get C++ and linker flags for rtengine (the GUI's C++ flags may have fewer flags): -set(CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${UPPER_CMAKE_BUILD_TYPE}} ${RTENGINE_CXX_FLAGS}") -set(LFLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_${UPPER_CMAKE_BUILD_TYPE}}") +# Get C++ and linker flags for rtengine (the GUI's C++ flags may have fewer +# flags): +set(CXX_FLAGS + "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${UPPER_CMAKE_BUILD_TYPE}} ${RTENGINE_CXX_FLAGS}" +) +set(LFLAGS + "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_${UPPER_CMAKE_BUILD_TYPE}}" +) -set(ABOUT_COMMAND_WITH_ARGS ${CMAKE_COMMAND} - -DPROJECT_SOURCE_DIR:STRING=${PROJECT_SOURCE_DIR} - -DCACHE_NAME_SUFFIX:STRING=${CACHE_NAME_SUFFIX} - -DPROC_LABEL:STRING="${PROC_LABEL}" - -DPROC_BIT_DEPTH:STRING="${PROC_BIT_DEPTH}" - -DBUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - -DGTKMM_VERSION:STRING=${GTKMM_VERSION} - -DOPTION_OMP:STRING=${OPTION_OMP} - -DWITH_MYFILE_MMAP:STRING=${WITH_MYFILE_MMAP} - -DLENSFUN_VERSION:STRING=${LENSFUN_VERSION}) +if(NOT APPLE) + set(ABOUT_COMMAND_WITH_ARGS + ${CMAKE_COMMAND} -DPROJECT_SOURCE_DIR:STRING=${PROJECT_SOURCE_DIR} + -DCACHE_NAME_SUFFIX:STRING=${CACHE_NAME_SUFFIX} + -DPROC_LABEL:STRING="${PROC_LABEL}" + -DPROC_BIT_DEPTH:STRING="${PROC_BIT_DEPTH}" + -DBUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DGTKMM_VERSION:STRING=${GTKMM_VERSION} + -DOPTION_OMP:STRING=${OPTION_OMP} + -DWITH_MYFILE_MMAP:STRING=${WITH_MYFILE_MMAP} + -DLENSFUN_VERSION:STRING=${LENSFUN_VERSION}) +endif() if(WIN32) - list(APPEND ABOUT_COMMAND_WITH_ARGS -DSYSTEM:STRING=Windows + list( + APPEND + ABOUT_COMMAND_WITH_ARGS + -DSYSTEM:STRING=Windows -DCXX_FLAGS:STRING="${CXX_FLAGS}" -DLFLAGS:STRING="${LFLAGS}" -DCOMPILER_INFO:STRING="${COMPILER_INFO}" -DCMAKE_INSTALL_PREFIX:STRING="${CMAKE_INSTALL_PREFIX}" -DBIT_DEPTH:STRING="${CMAKE_SIZEOF_VOID_P}") elseif(APPLE) - list(APPEND ABOUT_COMMAND_WITH_ARGS -DSYSTEM:STRING=Apple - -DCXX_FLAGS:STRING=${CXX_FLAGS} - -DLFLAGS:STRING=${LFLAGS} - -DCOMPILER_INFO:STRING=${COMPILER_INFO}) + set( + ABOUT_COMMAND_WITH_ARGS + cmake -DPROJECT_SOURCE_DIR:STRING=${PROJECT_SOURCE_DIR} -P ${PROJECT_SOURCE_DIR}/UpdateInfo.cmake -DSYSTEM:STRING=Apple -DCXX_FLAGS:STRING=${CXX_FLAGS} -DLFLAGS:STRING=${LFLAGS} -DCOMPILER_INFO:STRING=${COMPILER_INFO} -DCACHE_NAME_SUFFIX:STRING=${CACHE_NAME_SUFFIX}) else() list(APPEND ABOUT_COMMAND_WITH_ARGS -DSYSTEM:STRING=Linux - -DCXX_FLAGS:STRING=${CXX_FLAGS} - -DLFLAGS:STRING=${LFLAGS} - -DCOMPILER_INFO:STRING=${COMPILER_INFO}) + -DCXX_FLAGS:STRING=${CXX_FLAGS} -DLFLAGS:STRING=${LFLAGS} + -DCOMPILER_INFO:STRING=${COMPILER_INFO}) +endif() +if(NOT APPLE) + list(APPEND + ABOUT_COMMAND_WITH_ARGS + -P "${PROJECT_SOURCE_DIR}/UpdateInfo.cmake") endif() -list(APPEND ABOUT_COMMAND_WITH_ARGS -P "${PROJECT_SOURCE_DIR}/UpdateInfo.cmake") - -add_custom_target(UpdateInfo ALL +add_custom_target( + UpdateInfo ALL COMMAND ${ABOUT_COMMAND_WITH_ARGS} COMMENT "Creating AboutThisBuild.txt and other version-dependent files") -### End generating AboutThisBuild.txt +# End generating AboutThisBuild.txt install(FILES AUTHORS.txt DESTINATION "${CREDITSDIR}") install(FILES LICENSE.txt DESTINATION "${LICENCEDIR}") -install(FILES "${CMAKE_BINARY_DIR}/AboutThisBuild.txt" DESTINATION "${CREDITSDIR}") -install(FILES RELEASE_NOTES.txt DESTINATION "${CREDITSDIR}" OPTIONAL) +install(FILES "${CMAKE_BINARY_DIR}/AboutThisBuild.txt" + DESTINATION "${CREDITSDIR}") +install( + FILES RELEASE_NOTES.txt + DESTINATION "${CREDITSDIR}" + OPTIONAL) -# The standard location for man pages in Linux is /usr/share/man -# Use "manpath" to see the search paths for man pages on your system. +# The standard location for man pages in Linux is /usr/share/man Use "manpath" +# to see the search paths for man pages on your system. if(BUILD_BUNDLE) - install(FILES "${PROJECT_SOURCE_DIR}/doc/manpage/rawtherapee.1" DESTINATION "${DATADIR}/share/man/man1") + if(APPLE) + install(FILES "${PROJECT_SOURCE_DIR}/doc/manpage/rawtherapee.1" + DESTINATION "${DATADIR}/man/man1") + else() + install(FILES "${PROJECT_SOURCE_DIR}/doc/manpage/rawtherapee.1" + DESTINATION "${DATADIR}/share/man/man1") + endif() else() - install(FILES "${PROJECT_SOURCE_DIR}/doc/manpage/rawtherapee.1" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1") + install(FILES "${PROJECT_SOURCE_DIR}/doc/manpage/rawtherapee.1" + DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1") endif() if(WIN32) @@ -544,7 +713,8 @@ if(WIN32) endif() if(UNIX) - install(FILES com.rawtherapee.RawTherapee.appdata.xml DESTINATION "${APPDATADIR}") + install(FILES com.rawtherapee.RawTherapee.appdata.xml + DESTINATION "${APPDATADIR}") endif() # check whether the used version of lensfun has lfDatabase::LoadDirectory @@ -572,26 +742,31 @@ int main() lfDatabase *db = 0; bool b = db->LoadDirectory(0); return 0; -}" LENSFUN_HAS_LOAD_DIRECTORY) +}" + LENSFUN_HAS_LOAD_DIRECTORY) set(TCMALLOC_LIB_DIR) if(ENABLE_TCMALLOC) if(TCMALLOC_LIB_DIR) - find_library(TCMALLOC_LIBRARIES tcmalloc PATHS ${TCMALLOC_LIB_DIR} NO_DEFAULT_PATH) + find_library(TCMALLOC_LIBRARIES tcmalloc PATHS ${TCMALLOC_LIB_DIR} + NO_DEFAULT_PATH) else() find_library(TCMALLOC_LIBRARIES tcmalloc) endif() if(TCMALLOC_LIBRARIES) message(STATUS "using tcmalloc library in ${TCMALLOC_LIBRARIES}") else() - set(TCMALLOC_LIBRARIES "" CACHE INTERNAL "" FORCE) + set(TCMALLOC_LIBRARIES + "" + CACHE INTERNAL "" FORCE) message(STATUS "tcmalloc not found") endif() else() - set(TCMALLOC_LIBRARIES "" CACHE INTERNAL "" FORCE) + set(TCMALLOC_LIBRARIES + "" + CACHE INTERNAL "" FORCE) endif() - add_subdirectory(rtexif) add_subdirectory(rtengine) add_subdirectory(rtgui) diff --git a/UpdateInfo.cmake b/UpdateInfo.cmake index d1f532506..473c68364 100644 --- a/UpdateInfo.cmake +++ b/UpdateInfo.cmake @@ -1,5 +1,9 @@ # cmakefile executed within a makefile target +if(APPLE) + set(PROJECT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..") +endif() + # If we find ReleaseInfo.cmake we use the info from there and don't need Git to be installed find_file(REL_INFO_FILE ReleaseInfo.cmake PATHS "${PROJECT_SOURCE_DIR}" NO_DEFAULT_PATH) if(REL_INFO_FILE STREQUAL REL_INFO_FILE-NOTFOUND) @@ -10,10 +14,10 @@ if(REL_INFO_FILE STREQUAL REL_INFO_FILE-NOTFOUND) find_program(GIT_CMD git PATHS "/opt/local/bin" "/usr/local/bin" "/usr/bin") find_program(GIT_CMD git) set(SHELL "/bin/bash") - else(WIN32) # Linux + else() # Linux find_program(GIT_CMD git) set(SHELL "/bin/bash") - endif(WIN32) + endif() # Fail if Git is not installed if(GIT_CMD STREQUAL GIT_CMD-NOTFOUND) @@ -64,14 +68,23 @@ if(REL_INFO_FILE STREQUAL REL_INFO_FILE-NOTFOUND) set(GIT_NUMERIC_VERSION_BS "${GIT_NUMERIC_VERSION_BS}.${GIT_COMMITS_SINCE_TAG}") endif() + execute_process(COMMAND uname -mrs OUTPUT_VARIABLE BUILDINFO_OS OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND date -Ru OUTPUT_VARIABLE BUILDINFO_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND date +%s OUTPUT_VARIABLE BUILDINFO_EPOCH OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND uuidgen COMMAND tr "A-Z" "a-z" OUTPUT_VARIABLE BUILDINFO_UUID OUTPUT_STRIP_TRAILING_WHITESPACE) message(STATUS "Git checkout information:") - message(STATUS " Commit description: ${GIT_DESCRIBE}") - message(STATUS " Branch: ${GIT_BRANCH}") - message(STATUS " Commit: ${GIT_COMMIT}") - message(STATUS " Commit date: ${GIT_COMMIT_DATE}") - message(STATUS " Commits since tag: ${GIT_COMMITS_SINCE_TAG}") - message(STATUS " Commits since branch: ${GIT_COMMITS_SINCE_BRANCH}") - message(STATUS " Version (unreliable): ${GIT_NUMERIC_VERSION_BS}") + message(STATUS " Commit description: ${GIT_DESCRIBE}") + message(STATUS " Branch: ${GIT_BRANCH}") + message(STATUS " Commit: ${GIT_COMMIT}") + message(STATUS " Commit date: ${GIT_COMMIT_DATE}") + message(STATUS " Commits since tag: ${GIT_COMMITS_SINCE_TAG}") + message(STATUS " Commits since branch: ${GIT_COMMITS_SINCE_BRANCH}") + message(STATUS " Version (unreliable): ${GIT_NUMERIC_VERSION_BS}") + message(STATUS "Build information:") + message(STATUS " Build OS: ${BUILDINFO_OS}") + message(STATUS " Build date: ${BUILDINFO_DATE} UTC") + message(STATUS " Epoch: ${BUILDINFO_EPOCH}") + message(STATUS " UUID: ${BUILDINFO_UUID}") if(NOT DEFINED CACHE_NAME_SUFFIX) set(CACHE_NAME_SUFFIX "${GIT_DESCRIBE}") @@ -79,10 +92,9 @@ if(REL_INFO_FILE STREQUAL REL_INFO_FILE-NOTFOUND) else() message(STATUS "CACHE_NAME_SUFFIX is \"${CACHE_NAME_SUFFIX}\"") endif() - -else(REL_INFO_FILE STREQUAL REL_INFO_FILE-NOTFOUND) +else() include("${PROJECT_SOURCE_DIR}/ReleaseInfo.cmake") -endif(REL_INFO_FILE STREQUAL REL_INFO_FILE-NOTFOUND) +endif() if(WIN32) if(BIT_DEPTH EQUAL 4) @@ -97,12 +109,12 @@ if(WIN32) set(ARCHITECTURE_ALLOWED "x64 ia64") # installing in 64 bits mode for all 64 bits processors, even for itanium architecture set(INSTALL_MODE "x64 ia64") - endif(BIT_DEPTH EQUAL 4) + endif() # set part of the output archive name set(SYSTEM_NAME "WinVista") configure_file("${PROJECT_SOURCE_DIR}/tools/win/InnoSetup/WindowsInnoSetup.iss.in" "${CMAKE_BINARY_DIR}/rtdata/WindowsInnoSetup.iss") -endif(WIN32) +endif() # build version.h from template configure_file("${PROJECT_SOURCE_DIR}/rtgui/version.h.in" "${CMAKE_BINARY_DIR}/rtgui/version.h") diff --git a/cmake/modules/FindMacIntegration.cmake b/cmake/modules/FindMacIntegration.cmake index a67c31baa..a6729ad7f 100644 --- a/cmake/modules/FindMacIntegration.cmake +++ b/cmake/modules/FindMacIntegration.cmake @@ -24,7 +24,7 @@ mark_as_advanced(MACINTEGRATION_LIBRARY) # handle the QUIETLY and REQUIRED arguments and set MACINTEGRATION_FOUND to TRUE if # all listed variables are TRUE include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(MACINTEGRATION DEFAULT_MSG MACINTEGRATION_LIBRARY MACINTEGRATION_INCLUDE_DIR) +find_package_handle_standard_args(MacIntegration DEFAULT_MSG MACINTEGRATION_LIBRARY MACINTEGRATION_INCLUDE_DIR) if(MACINTEGRATION_FOUND) set(MacIntegration_LIBRARIES ${MACINTEGRATION_LIBRARY}) diff --git a/rtdata/CMakeLists.txt b/rtdata/CMakeLists.txt index 46722ba01..00a32c0cc 100644 --- a/rtdata/CMakeLists.txt +++ b/rtdata/CMakeLists.txt @@ -29,9 +29,12 @@ if(UNIX) 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-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-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-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() install(FILES ${LANGUAGEFILES} DESTINATION "${DATADIR}/languages") @@ -44,8 +47,8 @@ if(WIN32) install(FILES ${FONTS} DESTINATION "${DATADIR}/fonts") endif() -install(DIRECTORY ${PROFILESDIR} DESTINATION "${DATADIR}" FILES_MATCHING PATTERN "*.pp3") -install(DIRECTORY ${THEMEDIR} DESTINATION "${DATADIR}") +install(DIRECTORY "${PROFILESDIR}" DESTINATION "${DATADIR}" FILES_MATCHING PATTERN "*.pp3") +install(DIRECTORY "${THEMEDIR}" DESTINATION "${DATADIR}") install(FILES ${IMG_SVG} DESTINATION "${DATADIR}/images") install(FILES ${IMG_PNG} DESTINATION "${DATADIR}/images") @@ -54,19 +57,15 @@ install(FILES ${IMG_ICO} DESTINATION "${DATADIR}/images") if(APPLE) # CMake escapes first item quote character. Do not remove 'DUMMY_VARIABLE=' set(MACOSX_BUNDLE_COMMAND DUMMY_VARIABLE= - PROJECT_NAME="${PROJECT_NAME}" + PROJECT_NAME=${PROJECT_NAME} PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}" - CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" + CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} GTK_PREFIX="${GTK_PREFIX}") - if(PROC_BIT_DEPTH MATCHES 32) - list(APPEND MACOSX_BUNDLE_COMMAND PROC_BIT_DEPTH=32) - else() - list(APPEND MACOSX_BUNDLE_COMMAND PROC_BIT_DEPTH=64) - endif() - list(APPEND MACOSX_BUNDLE_COMMAND sh "${PROJECT_SOURCE_DIR}/tools/osx/macosx_bundle.sh") + list(APPEND MACOSX_BUNDLE_COMMAND PROC_BIT_DEPTH=64) + list(APPEND MACOSX_BUNDLE_COMMAND sh ${PROJECT_SOURCE_DIR}/tools/osx/macosx_bundle.sh) add_custom_target(macosx_bundle COMMAND ${MACOSX_BUNDLE_COMMAND} - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/build COMMENT "Creating macOS bundle") endif() diff --git a/rtdata/dcpprofiles/CANON EOS 5D MARK IV.dcp b/rtdata/dcpprofiles/CANON EOS 5D MARK IV.dcp new file mode 100644 index 000000000..80407fb21 Binary files /dev/null and b/rtdata/dcpprofiles/CANON EOS 5D MARK IV.dcp differ diff --git a/rtdata/dcpprofiles/CANON EOS M6 MARK II.dcp b/rtdata/dcpprofiles/CANON EOS M6 MARK II.dcp new file mode 100644 index 000000000..9a877f02f Binary files /dev/null and b/rtdata/dcpprofiles/CANON EOS M6 MARK II.dcp differ diff --git a/rtdata/dcpprofiles/CANON EOS R.dcp b/rtdata/dcpprofiles/CANON EOS R.dcp new file mode 100644 index 000000000..6ea5302e2 Binary files /dev/null and b/rtdata/dcpprofiles/CANON EOS R.dcp differ diff --git a/rtdata/dcpprofiles/CANON POWERSHOT G1 X MARK II.dcp b/rtdata/dcpprofiles/CANON POWERSHOT G1 X MARK II.dcp new file mode 100644 index 000000000..656649fd9 Binary files /dev/null and b/rtdata/dcpprofiles/CANON POWERSHOT G1 X MARK II.dcp differ diff --git a/rtdata/dcpprofiles/Canon PowerShot S120.dcp b/rtdata/dcpprofiles/Canon PowerShot S120.dcp new file mode 100644 index 000000000..8bb089c29 Binary files /dev/null and b/rtdata/dcpprofiles/Canon PowerShot S120.dcp differ diff --git a/rtdata/dcpprofiles/FUJIFILM X-A5.dcp b/rtdata/dcpprofiles/FUJIFILM X-A5.dcp new file mode 100644 index 000000000..c6e88d789 Binary files /dev/null and b/rtdata/dcpprofiles/FUJIFILM X-A5.dcp differ diff --git a/rtdata/dcpprofiles/FUJIFILM X-H1.dcp b/rtdata/dcpprofiles/FUJIFILM X-H1.dcp new file mode 100644 index 000000000..e3abc07f1 Binary files /dev/null and b/rtdata/dcpprofiles/FUJIFILM X-H1.dcp differ diff --git a/rtdata/dcpprofiles/FUJIFILM X-PRO3.dcp b/rtdata/dcpprofiles/FUJIFILM X-PRO3.dcp new file mode 100644 index 000000000..bfbaff9e5 Binary files /dev/null and b/rtdata/dcpprofiles/FUJIFILM X-PRO3.dcp differ diff --git a/rtdata/dcpprofiles/FUJIFILM X-T3.dcp b/rtdata/dcpprofiles/FUJIFILM X-T3.dcp new file mode 100644 index 000000000..5024f38a9 Binary files /dev/null and b/rtdata/dcpprofiles/FUJIFILM X-T3.dcp differ diff --git a/rtdata/dcpprofiles/NIKON D500.dcp b/rtdata/dcpprofiles/NIKON D500.dcp new file mode 100644 index 000000000..c25294439 Binary files /dev/null and b/rtdata/dcpprofiles/NIKON D500.dcp differ diff --git a/rtdata/dcpprofiles/NIKON D5300.dcp b/rtdata/dcpprofiles/NIKON D5300.dcp new file mode 100644 index 000000000..2c7566c8c Binary files /dev/null and b/rtdata/dcpprofiles/NIKON D5300.dcp differ diff --git a/rtdata/dcpprofiles/NIKON D610.dcp b/rtdata/dcpprofiles/NIKON D610.dcp new file mode 100644 index 000000000..a5a05ca34 Binary files /dev/null and b/rtdata/dcpprofiles/NIKON D610.dcp differ diff --git a/rtdata/dcpprofiles/NIKON D7100.dcp b/rtdata/dcpprofiles/NIKON D7100.dcp new file mode 100644 index 000000000..332157fc9 Binary files /dev/null and b/rtdata/dcpprofiles/NIKON D7100.dcp differ diff --git a/rtdata/dcpprofiles/NIKON D7500.dcp b/rtdata/dcpprofiles/NIKON D7500.dcp new file mode 100644 index 000000000..5e6cb2c64 Binary files /dev/null and b/rtdata/dcpprofiles/NIKON D7500.dcp differ diff --git a/rtdata/dcpprofiles/NIKON D800.dcp b/rtdata/dcpprofiles/NIKON D800.dcp new file mode 100644 index 000000000..5f0ebba8c Binary files /dev/null and b/rtdata/dcpprofiles/NIKON D800.dcp differ diff --git a/rtdata/dcpprofiles/NIKON D850.dcp b/rtdata/dcpprofiles/NIKON D850.dcp new file mode 100644 index 000000000..806e1e9bb Binary files /dev/null and b/rtdata/dcpprofiles/NIKON D850.dcp differ diff --git a/rtdata/dcpprofiles/NIKON Z 50.dcp b/rtdata/dcpprofiles/NIKON Z 50.dcp new file mode 100644 index 000000000..beca667a7 Binary files /dev/null and b/rtdata/dcpprofiles/NIKON Z 50.dcp differ diff --git a/rtdata/dcpprofiles/NIKON Z 6.dcp b/rtdata/dcpprofiles/NIKON Z 6.dcp new file mode 100644 index 000000000..eeb45a6b8 Binary files /dev/null and b/rtdata/dcpprofiles/NIKON Z 6.dcp differ diff --git a/rtdata/dcpprofiles/NIKON Z 7.dcp b/rtdata/dcpprofiles/NIKON Z 7.dcp new file mode 100644 index 000000000..19fb7bba6 Binary files /dev/null and b/rtdata/dcpprofiles/NIKON Z 7.dcp differ diff --git a/rtdata/dcpprofiles/OLYMPUS E-M5MARKII.dcp b/rtdata/dcpprofiles/OLYMPUS E-M5MARKII.dcp new file mode 100644 index 000000000..c3f670bfb Binary files /dev/null and b/rtdata/dcpprofiles/OLYMPUS E-M5MARKII.dcp differ diff --git a/rtdata/dcpprofiles/PENTAX K-50.dcp b/rtdata/dcpprofiles/PENTAX K-50.dcp new file mode 100644 index 000000000..3205c7579 Binary files /dev/null and b/rtdata/dcpprofiles/PENTAX K-50.dcp differ diff --git a/rtdata/dcpprofiles/SONY ILCE-6400.dcp b/rtdata/dcpprofiles/SONY ILCE-6400.dcp new file mode 100644 index 000000000..8c5fcfec4 Binary files /dev/null and b/rtdata/dcpprofiles/SONY ILCE-6400.dcp differ diff --git a/rtdata/dcpprofiles/SONY ILCE-6600.dcp b/rtdata/dcpprofiles/SONY ILCE-6600.dcp new file mode 100644 index 000000000..8c802d150 Binary files /dev/null and b/rtdata/dcpprofiles/SONY ILCE-6600.dcp differ diff --git a/rtdata/dcpprofiles/SONY ILCE-7RM4.dcp b/rtdata/dcpprofiles/SONY ILCE-7RM4.dcp new file mode 100644 index 000000000..e473fa496 Binary files /dev/null and b/rtdata/dcpprofiles/SONY ILCE-7RM4.dcp differ diff --git a/rtdata/dcpprofiles/SONY ILCE-9.dcp b/rtdata/dcpprofiles/SONY ILCE-9.dcp new file mode 100644 index 000000000..c07315812 Binary files /dev/null and b/rtdata/dcpprofiles/SONY ILCE-9.dcp differ diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index b4e1a2281..06a5136d6 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -9,13 +9,20 @@ #09 2014-10-16 DrSlony #10 2020-02-02 Bartłomiej Wiśniowski #11 2020-02-02 Bartłomiej Wiśniowski +#12 2020-02-15 Bartłomiej Wiśniowski +#13 2020-02-17 Bartłomiej Wiśniowski ABOUT_TAB_BUILD;Wersja ABOUT_TAB_CREDITS;Zasługi ABOUT_TAB_LICENSE;Licencja ABOUT_TAB_RELEASENOTES;Notatki eksploatacyjne ABOUT_TAB_SPLASH;Ekran powitalny +ADJUSTER_RESET_TO_DEFAULT;Klik - przywróć wartość domyślną.\nCtrl+klik - przywróć wartość początkową. BATCH_PROCESSING;Przetwarzanie wsadowe +CURVEEDITOR_AXIS_IN;We: +CURVEEDITOR_AXIS_LEFT_TAN;Lw: +CURVEEDITOR_AXIS_OUT;Wy: +CURVEEDITOR_AXIS_RIGHT_TAN;Pw: CURVEEDITOR_CATMULLROM;Elastyczny CURVEEDITOR_CURVE;Krzywa CURVEEDITOR_CURVES;Krzywe @@ -37,9 +44,11 @@ CURVEEDITOR_TOOLTIPPASTE;Wstaw krzywą ze schowka CURVEEDITOR_TOOLTIPSAVE;Zapisz krzywą CURVEEDITOR_TYPE;Typ: DIRBROWSER_FOLDERS;Katalogi +DONT_SHOW_AGAIN;Nie pokazuj tej wiadomości ponownie. DYNPROFILEEDITOR_DELETE;Usuń DYNPROFILEEDITOR_EDIT;Edytuj DYNPROFILEEDITOR_IMGTYPE_ANY;Każdy +DYNPROFILEEDITOR_IMGTYPE_HDR;HDR DYNPROFILEEDITOR_IMGTYPE_STD;Standardowy DYNPROFILEEDITOR_MOVE_DOWN;Przesuń w dół DYNPROFILEEDITOR_MOVE_UP;Przesuń w górę @@ -146,6 +155,7 @@ FILEBROWSER_POPUPRANK2;Ocena 2 ** FILEBROWSER_POPUPRANK3;Ocena 3 *** FILEBROWSER_POPUPRANK4;Ocena 4 **** FILEBROWSER_POPUPRANK5;Ocena 5 ***** +FILEBROWSER_POPUPREMOVE;Usuń na zawsze FILEBROWSER_POPUPRENAME;Zmień nazwę FILEBROWSER_POPUPSELECTALL;Zaznacz wszystkie FILEBROWSER_POPUPTRASH;Przenieś do kosza @@ -172,6 +182,7 @@ FILEBROWSER_SHOWDIRHINT;Wyłącza wyszstkie filtry.\nSkrót: d FILEBROWSER_SHOWEDITEDHINT;Pokazuje edytowane zdjęcia.\nSkrót: 7 FILEBROWSER_SHOWEDITEDNOTHINT;Pokazuje nieedytowane zdjęcia.\nSkrót: 6 FILEBROWSER_SHOWEXIFINFO;Pokaż dane Exif.\n\nSkróty:\ni - Tryb wielu zakładek,\nAlt-i - Tryb jednej zakładki. +FILEBROWSER_SHOWNOTTRASHHINT;Pokazuj tylko obrazy które nie znajdują się w koszu. FILEBROWSER_SHOWRANK1HINT;Pokazuje zdjęcia ocenione na 1 gwiazdkę.\nSkrót: 1 FILEBROWSER_SHOWRANK2HINT;Pokazuje zdjęcia ocenione na 2 gwiazdki.\nSkrót: 2 FILEBROWSER_SHOWRANK3HINT;Pokazuje zdjęcia ocenione na 3 gwiazdki.\nSkrót: 3 @@ -218,6 +229,7 @@ GENERAL_PORTRAIT;Pionowo GENERAL_RESET;Resetuj GENERAL_SAVE;Zapisz GENERAL_SAVE_AS;Zapisz jako... +GENERAL_SLIDER;Suwak GENERAL_UNCHANGED;(Niezmienione) GENERAL_WARNING;Uwaga HISTOGRAM_TOOLTIP_B;Pokaż/Ukryj histogram błękitów. @@ -590,6 +602,8 @@ HISTORY_MSG_411;Retinex - Siła HISTORY_MSG_413;Retinex - Kontrast HISTORY_MSG_418;Retinex - Próg HISTORY_MSG_419;Retinex - Przestrzeń kolorów +HISTORY_MSG_421;Retinex - Gamma +HISTORY_MSG_422;Retinex - Gamma HISTORY_MSG_426;Retinex - Wyrównywanie odcieni HISTORY_MSG_429;Retinex - Iteracje HISTORY_MSG_432;Retinex - M - Podświetlenia @@ -602,7 +616,11 @@ HISTORY_MSG_440;CbDL - Metoda HISTORY_MSG_442;Retinex - Skala HISTORY_MSG_449;PS - Adaptacja ISO HISTORY_MSG_452;PS - Pokaż ruch +HISTORY_MSG_453;PS - Pokaż tylko maskę +HISTORY_MSG_465;PS - Promień rozmycia +HISTORY_MSG_468;PS - Wypełnij dziury HISTORY_MSG_471;PS - Korekcja ruchu +HISTORY_MSG_472;PS - Miękkie przejścia HISTORY_MSG_474;PS - Wyrównaj HISTORY_MSG_475;PS - Wyrównaj kanał HISTORY_MSG_485;Korekcja obiektywu @@ -613,6 +631,10 @@ HISTORY_MSG_490;DRC - Ilość HISTORY_MSG_491;Balans bieli HISTORY_MSG_492;Krzywe RGB HISTORY_MSG_CLAMPOOG;Ucinaj kolory spoza zakresu +HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Korekcja koloru +HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Korekcja koloru +HISTORY_MSG_COLORTONING_LABREGION_CHANNEL;CT - Kanał +HISTORY_MSG_COLORTONING_LABREGION_SATURATION;CT - Saturacja HISTORY_MSG_DEHAZE_DEPTH;Usuwanie mgły - Głębia HISTORY_MSG_DEHAZE_ENABLED;Usuwanie mgły HISTORY_MSG_DEHAZE_LUMINANCE;Usuwanie mgły - Tylko luminancja @@ -631,6 +653,14 @@ HISTORY_MSG_PDSHARPEN_CONTRAST;CS - Próg kontrastu HISTORY_MSG_PDSHARPEN_ITERATIONS;CS - Iteracje HISTORY_MSG_PDSHARPEN_RADIUS;CS - Promień HISTORY_MSG_PRSHARPEN_CONTRAST;PRS - Próg kontrastu +HISTORY_MSG_RAWCACORR_AUTOIT;Korekcja aberracji chromatycznej - Iteracje +HISTORY_MSG_RAWCACORR_COLORSHIFT;Korekcja aberracji chromatycznej - Unikaj przesunięcia kolorów +HISTORY_MSG_SHARPENING_BLUR;Wyostrzanie - Promień rozmycia +HISTORY_MSG_SHARPENING_CONTRAST;Wyostrzanie - Próg kontrastu +HISTORY_MSG_SH_COLORSPACE;S/H - Przestrzeń kolorów +HISTORY_MSG_SOFTLIGHT_ENABLED;Miękkie światło +HISTORY_MSG_SOFTLIGHT_STRENGTH;Miękkie światło - Siła +HISTORY_MSG_TRANS_Method;Geometria - Metoda HISTORY_NEWSNAPSHOT;Nowa migawka HISTORY_NEWSNAPSHOT_TOOLTIP;Skrót: Alt-s HISTORY_SNAPSHOT;Migawka @@ -649,27 +679,43 @@ ICCPROFCREATOR_ILL_65;D65 ICCPROFCREATOR_ILL_80;D80 ICCPROFCREATOR_ILL_DEF;Domyślne ICCPROFCREATOR_ILL_INC;StdA 2856K +ICCPROFCREATOR_PRIM_ACESP0;ACES AP0 +ICCPROFCREATOR_PRIM_ACESP1;ACES AP1 ICCPROFCREATOR_PRIM_ADOBE;Adobe RGB (1998) ICCPROFCREATOR_PRIM_BEST;BestRGB ICCPROFCREATOR_PRIM_BETA;BetaRGB +ICCPROFCREATOR_PRIM_BLUX;Niebieski X +ICCPROFCREATOR_PRIM_BLUY;Niebieski Y ICCPROFCREATOR_PRIM_BRUCE;BruceRGB +ICCPROFCREATOR_PRIM_GREX;Zielony X +ICCPROFCREATOR_PRIM_GREY;Zielony Y ICCPROFCREATOR_PRIM_PROPH;Prophoto ICCPROFCREATOR_PRIM_REC2020;Rec2020 +ICCPROFCREATOR_PRIM_REDX;Czerwony X +ICCPROFCREATOR_PRIM_REDY;Czerwony Y ICCPROFCREATOR_PRIM_SRGB;sRGB +ICCPROFCREATOR_PRIM_WIDEG;Szeroka gama ICCPROFCREATOR_PROF_V2;ICC v2 ICCPROFCREATOR_PROF_V4;ICC v4 ICCPROFCREATOR_SAVEDIALOG_TITLE;Zapisz profil ICC jako... +ICCPROFCREATOR_SLOPE;Nachylenie +ICCPROFCREATOR_TRC_PRESET;Krzywa odpowiedzi tonalnej: IPTCPANEL_CATEGORY;Kategoria IPTCPANEL_CITY;Miasto IPTCPANEL_CITYHINT;Wprowadź nazwę miasta uwiecznionego na zdjęciu. IPTCPANEL_COPYHINT;Kopiuje ustawienia IPTC do schowka +IPTCPANEL_COPYRIGHT;Informacja o prawach autorskich +IPTCPANEL_COPYRIGHTHINT;Wprowadź informację o aktualnym posiadaczu praw autorskich np. ©2008 Jane Doe. IPTCPANEL_COUNTRY;Kraj +IPTCPANEL_COUNTRYHINT;Wprowadź nazwę kraju uwiecznionego na tym obrazie. IPTCPANEL_CREATOR;Twórca +IPTCPANEL_CREATORHINT;Wprowadź nazwę twórcy obrazu. IPTCPANEL_CREDIT;Zasługa IPTCPANEL_CREDITHINT;Identyfikuje dostawcę zdjęcia, niekoniecznie właściciela lub autora (Credit). IPTCPANEL_DATECREATED;Data utworzenia IPTCPANEL_DATECREATEDHINT;Wprowadź datę zrobienia zdjęcia. IPTCPANEL_DESCRIPTION;Opis +IPTCPANEL_DESCRIPTIONWRITER;Twórca opisu IPTCPANEL_EMBEDDED;Osadzony IPTCPANEL_EMBEDDEDHINT;Resetuje dane IPTC do domyślnych ustawień osadzonych w orginalnym zdjęciu IPTCPANEL_HEADLINE;Nagłówek @@ -682,6 +728,8 @@ IPTCPANEL_RESETHINT;Resetuje do domyślnych ustawień profilu IPTCPANEL_SOURCE;Źródło IPTCPANEL_SUPPCATEGORIES;Dodatkowe kategorie IPTCPANEL_TITLE;Tytuł +IPTCPANEL_TRANSREFERENCE;Numer pracy +IPTCPANEL_TRANSREFERENCEHINT;!IPTCPANEL_TRANSREFERENCEHINT;Wprowadź numer pracy, który umożliwi śledzenie obrazu. MAIN_BUTTON_FULLSCREEN;Pełen ekran MAIN_BUTTON_ICCPROFCREATOR;Kreator profili ICC MAIN_BUTTON_NAVNEXT_TOOLTIP;Przejdź do następnego zdjęcia względem zdjęcia otwartego w Edytorze.\nSkrót: Shift-F4\n\nAby przejść do następnego zdjęcia względem miniaturki wybranej w Nawigatorze Zdjęć:\nSkrót: F4 @@ -716,6 +764,7 @@ MAIN_MSG_OPERATIONCANCELLED;Operację anulowano MAIN_MSG_PATHDOESNTEXIST;Ścieżka\n\n%1\n\nnie istnieje. Wybierz przawidłową ścieżkę w Ustawieniach. MAIN_MSG_QOVERWRITE;Zastąpić? MAIN_MSG_SETPATHFIRST;Aby użyć tej funkcji należy wpierw wybrać odpowiednią ścieżkę docelową w Ustawieniach! +MAIN_MSG_TOOMANYOPENEDITORS;Za duża liczba otwartych edytorów.\nZamknij edytor aby kontynuować. MAIN_MSG_WRITEFAILED;Zapis nie powiódł się:\n\n"%1"\n\nUpewnij się, że folder istnieje oraz że można do niego zapisywać. MAIN_TAB_ADVANCED;Zaawansowane MAIN_TAB_ADVANCED_TOOLTIP;Skrót: Alt-a @@ -834,12 +883,18 @@ PARTIALPASTE_SHADOWSHIGHLIGHTS;Cienie/Podświetlenia PARTIALPASTE_SHARPENEDGE;Krawędzie PARTIALPASTE_SHARPENING;Wyostrzanie PARTIALPASTE_SHARPENMICRO;Mikrokontrast +PARTIALPASTE_SOFTLIGHT;Miękkie światło +PARTIALPASTE_TM_FATTAL;Kompresja zakresu dynamiki PARTIALPASTE_VIBRANCE;Jaskrawość PARTIALPASTE_VIGNETTING;Korekcja winietowania PARTIALPASTE_WHITEBALANCE;Balans bieli PREFERENCES_ADD;Dodaj PREFERENCES_APPEARANCE;Wygląd +PREFERENCES_APPEARANCE_COLORPICKERFONT;Czcionka narzędzia do wybierania kolorów +PREFERENCES_APPEARANCE_CROPMASKCOLOR;Kolor maski kadrowania +PREFERENCES_APPEARANCE_MAINFONT;Główny font PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Kolor ramki Nawigatora +PREFERENCES_APPEARANCE_PSEUDOHIDPI; Tryb pseudo-HiDPI PREFERENCES_APPEARANCE_THEME;Motyw graficzny PREFERENCES_APPLNEXTSTARTUP;wymaga ponownego uruchomienia PREFERENCES_AUTOMONPROFILE;Automatycznie użyj systemowego profilu monitora @@ -855,16 +910,23 @@ PREFERENCES_CACHECLEAR_ONLYPROFILES;Usuń wszystkie profile przetwarzania z pami PREFERENCES_CACHEMAXENTRIES;Maksymalna liczba wpisów w pamięci podręcznej PREFERENCES_CACHEOPTS;Opcje pamięci podręcznej PREFERENCES_CACHETHUMBHEIGHT;Maksymalna wysokość miniatury +PREFERENCES_CHUNKSIZES;Liczba kafelków na wątek PREFERENCES_CHUNKSIZE_RAW_AMAZE;Demozaikowanie AMaZE +PREFERENCES_CHUNKSIZE_RAW_CA;Korekcja aberracji chromatycznej PREFERENCES_CHUNKSIZE_RAW_RCD;Demozaikowanie RCD PREFERENCES_CHUNKSIZE_RAW_XT;Demozaikowanie Xtrans PREFERENCES_CHUNKSIZE_RGB;Przetwarzanie RGB PREFERENCES_CLIPPINGIND;Pokazywanie obciętych prześwietleń/cieni +PREFERENCES_CLUTSCACHE;Cache HaldCLUT PREFERENCES_CLUTSDIR;Folder obrazów HaldCLUT PREFERENCES_CMMBPC;Kompensacja punktu czerni +PREFERENCES_CROP;Kadrowanie +PREFERENCES_CROP_AUTO_FIT;Automatycznie przybliż aby dopasować do skadrowanego obrazu +PREFERENCES_CROP_GUIDES;Zawsze pokazuj ramkę kadrowania PREFERENCES_CROP_GUIDES_FRAME;Ramka PREFERENCES_CROP_GUIDES_FULL;Oryginał PREFERENCES_CROP_GUIDES_NONE;Brak +PREFERENCES_CURVEBBOXPOS;Położenie przycisków kopiuj oraz wklej krzywą PREFERENCES_CURVEBBOXPOS_ABOVE;Powyżej PREFERENCES_CURVEBBOXPOS_BELOW;Poniżej PREFERENCES_CURVEBBOXPOS_LEFT;Z lewej @@ -887,9 +949,11 @@ PREFERENCES_DIRLAST;Ostatnio odwiedzony katalog PREFERENCES_DIROTHER;Inny PREFERENCES_DIRSELECTDLG;Wybierz katalog z obrazami po uruchomieniu... PREFERENCES_DIRSOFTWARE;Katalog instalacyjny +PREFERENCES_EDITORCMDLINE;Własny wiersz poleceń PREFERENCES_EDITORLAYOUT;Układ edytora PREFERENCES_EXTERNALEDITOR;Zewnętrzny edytor PREFERENCES_FBROWSEROPTS;Opcje przeglądarki plików +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Zwiń paski w przeglądarce plików PREFERENCES_FLATFIELDFOUND;Znaleziono PREFERENCES_FLATFIELDSDIR;Katalog z pustymi polami PREFERENCES_FLATFIELDSHOTS;kadry @@ -911,6 +975,7 @@ PREFERENCES_INTENT_SATURATION;Nasyceniowy PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Pokaż osadzoną miniaturę JPEG jeśli plik raw jest nieedytowany PREFERENCES_LANG;Język PREFERENCES_LANGAUTODETECT;Użyj języka systemowego +PREFERENCES_MAXRECENTFOLDERS;Maksymalna liczba ostatnio otwieranych folderów PREFERENCES_MENUGROUPEXTPROGS;Grupuj "Otwórz za pomocą" PREFERENCES_MENUGROUPFILEOPERATIONS;Grupuj operacje plików PREFERENCES_MENUGROUPLABEL;Grupuj operacje etykiet @@ -919,30 +984,39 @@ PREFERENCES_MENUGROUPRANK;Grupuj operacje oceny PREFERENCES_MENUOPTIONS;Opcje menu PREFERENCES_MONITOR;Monitor PREFERENCES_MONPROFILE;Domyślny profil kolorów +PREFERENCES_MONPROFILE_WARNOSX;Z powodu ograniczeń MacOS, dostępna jest tylko paleta sRGB. PREFERENCES_MULTITAB;Tryb wielu zakładek PREFERENCES_MULTITABDUALMON;Tryb wielu zakładek (na drugim monitorze jeśli dostępny) PREFERENCES_NAVIGATIONFRAME;Nawigacja PREFERENCES_OVERLAY_FILENAMES;Nakładaj nazwy pliku na miniatury +PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Nakładaj nazwy plików na miniaturki w przeglądarce PREFERENCES_OVERWRITEOUTPUTFILE;Nadpisuj istniejące pliki PREFERENCES_PANFACTORLABEL;Współczynnik PREFERENCES_PARSEDEXT;Przetwarzane rozszerzenia PREFERENCES_PARSEDEXTADD;Dodaj rozszerzenie PREFERENCES_PARSEDEXTADDHINT;Proszę wprowadzić rozszerzenie i zatwierdzić przyciskiem, by dodać do listy PREFERENCES_PARSEDEXTDELHINT;Skasuje wybrane rozszerzenie z listy +PREFERENCES_PARSEDEXTDOWNHINT;Przenieś wybrane rozszerzenie w dół. +PREFERENCES_PARSEDEXTUPHINT;Przenieś wybrane rozszerzenie w górę. +PREFERENCES_PERFORMANCE_MEASURE;Zmierz PREFERENCES_PERFORMANCE_THREADS;Wątki PREFERENCES_PREVDEMO;Metoda demozaikowania podglądu PREFERENCES_PREVDEMO_FAST;Szybka +PREFERENCES_PREVDEMO_LABEL;Metoda demozaikowania podczas podglądu przy powiększeniu mniejszym niż 100%: +PREFERENCES_PREVDEMO_SIDECAR;Tak jak w PP3 PREFERENCES_PROFILEHANDLING;Obsługa profili PREFERENCES_PROFILELOADPR;Priorytet wczytywania profilu PREFERENCES_PROFILEPRCACHE;Profil w pamięci podręcznej PREFERENCES_PROFILEPRFILE;Profil przy pliku wejściowym PREFERENCES_PROFILESAVECACHE;Zapisz parametry przetwarzania w pamięci podręcznej PREFERENCES_PROFILESAVEINPUT;Zapisz parametry przetwarzania obok pliku wejściowego +PREFERENCES_PROFILESAVELOCATION;Miejsce zapisywania profilu przetwarzania PREFERENCES_PROFILE_NONE;Żaden PREFERENCES_PROPERTY;Własność PREFERENCES_PRTPROFILE;Profil kolorów PREFERENCES_PSPATH;Katalog w którym zainstalowany jest Adobe Photoshop PREFERENCES_SELECTLANG;Wybierz język +PREFERENCES_SERIALIZE_TIFF_READ;Ustawienia odczytu TIFF PREFERENCES_SET;Ustaw PREFERENCES_SHOWBASICEXIF;Pokaż podstawowe dane Exif PREFERENCES_SHOWDATETIME;Pokaż datę i czas @@ -961,6 +1035,7 @@ PREFERENCES_TAB_GENERAL;Ogólne PREFERENCES_TAB_IMPROC;Przetwarzanie obrazu PREFERENCES_TAB_PERFORMANCE;Wydajność PREFERENCES_TAB_SOUND;Dźwięki +PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Image to show PREFERENCES_TP_LABEL;Panel narzędzi: PREFERENCES_TP_VSCROLLBAR;Ukry pionowy pasek przesuwania PREFERENCES_USEBUNDLEDPROFILES;Użyj załączone profile przetwarzania @@ -974,6 +1049,7 @@ PROFILEPANEL_MODE_TIP;Tryb wypełnienia parametrów przetwarzania.\n\nWduszone: PROFILEPANEL_MYPROFILES;Moje profile przetwarzania PROFILEPANEL_PASTEPPASTE;Parametry do wklejenia PROFILEPANEL_PCUSTOM;Własny +PROFILEPANEL_PDYNAMIC;Dynamika PROFILEPANEL_PFILE;Z pliku PROFILEPANEL_PINTERNAL;Neutralny PROFILEPANEL_PLASTSAVED;Ostatnio zapisany @@ -984,7 +1060,10 @@ PROFILEPANEL_TOOLTIPLOAD;Ładuj profil z pliku.\nCtrl+klik aby wybrać pa PROFILEPANEL_TOOLTIPPASTE;Wklej profil ze schowka.\nCtrl+klik aby wybrać parametry do wklejenia. PROFILEPANEL_TOOLTIPSAVE;Zapisz aktualny profil.\nCtrl+klik aby wybrać parametry do zapisania. PROGRESSBAR_DECODING;Dekodowanie... +PROGRESSBAR_GREENEQUIL;Równoważenie koloru zielonego... PROGRESSBAR_HLREC;Rekonstrukcja podświetleń... +PROGRESSBAR_HOTDEADPIXELFILTER;Filtr gorących/martwych pikseli.. +PROGRESSBAR_LINEDENOISE;Liniowy filtr szumu... PROGRESSBAR_LOADING;Wczytywanie obrazu... PROGRESSBAR_LOADINGTHUMBS;Wczytywanie miniatur... PROGRESSBAR_LOADJPEG;Ładowanie pliku JPEG... @@ -993,6 +1072,7 @@ PROGRESSBAR_LOADTIFF;Ładowanie pliku TIFF... PROGRESSBAR_NOIMAGES;Nie znaleziono żadnych obrazów PROGRESSBAR_PROCESSING;Przetwarzanie obrazu... PROGRESSBAR_PROCESSING_PROFILESAVED;Zapisano profil przetwarzania +PROGRESSBAR_RAWCACORR;Korekcja aberracji chromatycznej... PROGRESSBAR_READY;Gotowe PROGRESSBAR_SAVEJPEG;Zapisywanie pliku JPEG... PROGRESSBAR_SAVEPNG;Zapisywanie pliku PNG... @@ -1011,8 +1091,18 @@ QUEUE_FORMAT_TITLE;Format pliku QUEUE_LOCATION_FOLDER;Zapisz do katalogu QUEUE_LOCATION_TEMPLATE;Użyj schemat QUEUE_LOCATION_TEMPLATE_TOOLTIP;Dozwolone są następujące kody formatujące:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r, %s1, %s2, ...\n\nKody formatujące odnoszą się do różnych elementów ścieżki zdjęcia, atrybutów zdjęcia oraz do arbitralnego ciągu numerycznego operacji wsadowej.\n\nPrzykładowo, jeśli zdjęcie obrabiane ma następującą ścieżkę:\n/home/andrzej/zdjecia/2010-10-31/dsc0042.nef\nznaczenie kodów formatujących jest następujące:\n%d4 = home\n%d3 = andrzej\n%d2 = zdjecia\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/photos/2010-10-31/\n%p2 = /home/andrzej/zdjecia/\n%p3 = /home/andrzej/\n%p4 = /home/\n\n%r zostanie zastąpione oceną zdjęcia. Jeśli zdjęcie nie posiada oceny, %r zostanie zastąpione liczbą '0'. Jeśli zdjęcie leży w śmietniku, %r zostanie zastąpione znakiem 'x'.\n\n%s1, %s2, etc. zostanie zastąpione ciągniem numerycznym dopełnionym od jednej do dziewięciu cyfr. Ciąg ten zostanie rozpocznięty od "1" za każdym razem gdy kolejka przetwarzania zostanie uruchomiona, i liczba jest zwiększona o "1" dla każdego zapisanego obrazu.\n\nJeśli chcesz zapisać obraz wyjściowy obok obrazu wejściowego, napisz:\n%p1/%f\n\nJeśli chcesz zapisać obraz wyjściowy w folderze o nazwie "wywolane" znajdującego się w katalogu zawierającym otwarty obraz, napisz:\n%p1/wywolane/%f\n\nJeśli chcesz zapisać obraz wyjściowy w folderze o nazwie "/home/andrzej/zdjecia/wywolane/2010-10-31", napisz:\n%p2/wywolane/%d1/%f +QUEUE_LOCATION_TITLE;Lokalizacja wyjściowa +SAMPLEFORMAT_0;Nieznany typ pliku +SAMPLEFORMAT_1;8-bit bez znaku +SAMPLEFORMAT_2;16-bit bez znaku +SAMPLEFORMAT_4;24-bit LogLuv +SAMPLEFORMAT_8;32-bit LogLuv +SAMPLEFORMAT_16;16-bit zmiennoprzecinkowy +SAMPLEFORMAT_32;24-bit zmiennoprzecinkowy +SAMPLEFORMAT_64;32-bit zmiennoprzecinkowy SAVEDLG_AUTOSUFFIX;Automatycznie dodaj przyrostek, jeżeli plik już istnieje SAVEDLG_FILEFORMAT;Format pliku +SAVEDLG_FILEFORMAT_FLOAT; zmiennoprzecinkowy SAVEDLG_FORCEFORMATOPTS;Wymuś opcje zapisu SAVEDLG_JPEGQUAL;Jakość JPEG SAVEDLG_PUTTOQUEUE;Umieść w kolejce przetwarzania @@ -1099,6 +1189,9 @@ TP_BWMIX_VAL;L TP_CACORRECTION_BLUE;Niebieski TP_CACORRECTION_LABEL;Korekcja aberracji chromatycznej TP_CACORRECTION_RED;Czerwony +TP_CBDL_AFT;Po zmianie na Cz-B +TP_CBDL_BEF;Przed zmianą na Cz-B +TP_CBDL_METHOD;Gdzie TP_CHMIXER_BLUE;Niebieski TP_CHMIXER_GREEN;Zielony TP_CHMIXER_LABEL;Mieszacz kanałów @@ -1188,11 +1281,17 @@ TP_COLORTONING_LABREGION_CHANNEL_ALL;Wszystkie TP_COLORTONING_LABREGION_CHANNEL_B;Niebieski TP_COLORTONING_LABREGION_CHANNEL_G;Zielony TP_COLORTONING_LABREGION_CHANNEL_R;Czerwony +TP_COLORTONING_LABREGION_CHROMATICITYMASK;C +TP_COLORTONING_LABREGION_HUEMASK;H +TP_COLORTONING_LABREGION_LIGHTNESSMASK;L TP_COLORTONING_LABREGION_LIST_TITLE;Korekcja TP_COLORTONING_LABREGION_MASK;Maska +TP_COLORTONING_LABREGION_MASKBLUR;Rozmycie maski TP_COLORTONING_LABREGION_OFFSET;Przesunięcie +TP_COLORTONING_LABREGION_POWER;Moc TP_COLORTONING_LABREGION_SATURATION;Saturacja TP_COLORTONING_LABREGION_SHOWMASK;Pokaż maskę +TP_COLORTONING_LABREGION_SLOPE;Nachylenie TP_COLORTONING_LUMA;Luminancja TP_COLORTONING_LUMAMODE;Zachowaj luminancję TP_COLORTONING_LUMAMODE_TOOLTIP;Luminancja zostanie zachowana przy zmianie kolorów. @@ -1205,7 +1304,7 @@ TP_COLORTONING_OPACITY;Przezroczystość TP_COLORTONING_RGBCURVES;RGB - Krzywe TP_COLORTONING_RGBSLIDERS;RGB - Suwaki TP_COLORTONING_SA;Ochrona przed przesyceniem -TP_COLORTONING_SATURATEDOPACITY;Śiła +TP_COLORTONING_SATURATEDOPACITY;Siła TP_COLORTONING_SATURATIONTHRESHOLD;Próg TP_COLORTONING_SHADOWS;Cienie TP_COLORTONING_SPLITCO;Cienie/półcienie/podświetlenia @@ -1244,6 +1343,7 @@ TP_DEHAZE_LABEL;Usuwanie mgły TP_DEHAZE_LUMINANCE;Tylko luminancja TP_DEHAZE_SHOW_DEPTH_MAP;Pokaż mapę głębokości TP_DEHAZE_STRENGTH;Siła +TP_DIRPYRDENOISE_CHROMINANCE_AUTOGLOBAL;Automatycznie TP_DIRPYRDENOISE_CHROMINANCE_BLUEYELLOW;Chrominancja - Błękit-żółć TP_DIRPYRDENOISE_CHROMINANCE_CURVE;Krzywa chrominancji TP_DIRPYRDENOISE_CHROMINANCE_FRAME;Chrominancja @@ -1277,6 +1377,12 @@ TP_DIRPYRDENOISE_MEDIAN_METHOD_RGB;RGB TP_DIRPYRDENOISE_MEDIAN_METHOD_TOOLTIP;Przy użyciu metod "tylko luminancja" oraz "L*a*b*", filtrowanie mediana zostanie wykonane prosto po funkcji falki w procesie odszumiania.\nW trybie "RGB" filtrowanie to zostanie wykonana pod koniec calego procesu. TP_DIRPYRDENOISE_MEDIAN_PASSES;Liczba powtórzeń mediana TP_DIRPYRDENOISE_MEDIAN_TYPE;Rodzaj mediana +TP_DIRPYRDENOISE_TYPE_3X3;3×3 +TP_DIRPYRDENOISE_TYPE_3X3SOFT;3×3 miękko +TP_DIRPYRDENOISE_TYPE_5X5;5×5 +TP_DIRPYRDENOISE_TYPE_5X5SOFT;5×5 miękko +TP_DIRPYRDENOISE_TYPE_7X7;7×7 +TP_DIRPYRDENOISE_TYPE_9X9;9×9 TP_DIRPYREQUALIZER_ALGO;Zakres odcieni skóry TP_DIRPYREQUALIZER_ALGO_TOOLTIP;- TP_DIRPYREQUALIZER_ARTIF;Usuń artefakty @@ -1322,11 +1428,16 @@ TP_EXPOSURE_TCMODE_FILMLIKE;Klisza TP_EXPOSURE_TCMODE_LABEL1;Tryb krzywej 1 TP_EXPOSURE_TCMODE_LABEL2;Tryb krzywej 2 TP_EXPOSURE_TCMODE_LUMINANCE;Luminancja +TP_EXPOSURE_TCMODE_PERCEPTUAL;Percepcyjny TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Mieszanie nasycenia i mocy światła białego TP_EXPOSURE_TCMODE_STANDARD;Standardowa TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Ważona standardowa TP_EXPOS_BLACKPOINT_LABEL;Punkt czerni raw TP_EXPOS_WHITEPOINT_LABEL;Punkt bieli raw +TP_FILMNEGATIVE_BLUE;Proporcja niebieskiego +TP_FILMNEGATIVE_LABEL;Negatyw - klisza +TP_FILMNEGATIVE_PICK;Wybierz miejsce neutralne +TP_FILMNEGATIVE_RED;Proporcja czerwonego TP_FILMSIMULATION_LABEL;Symulacja Kliszy TP_FILMSIMULATION_STRENGTH;Siła TP_FILMSIMULATION_ZEROCLUTSFOUND;Ustaw folder HaldCLUT w Ustawieniach @@ -1389,8 +1500,12 @@ TP_ICM_SAVEREFERENCE_TOOLTIP;Zapisz liniowy obraz TIFF zanim profil wejściowy z TP_ICM_TONECURVE;Użyj krzywą tonalną z DCP TP_ICM_TONECURVE_TOOLTIP;Włącz aby użyć krzywą tonalną znajdującą się w profilu DCP. Opcja ta jest tylko aktywna jeśli profil DCP zawiera krzywą tonalną. TP_ICM_WORKINGPROFILE;Profil roboczy +TP_ICM_WORKING_TRC;Krzywa odpowiedzi tonalnej: TP_ICM_WORKING_TRC_CUSTOM;Własna +TP_ICM_WORKING_TRC_GAMMA;Gamma TP_ICM_WORKING_TRC_NONE;Żadna +TP_ICM_WORKING_TRC_SLOPE;Nachylenie +TP_ICM_WORKING_TRC_TOOLTIP;Tylko dla wbudowanych profili. TP_IMPULSEDENOISE_LABEL;Redukcja Szumów Impulsowych TP_IMPULSEDENOISE_THRESH;Próg TP_LABCURVE_AVOIDCOLORSHIFT;Zapobiegaj zmianom koloru @@ -1435,14 +1550,19 @@ TP_LENSGEOM_FILL;Auto-wypełnienie TP_LENSGEOM_LABEL;Obiektyw / Geometria TP_LENSGEOM_LIN;Liniowo TP_LENSGEOM_LOG;Logarytmicznie +TP_LENSPROFILE_CORRECTION_AUTOMATCH;Wybierz automatycznie TP_LENSPROFILE_CORRECTION_LCPFILE;Plik LCP +TP_LENSPROFILE_CORRECTION_MANUAL;Wybierz ręcznie TP_LENSPROFILE_LABEL;Profil korekcji obiektywu LCP TP_LENSPROFILE_MODE_HEADER;Profil obiektywu TP_LENSPROFILE_USE_CA;Aberracja chromatyczna TP_LENSPROFILE_USE_GEOMETRIC;Zniekształcenia geometryczne +TP_LENSPROFILE_USE_HEADER;Popraw TP_LENSPROFILE_USE_VIGNETTING;Winietowanie TP_LOCALCONTRAST_AMOUNT;Ilość +TP_LOCALCONTRAST_DARKNESS;Ciemne miejsca TP_LOCALCONTRAST_LABEL;Kontrast lokalny +TP_LOCALCONTRAST_LIGHTNESS;Jasne miejsca TP_LOCALCONTRAST_RADIUS;Promień TP_METADATA_EDIT;Zastosuj modyfikacje TP_METADATA_MODE;Tryb kopiowania metadanych @@ -1470,9 +1590,11 @@ TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Łata gorące piksele (pojedyńcze świecące, TP_PREPROCESS_LABEL;Przetwarzanie początkowe TP_PREPROCESS_LINEDENOISE;Filtr zakłóceń liniowych TP_PREPROCESS_LINEDENOISE_DIRECTION;Kierunek +TP_PREPROCESS_LINEDENOISE_DIRECTION_BOTH;Oba TP_PREPROCESS_LINEDENOISE_DIRECTION_HORIZONTAL;Poziomo TP_PREPROCESS_LINEDENOISE_DIRECTION_VERTICAL;Pionowo TP_PREPROCESS_NO_FOUND;Nic nie znaleziono +TP_PRSHARPENING_LABEL;Wyostrzanie po zmianie rozmiaru TP_RAWCACORR_AUTO;Autokorekcja TP_RAWCACORR_AUTOIT;Iteracje TP_RAWCACORR_AVOIDCOLORSHIFT;Unikaj przesunięcia kolorów @@ -1517,11 +1639,23 @@ TP_RAW_LMMSE;LMMSE TP_RAW_LMMSEITERATIONS;Ilość kroków udoskonalenia LMMSE TP_RAW_LMMSE_TOOLTIP;Aby zmniejszyć ilość artefaktów i poprawić stosunek sygnału do szumów, można wykorzystać następujące ustawienia:\n1: Gamma\n2-4: Średnia mediana\n5-6: Rafinowanie TP_RAW_MONO;Mono +TP_RAW_PIXELSHIFTBLUR;Maska rozmycia ruchu +TP_RAW_PIXELSHIFTDMETHOD;Metoda demozaikowania ruchu TP_RAW_PIXELSHIFTEPERISO;Czułość +TP_RAW_PIXELSHIFTEQUALBRIGHT;Wyrównaj jasność klatek +TP_RAW_PIXELSHIFTHOLEFILL;Wypełnij dziury w masce ruchu +TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Wypełnia dziury w masce ruchu +TP_RAW_PIXELSHIFTMEDIAN;Użyj mediany dla poruszonych fragmentów TP_RAW_PIXELSHIFTMM_AUTO;Automatyczny TP_RAW_PIXELSHIFTMM_CUSTOM;Własny TP_RAW_PIXELSHIFTMM_OFF;Wyłączony +TP_RAW_PIXELSHIFTMOTIONMETHOD;Korekcja ruchu +TP_RAW_PIXELSHIFTNONGREENCROSS;Szukaj ruchu w kanale niebieskim/czerwonym +TP_RAW_PIXELSHIFTSHOWMOTION;Pokaż maskę ruchu +TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Pokaż tylko maskę ruchu +TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Pokaż samą maskę ruchu (bez obrazu). TP_RAW_PIXELSHIFTSIGMA;Promień rozmycia +TP_RAW_PIXELSHIFTSMOOTH;Miękkie przejścia TP_RAW_RCD;RCD TP_RAW_RCDVNG4;RCD+VNG4 TP_RAW_SENSOR_BAYER_LABEL;Matryca z filtrem Bayera @@ -1530,6 +1664,7 @@ TP_RAW_SENSOR_XTRANS_LABEL;Matryca z filtrem X-Trans TP_RAW_VNG4;VNG4 TP_RAW_XTRANS;X-Trans TP_RAW_XTRANSFAST;Szybki X-Trans +TP_RESIZE_ALLOW_UPSCALING;Zezwól na zwiększenie rozdzielczości TP_RESIZE_APPLIESTO;Dotyczy: TP_RESIZE_CROPPEDAREA;Obszaru kadrowanego TP_RESIZE_FITBOX;Wymiary obwodu @@ -1548,10 +1683,21 @@ TP_RETINEX_CONTEDIT_HSL;Histogram HSL TP_RETINEX_CONTEDIT_LAB;Histogram L*a*b* TP_RETINEX_CONTEDIT_LH;Odcień TP_RETINEX_CONTEDIT_MAP;Wyrównywanie +TP_RETINEX_CURVEEDITOR_CD;L=f(L) +TP_RETINEX_CURVEEDITOR_LH;Siła=f(H) +TP_RETINEX_CURVEEDITOR_MAP;L=f(L) TP_RETINEX_EQUAL;Wyrównywanie TP_RETINEX_GAIN;Wzmocnienie +TP_RETINEX_GAMMA;Gamma +TP_RETINEX_GAMMA_FREE;Wolna +TP_RETINEX_GAMMA_HIGH;Wysoka +TP_RETINEX_GAMMA_LOW;Niska +TP_RETINEX_GAMMA_MID;Średnia +TP_RETINEX_GAMMA_NONE;Żaden TP_RETINEX_HIGH;Wysoki TP_RETINEX_HIGHLIGHT;Próg podświetleń +TP_RETINEX_HSLSPACE_LIN;HSL-Liniowa +TP_RETINEX_HSLSPACE_LOG;HSL-Logarytmiczna TP_RETINEX_LABEL;Retinex TP_RETINEX_LABEL_MASK;Maska TP_RETINEX_LABSPACE;L*a*b* @@ -1595,6 +1741,7 @@ TP_SHARPENEDGE_LABEL;Krawędzie TP_SHARPENEDGE_PASSES;Powtórzenia TP_SHARPENEDGE_THREE;Tylko luminancja TP_SHARPENING_AMOUNT;Siła +TP_SHARPENING_BLUR;Promień rozmycia TP_SHARPENING_CONTRAST;Próg kontrastu TP_SHARPENING_EDRADIUS;Promień TP_SHARPENING_EDTOLERANCE;Tolerancja krawędzi @@ -1617,6 +1764,7 @@ TP_SHARPENMICRO_MATRIX;Matryca 3×3 zamiast 5×5 TP_SHARPENMICRO_UNIFORMITY;Jednolitość TP_SOFTLIGHT_STRENGTH;Siła TP_TM_FATTAL_AMOUNT;Ilość +TP_TM_FATTAL_LABEL;Kompresja zakresu dynamiki TP_TM_FATTAL_THRESHOLD;Detale TP_VIBRANCE_AVOIDCOLORSHIFT;Zapobiegaj przesunięcia kolorów TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH @@ -1659,14 +1807,24 @@ TP_WAVELET_BACKGROUND;Tło TP_WAVELET_BACUR;Krzywa TP_WAVELET_BALCHRO;Balans chrominancji TP_WAVELET_BANONE;Żaden +TP_WAVELET_BASLI;Suwak +TP_WAVELET_BATYPE;Metoda balansu kontrastu +TP_WAVELET_CBENAB;Tonowanie i balans kolorów TP_WAVELET_CCURVE;Kontrast lokalny +TP_WAVELET_CH1;Cały zakres chrominancji +TP_WAVELET_CH2;Nasycone/pastelowe +TP_WAVELET_CH3;Połącz poziomy kontrastu TP_WAVELET_CHCU;Krzywa +TP_WAVELET_CHSL;Suwaki TP_WAVELET_COMPCONT;Kontrast +TP_WAVELET_COMPGAMMA;Kompresja - Gamma TP_WAVELET_CONTR;Gamut TP_WAVELET_CONTRA;Kontrast TP_WAVELET_CONTRAST_MINUS;Kontrast - TP_WAVELET_CONTRAST_PLUS;Kontrast + TP_WAVELET_CTYPE;Kontrola chrominancji +TP_WAVELET_CURVEEDITOR_CL;L +TP_WAVELET_CURVEEDITOR_HH;HH TP_WAVELET_DALL;We wszystkich kierunkach TP_WAVELET_DAUB2;D2 - niski TP_WAVELET_DAUB4;D4 - standard @@ -1681,18 +1839,28 @@ TP_WAVELET_EDGCONT;Kontrast lokalny TP_WAVELET_EDGE;Ostrość krawędzi TP_WAVELET_EDGEDETECTTHR;Niski próg (szum) TP_WAVELET_EDGEDETECTTHR2;Wysoki próg (wykrywanie) +TP_WAVELET_EDGTHRESH;Szczegółowość TP_WAVELET_EDRAD;Promień TP_WAVELET_EDSL;Suwaki progów +TP_WAVELET_EDTYPE;Metoda kontrastu lokalnego: TP_WAVELET_EDVAL;Siła +TP_WAVELET_FINAL;Ostateczny retusz +TP_WAVELET_FINEST;Najdokładniej +TP_WAVELET_HIGHLIGHT;Zakres luminancji podświetleń +TP_WAVELET_HS1;Zakres luminancji TP_WAVELET_HS2;Cienie/Podświetlenia TP_WAVELET_HUESKIN;Odcień skóry TP_WAVELET_HUESKY;Odcień nieba +TP_WAVELET_LEVCH;Chrominancja TP_WAVELET_LEVF;Kontrast TP_WAVELET_LEVONE;Poziom 2 TP_WAVELET_LEVTHRE;Poziom 4 TP_WAVELET_LEVTWO;Poziom 3 TP_WAVELET_LEVZERO;Poziom 1 +TP_WAVELET_LINKEDG;Połącz z siłą 'Ostrość krawędzi' TP_WAVELET_LIPST;Usprawniony algorytm +TP_WAVELET_LOWLIGHT;Zakres luminancji cieni +TP_WAVELET_MEDGREINF;Pierwszy poziom TP_WAVELET_MEDI;Usuwaj artefakty niebieskiego nieba TP_WAVELET_MEDILEV;Wykrywanie krawędzi TP_WAVELET_NEUTRAL;Neutralny @@ -1701,12 +1869,16 @@ TP_WAVELET_NPHIGH;Wysoki TP_WAVELET_NPLOW;Niski TP_WAVELET_NPNONE;Brak TP_WAVELET_NPTYPE;Piksele sąsiadujące +TP_WAVELET_PASTEL;Chrominancja kolorów pastelowych TP_WAVELET_PROC;Proces TP_WAVELET_RE1;Wzmocniony TP_WAVELET_RE2;Niezmieniony TP_WAVELET_RE3;Zmniejszony +TP_WAVELET_RESCHRO;Chrominancja TP_WAVELET_RESCON;Cienie TP_WAVELET_RESCONH;Podświetlenia +TP_WAVELET_SAT;Chrominancja kolorów nasyconych +TP_WAVELET_SKY;Odcień nieba - wybór/ochrona TP_WAVELET_STREN;Siła TP_WAVELET_STRENGTH;Siła TP_WAVELET_SUPE;Ekstra @@ -1714,7 +1886,9 @@ TP_WAVELET_THR;Próg cieni TP_WAVELET_THRESHOLD;Poziom podświetleń TP_WAVELET_THRESHOLD2;Poziom cieni TP_WAVELET_THRH;Próg podświetleń +TP_WAVELET_TMSTRENGTH;Siła kompresji TP_WAVELET_TMTYPE;Metoda kompresji +TP_WAVELET_TON;Tonowanie TP_WBALANCE_AUTO;Auto TP_WBALANCE_CAMERA;Z aparatu TP_WBALANCE_CLOUDY;Pochmurnie @@ -1757,6 +1931,7 @@ TP_WBALANCE_SOLUX41;Solux 4100K TP_WBALANCE_SOLUX47;Solux 4700K (vendor) TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) TP_WBALANCE_SPOTWB;Punktowy +TP_WBALANCE_TEMPBIAS;Kompensacja automatycznego balansu bieli (AWB) TP_WBALANCE_TEMPERATURE;Temperatura TP_WBALANCE_TUNGSTEN;Wolfram TP_WBALANCE_WATER1;Pod wodą 1 @@ -1774,16 +1949,9 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!ADJUSTER_RESET_TO_DEFAULT;Click - reset to default value.\nCtrl+click - reset to initial value. -!CURVEEDITOR_AXIS_IN;I: -!CURVEEDITOR_AXIS_LEFT_TAN;LT: -!CURVEEDITOR_AXIS_OUT;O: -!CURVEEDITOR_AXIS_RIGHT_TAN;RT: !CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. -!DONT_SHOW_AGAIN;Don't show this message again. !DYNPROFILEEDITOR_EDIT_RULE;Edit Dynamic Profile Rule !DYNPROFILEEDITOR_ENTRY_TOOLTIP;The matching is case insensitive.\nUse the "re:" prefix to enter\na regular expression. -!DYNPROFILEEDITOR_IMGTYPE_HDR;HDR !DYNPROFILEEDITOR_IMGTYPE_PS;Pixel Shift !DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule !EXPORT_BYPASS;Processing steps to bypass @@ -1796,11 +1964,8 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !FILEBROWSER_DELETEDIALOG_ALL;Are you sure you want to permanently delete all %1 files in trash? !FILEBROWSER_DELETEDIALOG_SELECTED;Are you sure you want to permanently delete the selected %1 files? !FILEBROWSER_DELETEDIALOG_SELECTEDINCLPROC;Are you sure you want to permanently delete the selected %1 files, including a queue-processed version? -!FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version -!FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. !FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. -!GENERAL_SLIDER;Slider !GIMP_PLUGIN_INFO;Welcome to the RawTherapee GIMP plugin!\nOnce you are done editing, simply close the main RawTherapee window and the image will be automatically imported in GIMP. !HISTOGRAM_TOOLTIP_MODE;Toggle between linear, log-linear and log-log scaling of the histogram. !HISTORY_MSG_235;B&W - CM - Auto @@ -1862,8 +2027,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_416;Retinex !HISTORY_MSG_417;Retinex - Transmission median !HISTORY_MSG_420;Retinex - Histogram - HSL -!HISTORY_MSG_421;Retinex - Gamma -!HISTORY_MSG_422;Retinex - Gamma !HISTORY_MSG_423;Retinex - Gamma slope !HISTORY_MSG_424;Retinex - HL threshold !HISTORY_MSG_425;Retinex - Log base @@ -1877,14 +2040,10 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_443;Output black point compensation !HISTORY_MSG_444;WB - Temp bias !HISTORY_MSG_445;Raw sub-image -!HISTORY_MSG_453;PS - Show mask only !HISTORY_MSG_457;PS - Check red/blue !HISTORY_MSG_462;PS - Check green !HISTORY_MSG_464;PS - Blur motion mask -!HISTORY_MSG_465;PS - Blur radius -!HISTORY_MSG_468;PS - Fill holes !HISTORY_MSG_469;PS - Median -!HISTORY_MSG_472;PS - Smooth transitions !HISTORY_MSG_473;PS - Use LMMSE !HISTORY_MSG_476;CAM02 - Temp out !HISTORY_MSG_477;CAM02 - Green out @@ -1898,9 +2057,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_488;Dynamic Range Compression !HISTORY_MSG_493;L*a*b* Adjustments !HISTORY_MSG_494;Capture Sharpening -!HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction -!HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction -!HISTORY_MSG_COLORTONING_LABREGION_CHANNEL;CT - Channel !HISTORY_MSG_COLORTONING_LABREGION_CHROMATICITYMASK;CT - region C mask !HISTORY_MSG_COLORTONING_LABREGION_HUEMASK;CT - H mask !HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESS;CT - Lightness @@ -1909,7 +2065,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_COLORTONING_LABREGION_MASKBLUR;CT - region mask blur !HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - region offset !HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - region power -!HISTORY_MSG_COLORTONING_LABREGION_SATURATION;CT - Saturation !HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - region show mask !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -1928,43 +2083,19 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion !HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction !HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter -!HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correction - Iterations -!HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correction - Avoid color shift !HISTORY_MSG_RAW_BORDER;Raw border !HISTORY_MSG_RESIZE_ALLOWUPSCALING;Resize - Allow upscaling -!HISTORY_MSG_SHARPENING_BLUR;Sharpening - Blur radius -!HISTORY_MSG_SHARPENING_CONTRAST;Sharpening - Contrast threshold -!HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace -!HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light -!HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength !HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anchor -!HISTORY_MSG_TRANS_Method;Geometry - Method !ICCPROFCREATOR_DESCRIPTION_ADDPARAM;Append gamma and slope values to the description !ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Leave empty to set the default description. !ICCPROFCREATOR_ILL;Illuminant: !ICCPROFCREATOR_ILL_TOOLTIP;You can only set the illuminant for ICC v4 profiles. !ICCPROFCREATOR_PRIMARIES;Primaries: -!ICCPROFCREATOR_PRIM_ACESP0;ACES AP0 -!ICCPROFCREATOR_PRIM_ACESP1;ACES AP1 -!ICCPROFCREATOR_PRIM_BLUX;Blue X -!ICCPROFCREATOR_PRIM_BLUY;Blue Y -!ICCPROFCREATOR_PRIM_GREX;Green X -!ICCPROFCREATOR_PRIM_GREY;Green Y -!ICCPROFCREATOR_PRIM_REDX;Red X -!ICCPROFCREATOR_PRIM_REDY;Red Y !ICCPROFCREATOR_PRIM_TOOLTIP;You can only set custom primaries for ICC v4 profiles. -!ICCPROFCREATOR_PRIM_WIDEG;Widegamut -!ICCPROFCREATOR_SLOPE;Slope -!ICCPROFCREATOR_TRC_PRESET;Tone response curve: !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. -!IPTCPANEL_COPYRIGHT;Copyright notice -!IPTCPANEL_COPYRIGHTHINT;Enter a Notice on the current owner of the Copyright for this image, such as ©2008 Jane Doe. -!IPTCPANEL_COUNTRYHINT;Enter the name of the country pictured in this image. -!IPTCPANEL_CREATORHINT;Enter the name of the person that created this image. !IPTCPANEL_CREATORJOBTITLE;Creator's job title !IPTCPANEL_CREATORJOBTITLEHINT;Enter the Job Title of the person listed in the Creator field. !IPTCPANEL_DESCRIPTIONHINT;Enter a "caption" describing the who, what, and why of what is happening in this image, this might include names of people, and/or their role in the action that is taking place within the image. -!IPTCPANEL_DESCRIPTIONWRITER;Description writer !IPTCPANEL_DESCRIPTIONWRITERHINT;Enter the name of the person involved in writing, editing or correcting the description of the image. !IPTCPANEL_HEADLINEHINT;Enter a brief publishable synopsis or summary of the contents of the image. !IPTCPANEL_INSTRUCTIONSHINT;Enter information about embargoes, or other restrictions not covered by the Copyright field. @@ -1973,9 +2104,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !IPTCPANEL_SOURCEHINT;Enter or edit the name of a person or party who has a role in the content supply chain, such as a person or entity from whom you received this image from. !IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image. !IPTCPANEL_TITLEHINT;Enter a short verbal and human readable name for the image, this may be the file name. -!IPTCPANEL_TRANSREFERENCE;Job ID -!IPTCPANEL_TRANSREFERENCEHINT;Enter a number or identifier needed for workflow control or tracking. -!MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: middle grey\nShortcut: 9 !MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%. !OPTIONS_BUNDLED_MISSING;The bundled profile "%1" could not be found!\n\nYour installation could be damaged.\n\nDefault internal values will be used instead. @@ -1991,78 +2119,34 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PARTIALPASTE_RAW_BORDER;Raw border !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift -!PARTIALPASTE_SOFTLIGHT;Soft light -!PARTIALPASTE_TM_FATTAL;Dynamic range compression -!PREFERENCES_APPEARANCE_COLORPICKERFONT;Color picker font -!PREFERENCES_APPEARANCE_CROPMASKCOLOR;Crop mask color -!PREFERENCES_APPEARANCE_MAINFONT;Main font -!PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !PREFERENCES_AUTOSAVE_TP_OPEN;Save tool collapsed/expanded state on exit !PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Clear all cached files except for cached processing profiles: !PREFERENCES_CACHECLEAR_SAFETY;Only files in the cache are cleared. Processing profiles stored alongside the source images are not touched. -!PREFERENCES_CHUNKSIZES;Tiles per thread -!PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA correction -!PREFERENCES_CLUTSCACHE;HaldCLUT Cache !PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs -!PREFERENCES_CROP;Crop Editing -!PREFERENCES_CROP_AUTO_FIT;Automatically zoom to fit the crop -!PREFERENCES_CROP_GUIDES;Guides shown when not editing the crop -!PREFERENCES_CURVEBBOXPOS;Position of curve copy & paste buttons -!PREFERENCES_EDITORCMDLINE;Custom command line -!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Compact toolbars in File Browser !PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Filmstrip and the File Browser !PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;Having separate thumbnail size will require more processing time each time you'll switch between the single Editor tab and the File Browser. !PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;Set the maximum number of images stored in cache when hovering over them in the File Browser; systems with little RAM (2GB) should keep this value set to 1 or 2. -!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders !PREFERENCES_MONINTENT;Default rendering intent -!PREFERENCES_MONPROFILE_WARNOSX;Due to MacOS limitations, only sRGB is supported. -!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel -!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. -!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. -!PREFERENCES_PERFORMANCE_MEASURE;Measure !PREFERENCES_PERFORMANCE_MEASURE_HINT;Logs processing times in console !PREFERENCES_PERFORMANCE_THREADS_LABEL;Maximum number of threads for Noise Reduction and Wavelet Levels (0 = Automatic) -!PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: -!PREFERENCES_PREVDEMO_SIDECAR;As in PP3 !PREFERENCES_PRINTER;Printer (Soft-Proofing) !PREFERENCES_PROFILESAVEBOTH;Save processing profile both to the cache and next to the input file -!PREFERENCES_PROFILESAVELOCATION;Processing profile saving location !PREFERENCES_PRTINTENT;Rendering intent !PREFERENCES_REMEMBERZOOMPAN;Remember zoom % and pan offset !PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Remember the zoom % and pan offset of the current image when opening a new image.\n\nThis option only works in "Single Editor Tab Mode" and when "Demosaicing method used for the preview at <100% zoom" is set to "As in PP3". !PREFERENCES_SAVE_TP_OPEN_NOW;Save tool collapsed/expanded state now -!PREFERENCES_SERIALIZE_TIFF_READ;TIFF Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize reading of TIFF files !PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Enabling this option when working with folders containing uncompressed TIFF files can increase performance of thumbnail generation. !PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show Filmstrip toolbar !PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules !PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Embedded JPEG preview -!PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Image to show !PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutral raw rendering !PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Embedded JPEG if fullsize, neutral raw otherwise -!PROFILEPANEL_PDYNAMIC;Dynamic -!PROGRESSBAR_GREENEQUIL;Green equilibration... -!PROGRESSBAR_HOTDEADPIXELFILTER;Hot/dead pixel filter... -!PROGRESSBAR_LINEDENOISE;Line noise filter... -!PROGRESSBAR_RAWCACORR;Raw CA correction... -!QUEUE_LOCATION_TITLE;Output Location !QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s -!SAMPLEFORMAT_0;Unknown data format -!SAMPLEFORMAT_1;8-bit unsigned -!SAMPLEFORMAT_2;16-bit unsigned -!SAMPLEFORMAT_4;24-bit LogLuv -!SAMPLEFORMAT_8;32-bit LogLuv -!SAMPLEFORMAT_16;16-bit floating-point -!SAMPLEFORMAT_32;24-bit floating-point -!SAMPLEFORMAT_64;32-bit floating-point -!SAVEDLG_FILEFORMAT_FLOAT; floating-point !SAVEDLG_SUBSAMP_TOOLTIP;Best compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma halved horizontally and vertically.\n\nBalanced:\nJ:a:b 4:2:2\nh/v 2/1\nChroma halved horizontally.\n\nBest quality:\nJ:a:b 4:4:4\nh/v 1/1\nNo chroma subsampling. !SOFTPROOF_GAMUTCHECK_TOOLTIP;Highlight pixels with out-of-gamut colors with respect to:\n- the printer profile, if one is set and soft-proofing is enabled,\n- the output profile, if a printer profile is not set and soft-proofing is enabled,\n- the monitor profile, if soft-proofing is disabled. !SOFTPROOF_TOOLTIP;Soft-proofing simulates the appearance of the image:\n- when printed, if a printer profile is set in Preferences > Color Management,\n- when viewed on a display that uses the current output profile, if a printer profile is not set. !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen the tool is active:\n- Add a picker: left-click.\n- Drag a picker: left-click and drag.\n- Delete a picker: right-click.\n- Delete all pickers: Ctrl+Shift+right-click.\n- Revert to hand tool: right-click outside any picker. -!TP_CBDL_AFT;After Black-and-White -!TP_CBDL_BEF;Before Black-and-White -!TP_CBDL_METHOD;Process located !TP_CBDL_METHOD_TOOLTIP;Choose whether the Contrast by Detail Levels tool is to be positioned after the Black-and-White tool, which makes it work in L*a*b* space, or before it, which makes it work in RGB space. !TP_COLORAPP_CAT02ADAPTATION_TOOLTIP;When setting manually, values above 65 are recommended. !TP_COLORAPP_FREE;Free temp+green + CAT02 + [output] @@ -2072,18 +2156,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_COLORTONING_LABGRID_VALUES;HL: a=%1 b=%2\nS: a=%3 b=%4 !TP_COLORTONING_LABREGIONS;Color correction regions !TP_COLORTONING_LABREGION_ABVALUES;a=%1 b=%2 -!TP_COLORTONING_LABREGION_CHROMATICITYMASK;C -!TP_COLORTONING_LABREGION_HUEMASK;H !TP_COLORTONING_LABREGION_LIGHTNESS;Lightness -!TP_COLORTONING_LABREGION_LIGHTNESSMASK;L -!TP_COLORTONING_LABREGION_MASKBLUR;Mask Blur -!TP_COLORTONING_LABREGION_POWER;Power -!TP_COLORTONING_LABREGION_SLOPE;Slope !TP_CROP_GTHARMMEANS;Harmonic Means !TP_CROP_GTTRIANGLE1;Golden Triangles 1 !TP_CROP_GTTRIANGLE2;Golden Triangles 2 !TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones -!TP_DIRPYRDENOISE_CHROMINANCE_AUTOGLOBAL;Automatic global !TP_DIRPYRDENOISE_CHROMINANCE_CURVE_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. !TP_DIRPYRDENOISE_CHROMINANCE_METHODADVANCED_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. !TP_DIRPYRDENOISE_CHROMINANCE_METHOD_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. @@ -2096,22 +2173,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_DIRPYRDENOISE_MEDIAN_METHOD_WEIGHTED;Weighted L* (little) + a*b* (normal) !TP_DIRPYRDENOISE_MEDIAN_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. !TP_DIRPYRDENOISE_MEDIAN_TYPE_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. -!TP_DIRPYRDENOISE_TYPE_3X3;3×3 -!TP_DIRPYRDENOISE_TYPE_3X3SOFT;3×3 soft -!TP_DIRPYRDENOISE_TYPE_5X5;5×5 -!TP_DIRPYRDENOISE_TYPE_5X5SOFT;5×5 soft -!TP_DIRPYRDENOISE_TYPE_7X7;7×7 -!TP_DIRPYRDENOISE_TYPE_9X9;9×9 !TP_DISTORTION_AUTO_TIP;Automatically corrects lens distortion in raw files by matching it against the embedded JPEG image if one exists and has had its lens disortion auto-corrected by the camera. !TP_EXPOSURE_HISTMATCHING;Auto-Matched Tone Curve !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. -!TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual -!TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) !TP_FILMNEGATIVE_GUESS_TOOLTIP;Automatically set the red and blue ratios by picking two patches which had a neutral hue (no color) in the original scene. The patches should differ in brightness. Set the white balance afterwards. -!TP_FILMNEGATIVE_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick neutral spots -!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Baseline exposure !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only available if the selected DCP has one. @@ -2122,21 +2188,10 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_ICM_PROFILEINTENT;Rendering Intent !TP_ICM_SAVEREFERENCE;Save Reference Image !TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. -!TP_ICM_WORKING_TRC;Tone response curve: -!TP_ICM_WORKING_TRC_GAMMA;Gamma -!TP_ICM_WORKING_TRC_SLOPE;Slope -!TP_ICM_WORKING_TRC_TOOLTIP;Only for built-in profiles. -!TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected -!TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected !TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. -!TP_LENSPROFILE_USE_HEADER;Correct -!TP_LOCALCONTRAST_DARKNESS;Darkness level -!TP_LOCALCONTRAST_LIGHTNESS;Lightness level !TP_PDSHARPENING_LABEL;Capture Sharpening -!TP_PREPROCESS_LINEDENOISE_DIRECTION_BOTH;Both !TP_PREPROCESS_LINEDENOISE_DIRECTION_PDAF_LINES;Horizontal only on PDAF rows !TP_PREPROCESS_PDAFLINESFILTER;PDAF lines filter -!TP_PRSHARPENING_LABEL;Post-Resize Sharpening !TP_PRSHARPENING_TOOLTIP;Sharpens the image after resizing. Only works when the "Lanczos" resizing method is used. It is impossible to preview the effects of this tool. See RawPedia for usage instructions. !TP_RAWCACORR_AUTOIT_TOOLTIP;This setting is available if "Auto-correction" is checked.\nAuto-correction is conservative, meaning that it often does not correct all chromatic aberration.\nTo correct the remaining chromatic aberration, you can use up to five iterations of automatic chromatic aberration correction.\nEach iteration will reduce the remaining chromatic aberration from the last iteration at the cost of additional processing time. !TP_RAW_BORDER;Border @@ -2147,44 +2202,22 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_RAW_IMAGENUM_TOOLTIP;Some raw files consist of several sub-images (Pentax/Sony Pixel Shift, Pentax 3-in-1 HDR, Canon Dual Pixel, Fuji EXR).\n\nWhen using any demosaicing method other than Pixel Shift, this selects which sub-image is used.\n\nWhen using the Pixel Shift demosaicing method on a Pixel Shift raw, all sub-images are used, and this selects which sub-image should be used for moving parts. !TP_RAW_NONE;None (Shows sensor pattern) !TP_RAW_PIXELSHIFT;Pixel Shift -!TP_RAW_PIXELSHIFTBLUR;Blur motion mask -!TP_RAW_PIXELSHIFTDMETHOD;Demosaic method for motion !TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;The default value of 0 should work fine for base ISO.\nHigher values increase sensitivity of motion detection.\nChange in small steps and watch the motion mask while changing.\nIncrease sensitivity for underexposed or high ISO images. -!TP_RAW_PIXELSHIFTEQUALBRIGHT;Equalize brightness of frames !TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL;Equalize per channel !TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Enabled: Equalize the RGB channels individually.\nDisabled: Use same equalization factor for all channels. !TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Equalize the brightness of the frames to the brightness of the selected frame.\nIf there are overexposed areas in the frames select the brightest frame to avoid magenta color cast in overexposed areas or enable motion correction. !TP_RAW_PIXELSHIFTGREEN;Check green channel for motion -!TP_RAW_PIXELSHIFTHOLEFILL;Fill holes in motion mask -!TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Fill holes in motion mask -!TP_RAW_PIXELSHIFTMEDIAN;Use median for moving parts !TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Use median of all frames instead of selected frame for regions with motion.\nRemoves objects which are at different places in all frames.\nGives motion effect on slow moving (overlapping) objects. -!TP_RAW_PIXELSHIFTMOTIONMETHOD;Motion Correction -!TP_RAW_PIXELSHIFTNONGREENCROSS;Check red/blue channels for motion -!TP_RAW_PIXELSHIFTSHOWMOTION;Show motion mask -!TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Show only motion mask -!TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Shows the motion mask without the image. !TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Overlays the image with a green mask showing the regions with motion. !TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;The default radius of 1.0 usually fits well for base ISO.\nIncrease the value for high ISO shots, 5.0 is a good starting point.\nWatch the motion mask while changing the value. -!TP_RAW_PIXELSHIFTSMOOTH;Smooth transitions !TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Smooth transitions between areas with motion and areas without.\nSet to 0 to disable transition smoothing.\nSet to 1 to either get the AMaZE/LMMSE result of the selected frame (depending on whether "Use LMMSE" is selected), or the median of all four frames if "Use median" is selected. -!TP_RESIZE_ALLOW_UPSCALING;Allow Upscaling -!TP_RETINEX_CURVEEDITOR_CD;L=f(L) !TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminance according to luminance L=f(L)\nCorrect raw data to reduce halos and artifacts. -!TP_RETINEX_CURVEEDITOR_LH;Strength=f(H) !TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. -!TP_RETINEX_CURVEEDITOR_MAP;L=f(L) !TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! !TP_RETINEX_FREEGAMMA;Free gamma !TP_RETINEX_GAINOFFS;Gain and Offset (brightness) !TP_RETINEX_GAINTRANSMISSION;Gain transmission !TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce the transmission map to achieve the desired luminance.\nThe x-axis is the transmission.\nThe y-axis is the gain. -!TP_RETINEX_GAMMA;Gamma -!TP_RETINEX_GAMMA_FREE;Free -!TP_RETINEX_GAMMA_HIGH;High -!TP_RETINEX_GAMMA_LOW;Low -!TP_RETINEX_GAMMA_MID;Middle -!TP_RETINEX_GAMMA_NONE;None !TP_RETINEX_GAMMA_TOOLTIP;Restore tones by applying gamma before and after Retinex. Different from Retinex curves or others curves (Lab, Exposure, etc.). !TP_RETINEX_GRAD;Transmission gradient !TP_RETINEX_GRADS;Strength gradient @@ -2192,8 +2225,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_RETINEX_GRAD_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Variance and Threshold are reduced when iterations increase, and conversely. !TP_RETINEX_HIGHLIG;Highlight !TP_RETINEX_HIGHLIGHT_TOOLTIP;Increase action of High algorithm.\nMay require you to re-adjust "Neighboring pixels" and to increase the "White-point correction" in the Raw tab -> Raw White Points tool. -!TP_RETINEX_HSLSPACE_LIN;HSL-Linear -!TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic !TP_RETINEX_ITER;Iterations (Tone-mapping) !TP_RETINEX_ITERF;Tone mapping !TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. @@ -2219,31 +2250,21 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_RETINEX_VIEW_METHOD_TOOLTIP;Standard - Normal display.\nMask - Displays the mask.\nUnsharp mask - Displays the image with a high radius unsharp mask.\nTransmission - Auto/Fixed - Displays the file transmission-map, before any action on contrast and brightness.\n\nAttention: the mask does not correspond to reality, but is amplified to make it more visible. !TP_RETINEX_VIEW_TRAN;Transmission - Auto !TP_RETINEX_VIEW_TRAN2;Transmission - Fixed -!TP_SHARPENING_BLUR;Blur radius !TP_SHARPENING_ITERCHECK;Auto limit iterations !TP_SHARPENING_RADIUS_BOOST;Corner radius boost !TP_SOFTLIGHT_LABEL;Soft Light !TP_TM_FATTAL_ANCHOR;Anchor -!TP_TM_FATTAL_LABEL;Dynamic Range Compression !TP_WAVELET_B2;Residual !TP_WAVELET_BALANCE;Contrast balance d/v-h !TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chroma or residual tone mapping are activated, the effect due to balance is amplified. !TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chroma balance. -!TP_WAVELET_BASLI;Slider -!TP_WAVELET_BATYPE;Contrast balance method -!TP_WAVELET_CBENAB;Toning and Color Balance !TP_WAVELET_CB_TOOLTIP;For strong values product color-toning by combining it or not with levels decomposition 'toning'\nFor low values you can change the white balance of the background (sky, ...) without changing that of the front plane, generally more contrasted -!TP_WAVELET_CH1;Whole chroma range -!TP_WAVELET_CH2;Saturated/pastel -!TP_WAVELET_CH3;Link contrast levels !TP_WAVELET_CHR;Chroma-contrast link strength !TP_WAVELET_CHRO;Saturated/pastel threshold !TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. !TP_WAVELET_CHR_TOOLTIP;Adjusts chroma as a function of "contrast levels" and "chroma-contrast link strength" -!TP_WAVELET_CHSL;Sliders !TP_WAVELET_CHTYPE;Chrominance method !TP_WAVELET_COLORT;Opacity Red-Green -!TP_WAVELET_COMPGAMMA;Compression gamma !TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allows you to equilibrate the data and histogram. !TP_WAVELET_COMPTM;Tone mapping !TP_WAVELET_CONTEDIT;'After' contrast curve @@ -2251,9 +2272,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (abscissa).\nLow abscissa values represent small local contrast (real values about 10..20).\n50% abscissa represents average local contrast (real value about 100..300).\n66% abscissa represents standard deviation of local contrast (real value about 300..800).\n100% abscissa represents maximum local contrast (real value about 3000..8000). !TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) !TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function of hue.\nTake care not to overwrite changes made with the Gamut sub-tool's hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. -!TP_WAVELET_CURVEEDITOR_CL;L !TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. -!TP_WAVELET_CURVEEDITOR_HH;HH !TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. !TP_WAVELET_DAUB;Edge performance !TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. @@ -2264,21 +2283,14 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. !TP_WAVELET_EDGESENSI;Edge sensitivity !TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. -!TP_WAVELET_EDGTHRESH;Detail !TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centered on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. !TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. -!TP_WAVELET_EDTYPE;Local contrast method -!TP_WAVELET_FINAL;Final Touchup -!TP_WAVELET_FINEST;Finest -!TP_WAVELET_HIGHLIGHT;Highlight luminance range -!TP_WAVELET_HS1;Whole luminance range !TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. !TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. !TP_WAVELET_ITER;Delta balance levels !TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. !TP_WAVELET_LABEL;Wavelet Levels !TP_WAVELET_LARGEST;Coarsest -!TP_WAVELET_LEVCH;Chroma !TP_WAVELET_LEVDIR_ALL;All levels in all directions !TP_WAVELET_LEVDIR_INF;Below or equal the level !TP_WAVELET_LEVDIR_ONE;One level @@ -2286,9 +2298,6 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_WAVELET_LEVELS;Wavelet levels !TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. !TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 -!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength -!TP_WAVELET_LOWLIGHT;Shadow luminance range -!TP_WAVELET_MEDGREINF;First level !TP_WAVELET_MEDILEV_TOOLTIP;When you enable Edge Detection, it is recommanded:\n- to disabled low contrast levels to avoid artifacts,\n- to use high values of gradient sensitivity.\n\nYou can modulate the strength with 'refine' from Denoise and Refine. !TP_WAVELET_NOISE;Denoise and Refine !TP_WAVELET_NPTYPE_TOOLTIP;This algorithm uses the proximity of a pixel and eight of its neighbors. If less difference, edges are reinforced. @@ -2296,14 +2305,10 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_WAVELET_OPACITYW;Contrast balance d/v-h curve !TP_WAVELET_OPACITYWL;Final local contrast !TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. -!TP_WAVELET_PASTEL;Pastel chroma -!TP_WAVELET_RESCHRO;Chroma !TP_WAVELET_RESID;Residual Image -!TP_WAVELET_SAT;Saturated chroma !TP_WAVELET_SETTINGS;Wavelet Settings !TP_WAVELET_SKIN;Skin targetting/protection !TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. -!TP_WAVELET_SKY;Sky targetting/protection !TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. !TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). !TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. @@ -2312,8 +2317,5 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_WAVELET_TILESIZE;Tiling method !TP_WAVELET_TILESLIT;Little tiles !TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. -!TP_WAVELET_TMSTRENGTH;Compression strength !TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. -!TP_WAVELET_TON;Toning -!TP_WBALANCE_TEMPBIAS;AWB temperature bias !TP_WBALANCE_TEMPBIAS_TOOLTIP;Allows to alter the computation of the "auto white balance"\nby biasing it towards warmer or cooler temperatures. The bias\nis expressed as a percentage of the computed temperature,\nso that the result is given by "computedTemp + computedTemp * bias". diff --git a/rtdata/languages/default b/rtdata/languages/default index bbd91e908..3f9cbba41 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1150,6 +1150,7 @@ HISTORY_MSG_909;Local - Contrast Wavelet ES show HISTORY_MSG_910;Local - Wavelet Edge performance HISTORY_MSG_911;Local - Blur Chroma Luma HISTORY_MSG_912;Local - Blur Guide filter strength +HISTORY_MSG_CAT02PRESET;Cat02 automatic preset HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -1173,6 +1174,7 @@ HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +HISTORY_MSG_FILMNEGATIVE_FILMBASE;Film base color HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values HISTORY_MSG_HISTMATCHING;Auto-matched tone curve HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries @@ -1181,6 +1183,7 @@ HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type HISTORY_MSG_ICM_WORKING_GAMMA;Working - Gamma HISTORY_MSG_ICM_WORKING_SLOPE;Working - Slope HISTORY_MSG_ICM_WORKING_TRC_METHOD;Working - TRC method +HISTORY_MSG_ILLUM;Illuminant HISTORY_MSG_LOCALCONTRAST_AMOUNT;Local Contrast - Amount HISTORY_MSG_LOCALCONTRAST_DARKNESS;Local Contrast - Darkness HISTORY_MSG_LOCALCONTRAST_ENABLED;Local Contrast @@ -1208,8 +1211,34 @@ HISTORY_MSG_SHARPENING_CONTRAST;Sharpening - Contrast threshold HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength +HISTORY_MSG_TEMPOUT;CAM02 automatic temperature HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anchor HISTORY_MSG_TRANS_Method;Geometry - Method +HISTORY_MSG_WAVBALCHROM;Equalizer chrominance +HISTORY_MSG_WAVBALLUM;Equalizer luminance +HISTORY_MSG_WAVCHROMFI;Chroma fine +HISTORY_MSG_WAVCHROMCO;Chroma coarse +HISTORY_MSG_WAVCLARI;Clarity +HISTORY_MSG_WAVEDGS;Edge stopping +HISTORY_MSG_WAVMERGEC;Merge C +HISTORY_MSG_WAVMERGEL;Merge L +HISTORY_MSG_WAVRADIUS;Radius Shadows-Highlight +HISTORY_MSG_WAVSCALE;Scale +HISTORY_MSG_WAVSHOWMASK;Show wavelet mask +HISTORY_MSG_WAVSIGMA;Damper +HISTORY_MSG_WAVSOFTRAD;Soft radius clarity +HISTORY_MSG_WAVSOFTRADEND;Soft radius final +HISTORY_MSG_WAVUSHAMET;Clarity method +HISTORY_MSG_THRESWAV;Balance threshold +HISTORY_MSG_BLUWAV;Damper +HISTORY_MSG_WAVOLDSH;Old algorithm +HISTORY_MSG_WAVOFFSET;Offset +HISTORY_MSG_WAVLOWTHR;Threshold low contrast +HISTORY_MSG_BLSHAPE;Blur by level +HISTORY_MSG_WAVBL;Blur levels +HISTORY_MSG_BLURWAV;Blur luminance +HISTORY_MSG_BLURCWAV;Blur chroma +HISTORY_MSG_EDGEFFECT;Edge Damper HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -1857,6 +1886,16 @@ TP_COLORAPP_GAMUT;Gamut control (L*a*b*) TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. TP_COLORAPP_HUE;Hue (h) TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +TP_COLORAPP_ILLUM;Illuminant +TP_COLORAPP_ILLUM_TOOLTIP;Select the illuminant closest to the shooting conditions.\nIn general D50, but it can change depending on the time and lattitude. +TP_COLORAPP_ILA;Incandescent StdA 2856K +TP_COLORAPP_IL41;D41 +TP_COLORAPP_IL50;D50 +TP_COLORAPP_IL55;D55 +TP_COLORAPP_IL60;D60 +TP_COLORAPP_IL65;D65 +TP_COLORAPP_IL75;D75 +TP_COLORAPP_ILFREE;Free TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 TP_COLORAPP_LABEL_CAM02;Image Adjustments TP_COLORAPP_LABEL_SCENE;Scene Conditions @@ -1868,6 +1907,8 @@ TP_COLORAPP_MODEL;WP Model TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Viewing Conditions.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Viewing Conditions.\n\nFree temp+green + CAT02 + [output]: temp and green are selected by the user, the output device's white balance is set in Viewing Conditions. TP_COLORAPP_NEUTRAL;Reset TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values +TP_COLORAPP_PRESETCAT02;Preset cat02 automatic +TP_COLORAPP_PRESETCAT02_TIP;Set combobox, sliders, temp, green so that Cat02 automatic is preset.\nYou can change illuminant shooting conditions.\nYou must change Cat02 adaptation Viewing conditions if need.\nYou can change Temperature and Tint Viewing conditions if need, and other settings if need. TP_COLORAPP_RSTPRO;Red & skin-tones protection TP_COLORAPP_RSTPRO_TOOLTIP;Red & skin-tones protection affects both sliders and curves. TP_COLORAPP_SURROUND;Surround @@ -1884,7 +1925,9 @@ TP_COLORAPP_TCMODE_LABEL2;Curve mode 2 TP_COLORAPP_TCMODE_LABEL3;Curve chroma mode TP_COLORAPP_TCMODE_LIGHTNESS;Lightness TP_COLORAPP_TCMODE_SATUR;Saturation -TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant, always set Tint=1.\n\nA temp=2856\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 +TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant, always set Tint=1.\n\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504 +TP_COLORAPP_TEMP2_TOOLTIP;Either symmetrical mode temp = White balance.\nEither select illuminant always set Tint=1.\n\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504 +TP_COLORAPP_TEMPOUT_TOOLTIP;Disable to chnage temperature and tint TP_COLORAPP_TONECIE;Tone mapping using CIECAM02 TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect. TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP;Absolute luminance of the viewing environment\n(usually 16 cd/m²). @@ -2083,6 +2126,9 @@ TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points TP_EXPOS_WHITEPOINT_LABEL;Raw White Points TP_FILMNEGATIVE_BLUE;Blue ratio +TP_FILMNEGATIVE_FILMBASE_PICK;Pick film base color +TP_FILMNEGATIVE_FILMBASE_TOOLTIP;Pick a spot of unexposed film (eg. the border between frames), to get the actual film base color values, and save them in the processing profile.\nThis makes it easy to get a more consistent color balance when batch-processing multiple pictures from the same roll.\nAlso use this when the converted image is extremely dark, bright, or color-unbalanced. +TP_FILMNEGATIVE_FILMBASE_VALUES;Film base RGB: TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) TP_FILMNEGATIVE_GUESS_TOOLTIP;Automatically set the red and blue ratios by picking two patches which had a neutral hue (no color) in the original scene. The patches should differ in brightness. Set the white balance afterwards. TP_FILMNEGATIVE_LABEL;Film Negative @@ -3196,11 +3242,16 @@ TP_WAVELET_BACKGROUND;Background TP_WAVELET_BACUR;Curve TP_WAVELET_BALANCE;Contrast balance d/v-h TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chroma or residual tone mapping are activated, the effect due to balance is amplified. -TP_WAVELET_BALCHRO;Chroma balance +TP_WAVELET_BALCHRO;Chrominance balance TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chroma balance. +TP_WAVELET_BALCHROM;Denoise Equalizer Blue-Red +TP_WAVELET_BALLUM;Denoise Equalizer White-Black TP_WAVELET_BANONE;None TP_WAVELET_BASLI;Slider TP_WAVELET_BATYPE;Contrast balance method +TP_WAVELET_BLCURVE;Blur by levels +TP_WAVELET_BLURFRAME;Blur +TP_WAVELET_BLUWAV;Damper TP_WAVELET_CBENAB;Toning and Color Balance TP_WAVELET_CB_TOOLTIP;For strong values product color-toning by combining it or not with levels decomposition 'toning'\nFor low values you can change the white balance of the background (sky, ...) without changing that of the front plane, generally more contrasted TP_WAVELET_CCURVE;Local contrast @@ -3210,16 +3261,24 @@ TP_WAVELET_CH3;Link contrast levels TP_WAVELET_CHCU;Curve TP_WAVELET_CHR;Chroma-contrast link strength TP_WAVELET_CHRO;Saturated/pastel threshold +TP_WAVELET_CHROFRAME;Denoise Chrominance +TP_WAVELET_CHROMAFRAME;Chroma +TP_WAVELET_CHROMCO;Chrominance Coarse +TP_WAVELET_CHROMFI;Chrominance Fine TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. TP_WAVELET_CHR_TOOLTIP;Adjusts chroma as a function of "contrast levels" and "chroma-contrast link strength" +TP_WAVELET_CHRWAV;Blur chroma TP_WAVELET_CHSL;Sliders TP_WAVELET_CHTYPE;Chrominance method +TP_WAVELET_CLA;Clarity +TP_WAVELET_CLARI;Sharp-mask and Clarity TP_WAVELET_COLORT;Opacity Red-Green TP_WAVELET_COMPCONT;Contrast TP_WAVELET_COMPGAMMA;Compression gamma TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allows you to equilibrate the data and histogram. TP_WAVELET_COMPTM;Tone mapping TP_WAVELET_CONTEDIT;'After' contrast curve +TP_WAVELET_CONTFRAME;Contrast - Compression TP_WAVELET_CONTR;Gamut TP_WAVELET_CONTRA;Contrast TP_WAVELET_CONTRAST_MINUS;Contrast - @@ -3255,6 +3314,8 @@ TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +TP_WAVELET_EDEFFECT;Damper +TP_WAVELET_EDEFFECT_TOOLTIP;This slider controls how wide the range of contrast values are that receive the maximum effect from the tool.\nMaximum value (2.5) disabled the tool TP_WAVELET_EDGESENSI;Edge sensitivity TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. TP_WAVELET_EDGTHRESH;Detail @@ -3293,10 +3354,13 @@ TP_WAVELET_LEVZERO;Level 1 TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength TP_WAVELET_LIPST;Enhanced algoritm TP_WAVELET_LOWLIGHT;Shadow luminance range +TP_WAVELET_LOWTHR_TOOLTIP;Prevents amplification of fine textures and noise TP_WAVELET_MEDGREINF;First level TP_WAVELET_MEDI;Reduce artifacts in blue sky TP_WAVELET_MEDILEV;Edge detection TP_WAVELET_MEDILEV_TOOLTIP;When you enable Edge Detection, it is recommanded:\n- to disabled low contrast levels to avoid artifacts,\n- to use high values of gradient sensitivity.\n\nYou can modulate the strength with 'refine' from Denoise and Refine. +TP_WAVELET_MERGEC;Merge Chroma +TP_WAVELET_MERGEL;Merge Luma TP_WAVELET_NEUTRAL;Neutral TP_WAVELET_NOIS;Denoise TP_WAVELET_NOISE;Denoise and Refine @@ -3305,25 +3369,35 @@ TP_WAVELET_NPLOW;Low TP_WAVELET_NPNONE;None TP_WAVELET_NPTYPE;Neighboring pixels TP_WAVELET_NPTYPE_TOOLTIP;This algorithm uses the proximity of a pixel and eight of its neighbors. If less difference, edges are reinforced. +TP_WAVELET_OLDSH;Algorithm using negatives values TP_WAVELET_OPACITY;Opacity Blue-Yellow TP_WAVELET_OPACITYW;Contrast balance d/v-h curve TP_WAVELET_OPACITYWL;Final local contrast TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. TP_WAVELET_PASTEL;Pastel chroma TP_WAVELET_PROC;Process +TP_WAVELET_RADIUS;Radius Shadows - Highlight TP_WAVELET_RE1;Reinforced TP_WAVELET_RE2;Unchanged TP_WAVELET_RE3;Reduced -TP_WAVELET_RESCHRO;Chroma +TP_WAVELET_RESBLUR;Blur Luminance +TP_WAVELET_RESBLURC;Blur Chroma +TP_WAVELET_RESCHRO;Intensity TP_WAVELET_RESCON;Shadows TP_WAVELET_RESCONH;Highlights TP_WAVELET_RESID;Residual Image TP_WAVELET_SAT;Saturated chroma TP_WAVELET_SETTINGS;Wavelet Settings +TP_WAVELET_SHA;Sharp mask +TP_WAVELET_SHFRAME;Shadows/Highlights +TP_WAVELET_SHOWMASK;Show wavelet 'mask' +TP_WAVELET_SIGMA;Damper +TP_WAVELET_SIGMA_TOOLTIP;The effect of the contrast sliders is stronger in medium contrast details, and weaker in high and low contrast details.\n With this slider you can control how quickly the effect dampens towards the extreme contrasts.\n The higher the slider is set, the wider the range of contrasts which will get a strong change, and the higher the risk to generate artifacts.\n The lower it is, the more pinpoint will the effect be applied to a narrow range of contrast values. TP_WAVELET_SKIN;Skin targetting/protection TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. TP_WAVELET_SKY;Sky targetting/protection TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +TP_WAVELET_SOFTRAD;Soft Radius TP_WAVELET_STREN;Strength TP_WAVELET_STRENGTH;Strength TP_WAVELET_SUPE;Extra @@ -3332,17 +3406,32 @@ TP_WAVELET_THRESHOLD;Highlight levels TP_WAVELET_THRESHOLD2;Shadow levels TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +TP_WAVELET_THRESWAV;Balance Threshold TP_WAVELET_THRH;Highlights threshold -TP_WAVELET_TILESBIG;Big tiles +TP_WAVELET_TILESBIG;Tiles TP_WAVELET_TILESFULL;Full image TP_WAVELET_TILESIZE;Tiling method TP_WAVELET_TILESLIT;Little tiles TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +TP_WAVELET_BL;Blur levels +TP_WAVELET_TMEDGS;Edge stopping +TP_WAVELET_TMSCALE;Scale TP_WAVELET_TMSTRENGTH;Compression strength -TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. -TP_WAVELET_TMTYPE;Compression method +TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. +TP_WAVELET_TMEDGS;Edge stopping TP_WAVELET_TON;Toning +TP_WAVELET_TMTYPE;Compression method +TP_WAVELET_USH;None +TP_WAVELET_USHARP;Clarity method +TP_WAVELET_USHARP_TOOLTIP;Origin : the source file is the file before Wavelet.\nWavelet : the source file is the file including wavelet threatment +TP_WAVELET_USH_TOOLTIP;If you select Sharp-mask, wavelet settings will be automatically positioned :\nBackground=black, Process=below, level=3...you can change level between 1 and 4.\n\nIf you select Clarity, wavelet settings will be automatically positioned :\nBackground=residual, Process=above, level=7..you can change level between 5 and 10 and wavelet levels. +TP_WAVELET_WAVLOWTHR;Low contrast threshold +TP_WAVELET_WAVOFFSET;Offset +TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between shadows and highlights.\nHigh values here will amplify the contrast change of the highlights, whereas low values will amplify the contrast change of the shadows.\nAlong with a low Damper value you will able to select the contrasts that will be enhanced. TP_WBALANCE_AUTO;Auto +TP_WBALANCE_AUTOITCGREEN;Auto iterate temperature correlation +TP_WBALANCE_AUTOOLD;Auto RGB grey +TP_WBALANCE_AUTO_HEADER;Autos TP_WBALANCE_CAMERA;Camera TP_WBALANCE_CLOUDY;Cloudy TP_WBALANCE_CUSTOM;Custom @@ -3384,6 +3473,8 @@ TP_WBALANCE_SOLUX41;Solux 4100K TP_WBALANCE_SOLUX47;Solux 4700K (vendor) TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) TP_WBALANCE_SPOTWB;Use the pipette to pick the white balance from a neutral patch in the preview. +TP_WBALANCE_STUDLABEL;Student Itcwb: %1 +TP_WBALANCE_STUDLABEL_TOOLTIP;Display calculated Student correlation\nThe lower the student value, the better the correlation\nValues below 0.002 are excellent\nValues below 0.005 are very good\nValues below 0.01 are good\nValues below 0.05 are good enough\nValues above 0.5 are poor\nVery good Student test results does not mean that the WB is good, if the illuminant is non-standard the results are erratic.\nStudent=1000 means the calculations were not restarted but results are probably goods, use previous results TP_WBALANCE_TEMPBIAS;AWB temperature bias TP_WBALANCE_TEMPBIAS_TOOLTIP;Allows to alter the computation of the "auto white balance"\nby biasing it towards warmer or cooler temperatures. The bias\nis expressed as a percentage of the computed temperature,\nso that the result is given by "computedTemp + computedTemp * bias". TP_WBALANCE_TEMPERATURE;Temperature diff --git a/rtdata/options/options.osx b/rtdata/options/options.osx index 58e0a5604..c83aea179 100644 --- a/rtdata/options/options.osx +++ b/rtdata/options/options.osx @@ -9,6 +9,7 @@ # which can be useful if you want to keep the application and all the cache data in a single place, # an external HD for example MultiUser=true +UseSystemTheme=false [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) @@ -38,5 +39,6 @@ CustomProfileBuilder= #ImgDefault=Neutral [GUI] -FontFamily=Helvetica Regular -CPFontFamily=Helvetica Regular +# Set the included font as default +FontFamily=Droid Sans Mono Slashed +CPFontFamily=Droid Sans Mono Slashed diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index f4d082199..fa9788af0 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -790,12 +790,12 @@ float* RawImageSource::CA_correct_RT( for (int m = 0; m < polyord; m++) { double powHblock = powHblockInit; 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(blockwt[vblock * hblsz + hblock]); powHblock *= hblock; } 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(bstemp[dir]) * static_cast(blockwt[vblock * hblsz + hblock]); powHblockInit *= hblock; } powVblockInit *= vblock; @@ -848,7 +848,7 @@ float* RawImageSource::CA_correct_RT( for (int top = -border; top < height; top += ts - border2) { for (int left = -border; left < width - (W & 1); left += ts - border2) { memset(bufferThr, 0, buffersizePassTwo); - float lblockshifts[2][2]; + double lblockshifts[2][2]; const int vblock = ((top + border) / (ts - border2)) + 1; const int hblock = ((left + border) / (ts - border2)) + 1; const int bottom = min(top + ts, height + border); @@ -1036,8 +1036,8 @@ float* RawImageSource::CA_correct_RT( } if (!autoCA) { - float hfrac = -((float)(hblock - 0.5) / (hblsz - 2) - 0.5); - float vfrac = -((float)(vblock - 0.5) / (vblsz - 2) - 0.5) * height / width; + double hfrac = -((hblock - 0.5) / (hblsz - 2) - 0.5); + double vfrac = -((vblock - 0.5) / (vblsz - 2) - 0.5) * height / width; lblockshifts[0][0] = 2 * vfrac * cared; lblockshifts[0][1] = 2 * hfrac * cared; lblockshifts[1][0] = 2 * vfrac * cablue; @@ -1058,7 +1058,7 @@ float* RawImageSource::CA_correct_RT( } 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][1] = LIM(lblockshifts[0][1], -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 shiftvfloor[c] = floor((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]); } shiftvfrac[c] = fabs(lblockshifts[c>>1][0] - shiftvfloor[c]); shifthfloor[c] = floor((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]); } shifthfrac[c] = fabs(lblockshifts[c>>1][1] - shifthfloor[c]); diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 6538ecc61..49389c89f 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -1,35 +1,60 @@ -include_directories(${EXTRA_INCDIR} - ${EXPAT_INCLUDE_DIRS} - ${FFTW3F_INCLUDE_DIRS} - ${GLIB2_INCLUDE_DIRS} - ${GLIBMM_INCLUDE_DIRS} - ${GOBJECT_INCLUDE_DIRS} - ${GTHREAD_INCLUDE_DIRS} - ${GTKMM_INCLUDE_DIRS} - ${GTK_INCLUDE_DIRS} - ${IPTCDATA_INCLUDE_DIRS} - ${LCMS_INCLUDE_DIRS} - ${LENSFUN_INCLUDE_DIRS} - ${RSVG_INCLUDE_DIRS} -) +if(EXTRA_INCDIR) + include_directories("${EXTRA_INCDIR}") +endif() +if(EXPAT_INCLUDE_DIRS) + include_directories("${EXPAT_INCLUDE_DIRS}") +endif() +if(FFTW3F_INCLUDE_DIRS) + include_directories("${FFTW3F_INCLUDE_DIRS}") +endif() +if(GLIB2_INCLUDE_DIRS) + include_directories("${GLIB2_INCLUDE_DIRS}") +endif() +if(GLIBMM_INCLUDE_DIRS) + include_directories("${GLIBMM_INCLUDE_DIRS}") +endif() +if(GOBJECT_INCLUDE_DIRS) + include_directories("${GOBJECT_INCLUDE_DIRS}") +endif() +if(GTHREAD_INCLUDE_DIRS) + include_directories("${GTHREAD_INCLUDE_DIRS}") +endif() +if(GTKMM_INCLUDE_DIRS) + include_directories("${GTKMM_INCLUDE_DIRS}") +endif() +if(GTK_INCLUDE_DIRS) + include_directories("${GTK_INCLUDE_DIRS}") +endif() +if(IPTCDATA_INCLUDE_DIRS) + include_directories("${IPTCDATA_INCLUDE_DIRS}") +endif() +if(LCMS_INCLUDE_DIRS) + include_directories("${LCMS_INCLUDE_DIRS}") +endif() +if(LENSFUN_INCLUDE_DIRS) + include_directories("${LENSFUN_INCLUDE_DIRS}") +endif() +if(RSVG_INCLUDE_DIRS) + include_directories("${RSVG_INCLUDE_DIRS}") +endif() if(NOT WITH_SYSTEM_KLT) include_directories("${CMAKE_SOURCE_DIR}/rtengine/klt") else() - include_directories(${KLT_INCLUDE_DIRS}) + include_directories("${KLT_INCLUDE_DIRS}") endif() link_directories("${PROJECT_SOURCE_DIR}/rtexif" - ${EXPAT_LIBRARY_DIRS} - ${EXTRA_LIBDIR} - ${FFTW3F_LIBRARY_DIRS} - ${GLIB2_LIBRARY_DIRS} - ${GLIBMM_LIBRARY_DIRS} - ${GOBJECT_LIBRARY_DIRS} - ${GTHREAD_LIBRARY_DIRS} - ${IPTCDATA_LIBRARY_DIRS} - ${LCMS_LIBRARY_DIRS} - ${LENSFUN_LIBRARY_DIRS} - ${RSVG_LIBRARY_DIRS} + "${EXPAT_LIBRARY_DIRS}" + "${EXTRA_LIBDIR}" + "${FFTW3F_LIBRARY_DIRS}" + "${GLIB2_LIBRARY_DIRS}" + "${GLIBMM_LIBRARY_DIRS}" + "${GOBJECT_LIBRARY_DIRS}" + "${GTHREAD_LIBRARY_DIRS}" + "${IPTCDATA_LIBRARY_DIRS}" + "${LCMS_LIBRARY_DIRS}" + "${LENSFUN_LIBRARY_DIRS}" + "${RSVG_LIBRARY_DIRS}" ) set(CAMCONSTSFILE "camconst.json") @@ -101,6 +126,7 @@ set(RTENGINESOURCEFILES ipretinex.cc ipshadowshighlights.cc ipsharpen.cc + ipsharpenedges.cc ipsoftlight.cc iptransform.cc ipvibrance.cc @@ -112,6 +138,7 @@ set(RTENGINESOURCEFILES lj92.c lmmse_demosaic.cc loadinitial.cc + munselllch.cc myfile.cc panasonic_decoders.cc pdaflinesfilter.cc @@ -165,13 +192,13 @@ endif() include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}") -add_library(rtengine STATIC ${RTENGINESOURCEFILES}) +add_library(rtengine STATIC "${RTENGINESOURCEFILES}") add_dependencies(rtengine UpdateInfo) # It may be nice to store library version too if(BUILD_SHARED_LIBS) - install(TARGETS rtengine DESTINATION ${LIBDIR}) + install(TARGETS rtengine DESTINATION "${LIBDIR}") endif() set_target_properties(rtengine PROPERTIES COMPILE_FLAGS "${RTENGINE_CXX_FLAGS}") diff --git a/rtengine/EdgePreservingDecomposition.cc b/rtengine/EdgePreservingDecomposition.cc index a8d3575cf..9e71b6a06 100644 --- a/rtengine/EdgePreservingDecomposition.cc +++ b/rtengine/EdgePreservingDecomposition.cc @@ -55,7 +55,7 @@ float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), fl #endif for(int ii = 0; ii < n; ii++) { - rs += r[ii] * s[ii]; + rs += static_cast(r[ii]) * static_cast(s[ii]); } //Search direction d. @@ -84,15 +84,15 @@ float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), fl #endif for(int ii = 0; ii < n; ii++) { - ab += d[ii] * ax[ii]; + ab += static_cast(d[ii]) * static_cast(ax[ii]); } - if(ab == 0.0f) { + if(ab == 0.0) { break; //So unlikely. It means perfectly converged or singular, stop either way. } ab = rs / ab; - + float abf = ab; //Update x and r with this step size. double rms = 0.0; // use double precision for large summations #ifdef _OPENMP @@ -100,15 +100,15 @@ float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), fl #endif for(int ii = 0; ii < n; ii++) { - x[ii] += ab * d[ii]; - r[ii] -= ab * ax[ii]; //"Fast recursive formula", use explicit r = b - Ax occasionally? - rms += r[ii] * r[ii]; + x[ii] += abf * d[ii]; + r[ii] -= abf * ax[ii]; //"Fast recursive formula", use explicit r = b - Ax occasionally? + rms += rtengine::SQR(r[ii]); } rms = sqrtf(rms / n); //Quit? This probably isn't the best stopping condition, but ok. - if(rms < RMSResidual) { + if(rms < static_cast(RMSResidual)) { break; } @@ -129,20 +129,20 @@ float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), fl #endif for(int ii = 0; ii < n; ii++) { - rs += r[ii] * s[ii]; + rs += static_cast(r[ii]) * static_cast(s[ii]); } } ab = rs / ab; - + abf = ab; //Update search direction p. #ifdef _OPENMP #pragma omp parallel for #endif for(int ii = 0; ii < n; ii++) { - d[ii] = s[ii] + ab * d[ii]; + d[ii] = s[ii] + abf * d[ii]; } diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 297308a0b..894c72ce2 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -546,7 +546,7 @@ BENCHFUN const bool denoiseMethodRgb = (dnparams.dmethod == "RGB"); // init luma noisevarL const float noiseluma = static_cast(dnparams.luma); - const float noisevarL = (useNoiseLCurve && (denoiseMethodRgb || !isRAW)) ? static_cast(SQR(((noiseluma + 1.0) / 125.0) * (10. + (noiseluma + 1.0) / 25.0))) : static_cast(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); //printf("NL=%f \n",noisevarL); @@ -633,20 +633,20 @@ BENCHFUN if (dnparams.luma != 0 || dnparams.chroma != 0 || dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly") { // gamma transform for input data - float gam = dnparams.gamma; - float gamthresh = 0.001f; + double gam = dnparams.gamma; + constexpr double gamthresh = 0.001; if (!isRAW) {//reduce gamma under 1 for Lab mode ==> TIF and JPG - if (gam < 1.9f) { - gam = 1.f - (1.9f - gam) / 3.f; //minimum gamma 0.7 - } else if (gam >= 1.9f && gam <= 3.f) { - gam = (1.4f / 1.1f) * gam - 1.41818f; + if (gam < 1.9) { + gam = 1.0 - (1.9 - gam) / 3.0; //minimum gamma 0.7 + } else if (gam >= 1.9 && gam <= 3.0) { + gam = (1.4 / 1.1) * gam - 1.41818; } } LUTf gamcurve(65536, LUT_CLIP_BELOW); - float gamslope = exp(log(static_cast(gamthresh)) / gam) / gamthresh; + const double gamslope = exp(log(gamthresh) / gam) / gamthresh; if (denoiseMethodRgb) { Color::gammaf2lut(gamcurve, gam, gamthresh, gamslope, 65535.f, 32768.f); @@ -655,9 +655,9 @@ BENCHFUN } // inverse gamma transform for output data - float igam = 1.f / gam; - float igamthresh = gamthresh * gamslope; - float igamslope = 1.f / gamslope; + const float igam = 1.0 / gam; + const float igamthresh = gamthresh * gamslope; + const float igamslope = 1.0 / gamslope; LUTf igamcurve(65536, LUT_CLIP_BELOW); @@ -667,9 +667,9 @@ BENCHFUN Color::gammanf2lut(igamcurve, igam, 32768.f, 65535.f); } - const float gain = pow(2.0f, float(expcomp)); - float params_Ldetail = min(float(dnparams.Ldetail), 99.9f); // max out to avoid div by zero when using noisevar_Ldetail as divisor - float noisevar_Ldetail = SQR(static_cast(SQR(100. - params_Ldetail) + 50.*(100. - params_Ldetail)) * TS * 0.5f); + const float gain = std::pow(2.0, expcomp); + const double params_Ldetail = std::min(dnparams.Ldetail, 99.9); // max out to avoid div by zero when using noisevar_Ldetail as divisor + const float noisevar_Ldetail = SQR(SQR(100. - params_Ldetail) + 50.0 * (100.0 - params_Ldetail) * TS * 0.5); array2D tilemask_in(TS, TS); array2D tilemask_out(TS, TS); @@ -679,13 +679,13 @@ BENCHFUN for (int i = 0; i < TS; ++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 vmask2 = (i1 < 2 * 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_F * i1) / (2 * border))) : 1.f); for (int j = 0; j < TS; ++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_out[i][j] = (vmask2 * (j1 < 2 * 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_F * j1) / (2 * border))) : 1.0f)) + epsilon; } } @@ -881,19 +881,19 @@ BENCHFUN int height = tilebottom - tiletop; int width2 = (width + 1) / 2; float realred, realblue; - float interm_med = static_cast(dnparams.chroma) / 10.0; + float interm_med = dnparams.chroma / 10.0; float intermred, intermblue; if (dnparams.redchro > 0.) { - intermred = (dnparams.redchro / 10.); + intermred = dnparams.redchro / 10.0; } else { - intermred = static_cast(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.) { - intermblue = (dnparams.bluechro / 10.); + intermblue = dnparams.bluechro / 10.0; } else { - intermblue = static_cast(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) { @@ -1094,7 +1094,7 @@ BENCHFUN //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. //actual implementation only works with subsampling set to 1 - float interm_medT = static_cast(dnparams.chroma) / 10.0; + float interm_medT = dnparams.chroma / 10.0; bool execwavelet = true; if (!denoiseLuminance && interm_medT < 0.05f && dnparams.median && (dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly")) { @@ -2140,7 +2140,7 @@ float ImProcFunctions::Mad(const float * DataList, const int datalen) int count_ = count - histo[median - 1]; // interpolate - return (((median - 1) + (datalen / 2 - count_) / (static_cast(count - count_))) / 0.6745); + return (((median - 1) + (datalen / 2 - count_) / (static_cast(count - count_))) / 0.6745f); } float ImProcFunctions::MadRgb(const float * DataList, const int datalen) @@ -2174,7 +2174,7 @@ float ImProcFunctions::MadRgb(const float * DataList, const int datalen) // interpolate delete[] histo; - return (((median - 1) + (datalen / 2 - count_) / (static_cast(count - count_))) / 0.6745); + return (((median - 1) + (datalen / 2 - count_) / (static_cast(count - count_))) / 0.6745f); } @@ -2214,7 +2214,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5); const float eps = 0.01f; - if (edge == 1 || edge == 3) { + if (edge == 1 || edge == 3 || edge == 4) { maxlvl = 4; //for refine denoise edge wavelet } @@ -2294,7 +2294,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W } } - if (edge == 2) { + if (edge == 2 || edge == 4) { for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) { nvl[i] = vari[lvl] * SQR(noisevarlum[i]); } @@ -2721,7 +2721,7 @@ void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, f } } - if (edge == 2) { + if (edge == 2 || edge == 4) { for (int i = 0; i < W_L * H_L; ++i) { nvl[i] = vari[level] * SQR(noisevarlum[i]); } @@ -3074,7 +3074,7 @@ void ImProcFunctions::RGB_denoise_infoGamCurve(const procparams::DirPyrDenoisePa bool denoiseMethodRgb = (dnparams.dmethod == "RGB"); if (denoiseMethodRgb) { - gamslope = exp(log(static_cast(gamthresh)) / gam) / gamthresh; + gamslope = exp(log(static_cast(gamthresh)) / static_cast(gam)) / static_cast(gamthresh); Color::gammaf2lut(gamcurve, gam, gamthresh, gamslope, 65535.f, 32768.f); } else { Color::gammanf2lut(gamcurve, gam, 65535.f, 32768.f); @@ -3355,19 +3355,19 @@ void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, } float realred, realblue; - float interm_med = static_cast(dnparams.chroma) / 10.0; + float interm_med = dnparams.chroma / 10.0; float intermred, intermblue; if (dnparams.redchro > 0.) { - intermred = (dnparams.redchro / 10.); + intermred = dnparams.redchro / 10.0; } else { - intermred = static_cast(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.) { - intermblue = (dnparams.bluechro / 10.); + intermblue = dnparams.bluechro / 10.0; } else { - intermblue = static_cast(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; diff --git a/rtengine/LUT.h b/rtengine/LUT.h index a80e5996d..6ba7d570f 100644 --- a/rtengine/LUT.h +++ b/rtengine/LUT.h @@ -254,7 +254,6 @@ public: } // handy to sum up per thread histograms. #pragma omp simd speeds up the loop by about factor 3 for LUTu (uint32_t). - template::value>::type> LUT & operator+=(const LUT& rhs) { if (rhs.size == this->size) { diff --git a/rtengine/PF_correct_RT.cc b/rtengine/PF_correct_RT.cc index 9a95b8e2f..15b7b21ee 100644 --- a/rtengine/PF_correct_RT.cc +++ b/rtengine/PF_correct_RT.cc @@ -103,7 +103,7 @@ void ImProcFunctions::PF_correct_RT(LabImage * lab, double radius, int thresh) // no precalculated values without SSE => calculate const float HH = xatan2f(lab->b[i][j], lab->a[i][j]); #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) { 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 - chromave += chroma; + chromave += static_cast(chroma); fringe[i * width + j] = chroma; } } } chromave /= height * width; - if (chromave > 0.0) { // now as chromave is calculated, we postprocess fringe to reduce the number of divisions in future + const float chromavef = chromave; #ifdef _OPENMP #pragma omp parallel for simd #endif 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; // Issue 1674: @@ -297,7 +297,7 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * ncie, double radius, int thres // no precalculated values without SSE => calculate const float HH = xatan2f(srbb[i][j], sraa[i][j]); #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) { 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 - chromave += chroma; + chromave += static_cast(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) { // now as chromave is calculated, we postprocess fringe to reduce the number of divisions in future + const float chromavef = chromave; #ifdef _OPENMP #pragma omp parallel for simd #endif 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; // 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 j = 0; j < width; j++) { const float chroma = SQR(sraa[i][j] - tmaa[i][j]) + SQR(srbb[i][j] - tmbb[i][j]); - chrommed += chroma; + chrommed += static_cast(chroma); badpix[i * width + j] = chroma; } } @@ -703,15 +704,16 @@ void ImProcFunctions::Badpixelscam(CieImage * ncie, double radius, int thresh, i chrommed /= height * width; if (chrommed > 0.0) { + const float chrommedf = chrommed; // 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; #ifdef _OPENMP #pragma omp parallel #endif { #ifdef __SSE2__ - const vfloat chrommedv = F2V(chrommed); + const vfloat chrommedv = F2V(chrommedf); const vfloat onev = F2V(1.f); #endif #ifdef _OPENMP @@ -726,7 +728,7 @@ void ImProcFunctions::Badpixelscam(CieImage * ncie, double radius, int thresh, i } #endif 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 j = 0; j < width; 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(chroma); badpix[i * width + j] = chroma; } } @@ -1049,13 +1051,13 @@ void ImProcFunctions::BadpixelsLab(LabImage * lab, double radius, int thresh, fl if (chrommed > 0.0) { // now as chrommed is calculated, we postprocess badpix to reduce the number of divisions in future - + const float chrommedf = chrommed; #ifdef _OPENMP #pragma omp parallel #endif { #ifdef __SSE2__ - const vfloat chrommedv = F2V(chrommed); + const vfloat chrommedv = F2V(chrommedf); const vfloat onev = F2V(1.f); #endif #ifdef _OPENMP @@ -1070,12 +1072,12 @@ void ImProcFunctions::BadpixelsLab(LabImage * lab, double radius, int thresh, fl } #endif 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 *= chrom; diff --git a/rtengine/ahd_demosaic_RT.cc b/rtengine/ahd_demosaic_RT.cc index 064dfd6e1..536726925 100644 --- a/rtengine/ahd_demosaic_RT.cc +++ b/rtengine/ahd_demosaic_RT.cc @@ -52,13 +52,13 @@ void RawImageSource::ahd_demosaic() int width = W, height = H; - constexpr double xyz_rgb[3][3] = { /* XYZ from RGB */ - { 0.412453, 0.357580, 0.180423 }, - { 0.212671, 0.715160, 0.072169 }, - { 0.019334, 0.119193, 0.950227 } + constexpr float xyz_rgb[3][3] = { /* XYZ from RGB */ + { 0.412453f, 0.357580f, 0.180423f }, + { 0.212671f, 0.715160f, 0.072169f }, + { 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; @@ -76,7 +76,7 @@ void RawImageSource::ahd_demosaic() for (unsigned int j = 0; j < 3; j++) { xyz_cam[i][j] = 0; 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(imatrices.rgb_cam[k][j]) / d65_white[i]; } } } diff --git a/rtengine/badpixels.cc b/rtengine/badpixels.cc index 0ae63a618..97294bdf7 100644 --- a/rtengine/badpixels.cc +++ b/rtengine/badpixels.cc @@ -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 { 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 int counter = 0; diff --git a/rtengine/camconst.cc b/rtengine/camconst.cc index c5cfc26fa..aab2a252c 100644 --- a/rtengine/camconst.cc +++ b/rtengine/camconst.cc @@ -2,20 +2,25 @@ * This file is part of RawTherapee. */ #include "camconst.h" + +#include +#include +#include +#include +#include +#include +#include + #include #include #include + #include "settings.h" #include "rt_math.h" -#include -#include // cJSON is a very minimal JSON parser lib in C, not for threaded stuff etc, so if we're going to use JSON more than just // here we should probably replace cJSON with something beefier. #include "cJSON.h" -#include -#include -#include namespace rtengine { @@ -30,66 +35,70 @@ CameraConst::CameraConst() : pdafOffset(0) } -bool -CameraConst::parseApertureScaling(CameraConst *cc, void *ji_) +bool CameraConst::parseApertureScaling(CameraConst *cc, const void *ji_) { - cJSON *ji = (cJSON *)ji_; + const cJSON *ji = static_cast(ji_); if (ji->type != cJSON_Array) { fprintf(stderr, "\"ranges\":\"aperture_scaling\" must be an array\n"); return false; } - for (ji = ji->child; ji != nullptr; ji = ji->next) { - cJSON *js = cJSON_GetObjectItem(ji, "aperture"); + for (ji = ji->child; ji; ji = ji->next) { + const cJSON *js = cJSON_GetObjectItem(ji, "aperture"); if (!js) { fprintf(stderr, "missing \"ranges\":\"aperture_scaling\":\"aperture\" object item.\n"); return false; - } else if (js->type != cJSON_Number) { + } + + if (js->type != cJSON_Number) { fprintf(stderr, "\"ranges\":\"aperture_scaling\":\"aperture\" must be a number.\n"); return false; } - float aperture = (float)js->valuedouble; + const float aperture = js->valuedouble; js = cJSON_GetObjectItem(ji, "scale_factor"); if (!js) { fprintf(stderr, "missing \"ranges\":\"aperture_scaling\":\"scale_factor\" object item.\n"); return false; - } else if (js->type != cJSON_Number) { + } + + if (js->type != cJSON_Number) { fprintf(stderr, "\"ranges\":\"aperture_scaling\":\"scale_factor\" must be a number.\n"); return false; } - float scale_factor = (float)js->valuedouble; - cc->mApertureScaling.insert(std::pair(aperture, scale_factor)); + const float scale_factor = js->valuedouble; + cc->mApertureScaling.emplace(aperture, scale_factor); } return true; } -bool -CameraConst::parseLevels(CameraConst *cc, int bw, void *ji_) +bool CameraConst::parseLevels(CameraConst *cc, int bw, const void *ji_) { - cJSON *ji = (cJSON *)ji_; + const cJSON *ji = static_cast(ji_); if (ji->type == cJSON_Number) { - struct camera_const_levels lvl; + camera_const_levels lvl; lvl.levels[0] = lvl.levels[1] = lvl.levels[2] = lvl.levels[3] = ji->valueint; - cc->mLevels[bw].insert(std::pair(0, lvl)); + cc->mLevels[bw].emplace(0, lvl); return true; - } else if (ji->type != cJSON_Array) { + } + + if (ji->type != cJSON_Array) { fprintf(stderr, "\"ranges\":\"%s\" must be a number or an array\n", bw ? "white" : "black"); return false; } if (ji->child->type == cJSON_Number) { - struct camera_const_levels lvl; + camera_const_levels lvl; int i; - cJSON *js; + const cJSON *js; - for (js = ji->child, i = 0; js != nullptr && i < 4; js = js->next, i++) { + for (js = ji->child, i = 0; js && i < 4; js = js->next, i++) { lvl.levels[i] = js->valueint; } @@ -97,39 +106,36 @@ CameraConst::parseLevels(CameraConst *cc, int bw, void *ji_) lvl.levels[3] = lvl.levels[1]; // G2 = G1 } else if (i == 1) { lvl.levels[3] = lvl.levels[2] = lvl.levels[1] = lvl.levels[0]; - } else if (i != 4 || js != nullptr) { + } else if (i != 4 || js) { fprintf(stderr, "\"ranges\":\"%s\" array must have 1, 3 or 4 numbers.\n", bw ? "white" : "black"); return false; } - cc->mLevels[bw].insert(std::pair(0, lvl)); + cc->mLevels[bw].emplace(0, lvl); return true; } - for (ji = ji->child; ji != nullptr; ji = ji->next) { - int iso[1000] = { 0 }; - int iso_count = 0; - cJSON *js = cJSON_GetObjectItem(ji, "iso"); + for (ji = ji->child; ji; ji = ji->next) { + const cJSON *js = cJSON_GetObjectItem(ji, "iso"); if (!js) { fprintf(stderr, "missing \"ranges\":\"%s\":\"iso\" object item.\n", bw ? "white" : "black"); return false; - } else if (js->type == cJSON_Number) { - iso[0] = js->valueint; - iso_count = 1; - } else if (js->type == cJSON_Array) { - int i; + } - for (js = js->child, i = 0; js != nullptr && i < 1000; js = js->next, i++) { + std::vector isos; + + if (js->type == cJSON_Number) { + isos.push_back(js->valueint); + } else if (js->type == cJSON_Array) { + for (js = js->child; js; js = js->next) { if (js->type != cJSON_Number) { fprintf(stderr, "\"ranges\":\"%s\":\"iso\" must be a number or an array of numbers.\n", bw ? "white" : "black"); return false; } - iso[i] = js->valueint; + isos.push_back(js->valueint); } - - iso_count = i; } else { fprintf(stderr, "\"ranges\":\"%s\":\"iso\" must be an array or a number.\n", bw ? "white" : "black"); return false; @@ -142,14 +148,14 @@ CameraConst::parseLevels(CameraConst *cc, int bw, void *ji_) return false; } - struct camera_const_levels lvl; + camera_const_levels lvl; if (js->type == cJSON_Number) { lvl.levels[0] = lvl.levels[1] = lvl.levels[2] = lvl.levels[3] = js->valueint; } else if (js->type == cJSON_Array) { int i; - for (js = js->child, i = 0; js != nullptr && i < 4; js = js->next, i++) { + for (js = js->child, i = 0; js && i < 4; js = js->next, i++) { if (js->type != cJSON_Number) { fprintf(stderr, "\"ranges\":\"%s\":\"levels\" must be a number or an array of numbers.\n", bw ? "white" : "black"); return false; @@ -162,7 +168,7 @@ CameraConst::parseLevels(CameraConst *cc, int bw, void *ji_) lvl.levels[3] = lvl.levels[1]; // G2 = G1 } else if (i == 1) { lvl.levels[3] = lvl.levels[2] = lvl.levels[1] = lvl.levels[0]; - } else if (i != 4 || js != nullptr) { + } else if (i != 4 || js) { fprintf(stderr, "\"ranges\":\"%s\":\"levels\" array must have 1, 3 or 4 numbers.\n", bw ? "white" : "black"); return false; } @@ -171,40 +177,38 @@ CameraConst::parseLevels(CameraConst *cc, int bw, void *ji_) return false; } - for (int i = 0; i < iso_count; i++) { - cc->mLevels[bw].insert(std::pair(iso[i], lvl)); + for (auto iso : isos) { + cc->mLevels[bw].emplace(iso, lvl); } } return true; } -CameraConst * -CameraConst::parseEntry(void *cJSON_, const char *make_model) +CameraConst* CameraConst::parseEntry(const void *cJSON_, const char *make_model) { - cJSON *js, *ji, *jranges; - js = (cJSON *)cJSON_; + const cJSON *js = static_cast(cJSON_); - CameraConst *cc = new CameraConst; + std::unique_ptr cc(new CameraConst); cc->make_model = make_model; - ji = cJSON_GetObjectItem(js, "dcraw_matrix"); + const cJSON *ji = cJSON_GetObjectItem(js, "dcraw_matrix"); if (ji) { if (ji->type != cJSON_Array) { fprintf(stderr, "\"dcraw_matrix\" must be an array\n"); - goto parse_error; + return nullptr; } int i; - for (i = 0, ji = ji->child; i < 12 && ji != nullptr; i++, ji = ji->next) { + for (i = 0, ji = ji->child; i < 12 && ji; i++, ji = ji->next) { if (ji->type != cJSON_Number) { fprintf(stderr, "\"dcraw_matrix\" array must contain numbers\n"); - goto parse_error; + return nullptr; } - cc->dcraw_matrix[i] = (short)ji->valueint; + cc->dcraw_matrix[i] = ji->valueint; } } @@ -213,23 +217,23 @@ CameraConst::parseEntry(void *cJSON_, const char *make_model) if (ji) { if (ji->type != cJSON_Array) { fprintf(stderr, "\"raw_crop\" must be an array\n"); - goto parse_error; + return nullptr; } int i; - for (i = 0, ji = ji->child; i < 4 && ji != nullptr; i++, ji = ji->next) { + for (i = 0, ji = ji->child; i < 4 && ji; i++, ji = ji->next) { if (ji->type != cJSON_Number) { fprintf(stderr, "\"raw_crop\" array must contain numbers\n"); - goto parse_error; + return nullptr; } cc->raw_crop[i] = ji->valueint; } - if (i != 4 || ji != nullptr) { + if (i != 4 || ji) { fprintf(stderr, "\"raw_crop\" must contain 4 numbers\n"); - goto parse_error; + return nullptr; } } @@ -238,15 +242,15 @@ CameraConst::parseEntry(void *cJSON_, const char *make_model) if (ji) { if (ji->type != cJSON_Array) { fprintf(stderr, "\"masked_areas\" must be an array\n"); - goto parse_error; + return nullptr; } int i; - for (i = 0, ji = ji->child; i < 8 * 4 && ji != nullptr; i++, ji = ji->next) { + for (i = 0, ji = ji->child; i < 2 * 4 && ji; i++, ji = ji->next) { if (ji->type != cJSON_Number) { fprintf(stderr, "\"masked_areas\" array must contain numbers\n"); - goto parse_error; + return nullptr; } cc->raw_mask[i / 4][i % 4] = ji->valueint; @@ -254,27 +258,23 @@ CameraConst::parseEntry(void *cJSON_, const char *make_model) if (i % 4 != 0) { fprintf(stderr, "\"masked_areas\" array length must be divisible by 4\n"); - goto parse_error; + return nullptr; } } - jranges = cJSON_GetObjectItem(js, "ranges"); + const cJSON *jranges = cJSON_GetObjectItem(js, "ranges"); if (jranges) { ji = cJSON_GetObjectItem(jranges, "black"); - if (ji) { - if (!parseLevels(cc, 0, ji)) { - goto parse_error; - } + if (ji && !parseLevels(cc.get(), 0, ji)) { + return nullptr; } ji = cJSON_GetObjectItem(jranges, "white"); - if (ji) { - if (!parseLevels(cc, 1, ji)) { - goto parse_error; - } + if (ji && !parseLevels(cc.get(), 1, ji)) { + return nullptr; } ji = cJSON_GetObjectItem(jranges, "white_max"); @@ -282,32 +282,28 @@ CameraConst::parseEntry(void *cJSON_, const char *make_model) if (ji) { if (ji->type != cJSON_Number) { fprintf(stderr, "\"ranges\":\"white_max\" must be a number\n"); - goto parse_error; + return nullptr; } - cc->white_max = (int)ji->valueint; + cc->white_max = ji->valueint; } ji = cJSON_GetObjectItem(jranges, "aperture_scaling"); - if (ji) { - if (!parseApertureScaling(cc, ji)) { - goto parse_error; - } + if (ji && !parseApertureScaling(cc.get(), ji)) { + return nullptr; } } for (int bw = 0; bw < 2; bw++) { - struct camera_const_levels lvl; + camera_const_levels lvl; if (!cc->get_Levels(lvl, bw, 0, 0)) { - std::map::iterator it; - it = cc->mLevels[bw].begin(); + const auto it = cc->mLevels[bw].cbegin(); - if (it != cc->mLevels[bw].end()) { + if (it != cc->mLevels[bw].cend()) { // insert levels with lowest iso as the default (iso 0) - struct camera_const_levels lvl = it->second; - cc->mLevels[bw].insert(std::pair(0, lvl)); + cc->mLevels[bw].emplace(0, it->second); } } } @@ -317,13 +313,13 @@ CameraConst::parseEntry(void *cJSON_, const char *make_model) if (ji) { if (ji->type != cJSON_Array) { fprintf(stderr, "\"pdaf_pattern\" must be an array\n"); - goto parse_error; + return nullptr; } - for (ji = ji->child; ji != nullptr; ji = ji->next) { + for (ji = ji->child; ji; ji = ji->next) { if (ji->type != cJSON_Number) { fprintf(stderr, "\"pdaf_pattern\" array must contain numbers\n"); - goto parse_error; + return nullptr; } cc->pdafPattern.push_back(ji->valueint); @@ -335,7 +331,7 @@ CameraConst::parseEntry(void *cJSON_, const char *make_model) if (ji) { if (ji->type != cJSON_Number) { fprintf(stderr, "\"pdaf_offset\" must contain a number\n"); - goto parse_error; + return nullptr; } cc->pdafOffset = ji->valueint; @@ -346,27 +342,21 @@ CameraConst::parseEntry(void *cJSON_, const char *make_model) if (ji) { if (ji->type != cJSON_False && ji->type != cJSON_True) { fprintf(stderr, "\"global_green_equilibration\" must be a boolean\n"); - goto parse_error; + return nullptr; } cc->globalGreenEquilibration = (ji->type == cJSON_True); } - return cc; - -parse_error: - delete cc; - return nullptr; + return cc.release(); } -bool -CameraConst::has_dcrawMatrix() +bool CameraConst::has_dcrawMatrix() const { return dcraw_matrix[0] != 0; } -void -CameraConst::update_dcrawMatrix(const short *other) +void CameraConst::update_dcrawMatrix(const short *other) { if (!other) { return; @@ -377,8 +367,7 @@ CameraConst::update_dcrawMatrix(const short *other) } } -const short * -CameraConst::get_dcrawMatrix() +const short* CameraConst::get_dcrawMatrix() const { if (!has_dcrawMatrix()) { return nullptr; @@ -387,44 +376,35 @@ CameraConst::get_dcrawMatrix() return dcraw_matrix; } -bool -CameraConst::has_pdafPattern() -{ - return pdafPattern.size() > 0; -} - -std::vector -CameraConst::get_pdafPattern() +const std::vector& CameraConst::get_pdafPattern() const { return pdafPattern; } -void -CameraConst::update_pdafPattern(const std::vector &other) +void CameraConst::update_pdafPattern(const std::vector &other) { if (other.empty()) { return; } + pdafPattern = other; } -void -CameraConst::update_pdafOffset(int other) +void CameraConst::update_pdafOffset(int other) { if (other == 0) { return; } + pdafOffset = other; } -bool -CameraConst::has_rawCrop() +bool CameraConst::has_rawCrop() const { return raw_crop[0] != 0 || raw_crop[1] != 0 || raw_crop[2] != 0 || raw_crop[3] != 0; } -void -CameraConst::get_rawCrop(int& left_margin, int& top_margin, int& width, int& height) +void CameraConst::get_rawCrop(int& left_margin, int& top_margin, int& width, int& height) const { left_margin = raw_crop[0]; top_margin = raw_crop[1]; @@ -432,22 +412,20 @@ CameraConst::get_rawCrop(int& left_margin, int& top_margin, int& width, int& hei height = raw_crop[3]; } -bool -CameraConst::has_rawMask(int idx) +bool CameraConst::has_rawMask(int idx) const { - if (idx < 0 || idx > 7) { + if (idx < 0 || idx > 1) { return false; } return (raw_mask[idx][0] | raw_mask[idx][1] | raw_mask[idx][2] | raw_mask[idx][3]) != 0; } -void -CameraConst::get_rawMask(int idx, int& top, int& left, int& bottom, int& right) +void CameraConst::get_rawMask(int idx, int& top, int& left, int& bottom, int& right) const { top = left = bottom = right = 0; - if (idx < 0 || idx > 7) { + if (idx < 0 || idx > 1) { return; } @@ -457,38 +435,30 @@ CameraConst::get_rawMask(int idx, int& top, int& left, int& bottom, int& right) right = raw_mask[idx][3]; } -void -CameraConst::update_Levels(const CameraConst *other) +void CameraConst::update_Levels(const CameraConst *other) { if (!other) { return; } - if (other->mLevels[0].size()) { - mLevels[0].clear(); + if (!other->mLevels[0].empty()) { mLevels[0] = other->mLevels[0]; } - if (other->mLevels[1].size()) { - mLevels[1].clear(); + if (!other->mLevels[1].empty()) { mLevels[1] = other->mLevels[1]; } - if (other->mApertureScaling.size()) { - mApertureScaling.clear(); + if (!other->mApertureScaling.empty()) { mApertureScaling = other->mApertureScaling; } if (other->white_max) { white_max = other->white_max; } - -// for (std::map::iterator i=other->mLevels[0].begin(); i!=other->mLevels[0].end(); i++) { -// } } -void -CameraConst::update_Crop(CameraConst *other) +void CameraConst::update_Crop(CameraConst *other) { if (!other) { return; @@ -499,18 +469,16 @@ CameraConst::update_Crop(CameraConst *other) } } -bool -CameraConst::get_Levels(struct camera_const_levels & lvl, int bw, int iso, float fnumber) +bool CameraConst::get_Levels(camera_const_levels & lvl, int bw, int iso, float fnumber) const { - std::map::iterator it; - it = mLevels[bw].find(iso); + std::map::const_iterator it = mLevels[bw].find(iso); if (it == mLevels[bw].end()) { - std::map::iterator best_it = mLevels[bw].begin(); + auto best_it = mLevels[bw].cbegin(); if (iso > 0) { for (it = mLevels[bw].begin(); it != mLevels[bw].end(); ++it) { - if (abs(it->first - iso) <= abs(best_it->first - iso)) { + if (std::abs(it->first - iso) <= std::abs(best_it->first - iso)) { best_it = it; } else { break; @@ -527,35 +495,34 @@ CameraConst::get_Levels(struct camera_const_levels & lvl, int bw, int iso, float lvl = it->second; - if (bw == 1 && fnumber > 0 && mApertureScaling.size() > 0) { - std::map::iterator it; - it = mApertureScaling.find(fnumber); + if (bw == 1 && fnumber > 0 && !mApertureScaling.empty()) { + std::map::const_iterator scaleIt = mApertureScaling.find(fnumber); - if (it == mApertureScaling.end()) { + if (scaleIt == mApertureScaling.end()) { // fnumber may be an exact aperture, eg 1.414, or a rounded eg 1.4. In our map we // should have rounded numbers so we translate and retry the lookup // table with traditional 1/3 stop f-number rounding used by most cameras, we only // have in the range 0.7 - 10.0, but aperture scaling rarely happen past f/4.0 - const float fn_tab[8][3] = { - { 0.7, 0.8, 0.9 }, - { 1.0, 1.1, 1.2 }, - { 1.4, 1.6, 1.8 }, - { 2.0, 2.2, 2.5 }, - { 2.8, 3.2, 3.5 }, - { 4.0, 4.5, 5.0 }, - { 5.6, 6.3, 7.1 }, - { 8.0, 9.0, 10.0 } + constexpr float fn_tab[8][3] = { + { 0.7f, 0.8f, 0.9f }, + { 1.f, 1.1f, 1.2f }, + { 1.4f, 1.6f, 1.8f }, + { 2.f, 2.2f, 2.5f }, + { 2.8f, 3.2f, 3.5f }, + { 4.f, 4.5f, 5.f }, + { 5.6f, 6.3f, 7.1f }, + { 8.f, 9.f, 10.f } }; for (int avh = 0; avh < 8; avh++) { for (int k = 0; k < 3; k++) { - float av = (avh - 1) + (float)k / 3; - float aperture = sqrtf(powf(2, av)); + const float av = (avh - 1) + k / 3.f; + const float aperture = std::sqrt(std::pow(2.f, av)); - if (fnumber > aperture * 0.97 && fnumber < aperture / 0.97) { + if (fnumber > aperture * 0.97f && fnumber < aperture / 0.97f) { fnumber = fn_tab[avh][k]; - it = mApertureScaling.find(fnumber); + scaleIt = mApertureScaling.find(fnumber); avh = 7; break; } @@ -563,23 +530,21 @@ CameraConst::get_Levels(struct camera_const_levels & lvl, int bw, int iso, float } } - float scaling = 1.0; + float scaling = 1.f; - if (it == mApertureScaling.end()) { - std::map::reverse_iterator it; - - for (it = mApertureScaling.rbegin(); it != mApertureScaling.rend(); ++it) { - if (it->first > fnumber) { - scaling = it->second; + if (scaleIt == mApertureScaling.end()) { + for (auto entry = mApertureScaling.crbegin(); entry != mApertureScaling.crend(); ++entry) { + if (entry->first > fnumber) { + scaling = entry->second; } else { break; } } } else { - scaling = it->second; + scaling = scaleIt->second; } - if (scaling > 1.0) { + if (scaling > 1.f) { for (int i = 0; i < 4; i++) { lvl.levels[i] *= scaling; @@ -593,24 +558,22 @@ CameraConst::get_Levels(struct camera_const_levels & lvl, int bw, int iso, float return true; } -int -CameraConst::get_BlackLevel(const int idx, const int iso_speed) +int CameraConst::get_BlackLevel(const int idx, const int iso_speed) const { assert(idx >= 0 && idx <= 3); - struct camera_const_levels lvl; + camera_const_levels lvl; - if (!get_Levels(lvl, 0, iso_speed, 0.0)) { + if (!get_Levels(lvl, 0, iso_speed, 0.f)) { return -1; } return lvl.levels[idx]; } -int -CameraConst::get_WhiteLevel(const int idx, const int iso_speed, const float fnumber) +int CameraConst::get_WhiteLevel(const int idx, const int iso_speed, const float fnumber) const { assert(idx >= 0 && idx <= 3); - struct camera_const_levels lvl; + camera_const_levels lvl; if (!get_Levels(lvl, 1, iso_speed, fnumber)) { return -1; @@ -619,48 +582,44 @@ CameraConst::get_WhiteLevel(const int idx, const int iso_speed, const float fnum return lvl.levels[idx]; } -bool -CameraConst::has_globalGreenEquilibration() +bool CameraConst::has_globalGreenEquilibration() const { return globalGreenEquilibration >= 0; } -bool -CameraConst::get_globalGreenEquilibration() +bool CameraConst::get_globalGreenEquilibration() const { return globalGreenEquilibration > 0; } -void -CameraConst::update_globalGreenEquilibration(bool other) +void CameraConst::update_globalGreenEquilibration(bool other) { globalGreenEquilibration = (other ? 1 : 0); } -bool -CameraConstantsStore::parse_camera_constants_file(const Glib::ustring& filename_) +bool CameraConstantsStore::parse_camera_constants_file(const Glib::ustring& filename_) { // read the file into a single long string const char *filename = filename_.c_str(); FILE *stream = fopen(filename, "rt"); - if (stream == nullptr) { + if (!stream) { fprintf(stderr, "Could not open camera constants file \"%s\": %s\n", filename, strerror(errno)); return false; } - size_t bufsize = 16384; - size_t increment = 2 * bufsize; + size_t bufsize = 262144; + size_t increment = bufsize; size_t datasize = 0, ret; char *buf = (char *)malloc(bufsize); - while ((ret = fread(&buf[datasize], 1, bufsize - datasize, stream)) != 0) { + while ((ret = fread(&buf[datasize], 1, bufsize - datasize - 1, stream)) != 0) { datasize += ret; - if (datasize == bufsize) { // we need more memory + if (datasize == bufsize - 1) { // we need more memory bufsize += increment; void *temp = realloc(buf, bufsize); // try to realloc buffer with new size - if(!temp) { // realloc failed + if (!temp) { // realloc failed temp = malloc(bufsize); // alloc now buffer if (temp) { // alloc worked memcpy(temp, buf, bufsize - increment); // copy old buffer content to new buffer @@ -683,17 +642,13 @@ CameraConstantsStore::parse_camera_constants_file(const Glib::ustring& filename_ fclose(stream); - if(datasize == bufsize) { - buf = (char *)realloc(buf, datasize + 1); - } - buf[datasize] = '\0'; // remove comments cJSON_Minify(buf); // parse - cJSON *jsroot = cJSON_Parse(buf); + cJSON* const jsroot = cJSON_Parse(buf); if (!jsroot) { char str[128]; @@ -711,20 +666,16 @@ CameraConstantsStore::parse_camera_constants_file(const Glib::ustring& filename_ } free(buf); - /*{ - char *js_str = cJSON_Print(jsroot); - printf("%s\n", js_str); - free(js_str); - }*/ - cJSON *js = cJSON_GetObjectItem(jsroot, "camera_constants"); + + const cJSON *js = cJSON_GetObjectItem(jsroot, "camera_constants"); if (!js) { fprintf(stderr, "missing \"camera_constants\" object item\n"); goto parse_error; } - for (js = js->child; js != nullptr; js = js->next) { - cJSON *ji = cJSON_GetObjectItem(js, "make_model"); + for (js = js->child; js; js = js->next) { + const cJSON *ji = cJSON_GetObjectItem(js, "make_model"); if (!ji) { fprintf(stderr, "missing \"make_model\" object item\n"); @@ -738,30 +689,30 @@ CameraConstantsStore::parse_camera_constants_file(const Glib::ustring& filename_ is_array = true; } - while (ji != nullptr) { + while (ji) { if (ji->type != cJSON_String) { fprintf(stderr, "\"make_model\" must be a string or an array of strings\n"); goto parse_error; } - CameraConst *cc = CameraConst::parseEntry((void *)js, ji->valuestring); + CameraConst* const cc = CameraConst::parseEntry((const void *)js, ji->valuestring); if (!cc) { goto parse_error; } - Glib::ustring make_model(ji->valuestring); - make_model = make_model.uppercase(); + std::string make_model(ji->valuestring); + std::transform(make_model.begin(), make_model.end(), make_model.begin(), ::toupper); - const auto ret = mCameraConstants.emplace(make_model, cc); + const auto entry = mCameraConstants.emplace(make_model, cc); - if(ret.second) { // entry inserted into map + if (entry.second) { // entry inserted into map if (settings->verbose) { printf("Add camera constants for \"%s\"\n", make_model.c_str()); } } else { // The CameraConst already exist for this camera make/model -> we merge the values - CameraConst *existingcc = ret.first->second; + CameraConst* const existingcc = entry.first->second; // updating the dcraw matrix existingcc->update_dcrawMatrix(cc->get_dcrawMatrix()); @@ -813,29 +764,26 @@ void CameraConstantsStore::init(const Glib::ustring& baseDir, const Glib::ustrin { parse_camera_constants_file(Glib::build_filename(baseDir, "camconst.json")); - Glib::ustring userFile(Glib::build_filename(userSettingsDir, "camconst.json")); + const Glib::ustring userFile(Glib::build_filename(userSettingsDir, "camconst.json")); if (Glib::file_test(userFile, Glib::FILE_TEST_EXISTS)) { parse_camera_constants_file(userFile); } } -CameraConstantsStore * -CameraConstantsStore::getInstance() +CameraConstantsStore* CameraConstantsStore::getInstance() { static CameraConstantsStore instance_; return &instance_; } -CameraConst * -CameraConstantsStore::get(const char make[], const char model[]) +const CameraConst* CameraConstantsStore::get(const char make[], const char model[]) const { - Glib::ustring key(make); + std::string key(make); key += " "; key += model; - key = key.uppercase(); - std::map::iterator it; - it = mCameraConstants.find(key); + std::transform(key.begin(), key.end(), key.begin(), ::toupper); + const auto it = mCameraConstants.find(key); if (it == mCameraConstants.end()) { return nullptr; diff --git a/rtengine/camconst.h b/rtengine/camconst.h index 3af05ab01..aa0702439 100644 --- a/rtengine/camconst.h +++ b/rtengine/camconst.h @@ -27,35 +27,34 @@ private: std::string make_model; short dcraw_matrix[12]; int raw_crop[4]; - int raw_mask[8][4]; + int raw_mask[2][4]; int white_max; - std::map mLevels[2]; + std::map mLevels[2]; std::map mApertureScaling; std::vector pdafPattern; int pdafOffset; int globalGreenEquilibration; CameraConst(); - static bool parseLevels(CameraConst *cc, int bw, void *ji); - static bool parseApertureScaling(CameraConst *cc, void *ji); - bool get_Levels(struct camera_const_levels & lvl, int bw, int iso, float fnumber); + static bool parseLevels(CameraConst *cc, int bw, const void *ji); + static bool parseApertureScaling(CameraConst *cc, const void *ji); + bool get_Levels(camera_const_levels & lvl, int bw, int iso, float fnumber) const; public: - static CameraConst *parseEntry(void *cJSON, const char *make_model); - bool has_dcrawMatrix(void); - bool has_pdafPattern(void); + static CameraConst *parseEntry(const void *cJSON, const char *make_model); + bool has_dcrawMatrix(void) const; void update_dcrawMatrix(const short *other); - const short *get_dcrawMatrix(void); - std::vector get_pdafPattern(); - int get_pdafOffset() {return pdafOffset;} - bool has_rawCrop(void); - void get_rawCrop(int& left_margin, int& top_margin, int& width, int& height); - bool has_rawMask(int idx); - void get_rawMask(int idx, int& top, int& left, int& bottom, int& right); - int get_BlackLevel(int idx, int iso_speed); - int get_WhiteLevel(int idx, int iso_speed, float fnumber); - bool has_globalGreenEquilibration(); - bool get_globalGreenEquilibration(); + const short *get_dcrawMatrix(void) const; + const std::vector& get_pdafPattern() const; + int get_pdafOffset() const {return pdafOffset;}; + bool has_rawCrop(void) const; + void get_rawCrop(int& left_margin, int& top_margin, int& width, int& height) const; + bool has_rawMask(int idx) const; + void get_rawMask(int idx, int& top, int& left, int& bottom, int& right) const; + int get_BlackLevel(int idx, int iso_speed) const; + int get_WhiteLevel(int idx, int iso_speed, float fnumber) const; + bool has_globalGreenEquilibration() const; + bool get_globalGreenEquilibration() const; void update_Levels(const CameraConst *other); void update_Crop(CameraConst *other); void update_pdafPattern(const std::vector &other); @@ -75,7 +74,7 @@ public: ~CameraConstantsStore(); void init(const Glib::ustring& baseDir, const Glib::ustring& userSettingsDir); static CameraConstantsStore *getInstance(void); - CameraConst *get(const char make[], const char model[]); + const CameraConst *get(const char make[], const char model[]) const; }; } diff --git a/rtengine/camconst.json b/rtengine/camconst.json index ab42f3d19..8bed22437 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1221,7 +1221,7 @@ Camera constants: { // Quality A, changes for raw crop which is wrong (larger) in dcraw "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 ], "masked_areas": [ 32, 2, 3028, 80 ], "ranges": { "white": 4050 } @@ -1240,6 +1240,12 @@ Camera constants: "ranges": { "white": 4050 } // nominal 4080-4093 }, + { // Quality C, only raw crop + "make_model": "Canon PowerShot SX70 HS", + "dcraw_matrix" : [18285, -8907, -1951, -1845, 10688, 1323, 364, 1101, 5139], // taken from ART + "raw_crop": [ 96, 17, 5248, 3932 ] + }, + { // Quality C "make_model": "Canon PowerShot SX150 IS", "dcraw_matrix": [ 13481, -4867, -1063, -2074, 9960, 2472, -170, 1474, 3894 ], // Adobe DNG Converter 11.1 ColorMatrix1 (there is only one matrix and illuminant, and it's for daylight) @@ -1265,6 +1271,7 @@ Camera constants: { // Quality C "make_model": "FUJIFILM GFX 100", + "dcraw_matrix" : [16212, -8423, -1583, -4336, 12583, 1937, -195, 726, 6199], // taken from ART "raw_crop": [ 0, 2, 11664, 8734 ] }, @@ -1288,6 +1295,12 @@ Camera constants: "ranges": { "white": 16100 } }, + { // Quality C + "make_model": [ "FUJIFILM X100V", "FUJIFILM X-T4" ], + "dcraw_matrix": [ 13426,-6334,-1177,-4244,12136,2371,-580,1303,5980 ], // DNG_v12.2 D65 + "raw_crop": [ 0, 5, 6252, 4140 ] + }, + { // Quality C "make_model": "Fujifilm X10", "ranges": { "white": 3788 } @@ -1345,6 +1358,7 @@ Camera constants: { // Quality C "make_model": [ "FUJIFILM X-T100" ], + "dcraw_matrix" : [11673, -4760, -1041, -3988, 12058, 2166, -771, 1417, 5568], // taken from ART "ranges": { "white": 16100 } }, @@ -1370,7 +1384,8 @@ Camera constants: }, { // Quality C, only raw crop - "make_model": [ "FUJIFILM X-T3", "FUJIFILM X-T30" ], + "make_model": [ "FUJIFILM X-T3", "FUJIFILM X-T30", "FUJIFILM X-PRO3" ], + "dcraw_matrix": [ 13426,-6334,-1177,-4244,12136,2371,-580,1303,5980 ], // DNG_v11, standard_v2 d65 "raw_crop": [ 0, 5, 6252, 4176] }, @@ -1386,6 +1401,11 @@ Camera constants: "ranges": { "white": 4040 } }, + { // Quality B, Matrix from ART + "make_model" : "LEICA D-LUX 7", + "dcraw_matrix" : [11577, -4230, -1106, -3967, 12211, 1957, -758, 1762, 5610] + }, + { // Quality B, Matrix from Adobe's dcp D65 instead of the internal in Leica's DNG "make_model": "LEICA Q (Typ 116)", "dcraw_matrix": [ 10068,-4043,-1068,-5319,14268,1044,-765,1701,6522 ], // DCP D65 @@ -1408,6 +1428,11 @@ Camera constants: "raw_crop": [ 0, 0, 0, -18 ] // 18 rows at bottom are garbage }, + { // Quality B, Matrix from ART + "make_model" : "LEICA V-LUX 5", + "dcraw_matrix" : [9803, -4185, -992, -4066, 12578, 1628, -838, 1824, 5288] + }, + { // Quality C "make_model": "LG mobile LG-H815", "dcraw_matrix": [ 5859,547,-1250,-6484,15547,547,-2422,5625,3906 ], // DNG D65 @@ -1768,6 +1793,7 @@ Camera constants: { // Quality C, only raw crop "make_model": "OLYMPUS TG-6", + "dcraw_matrix" : [10899, -3832, -1082, -2112, 10736, 1575, -267, 1452, 5269], // taken from ART "raw_crop": [ 0, 0, -24, 0 ] // 24 pixels at right are garbage }, diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index 9b60694f2..4dcdd0734 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -761,13 +761,13 @@ bool checkForStop(float** tmpIThr, float** iterCheck, int fullTileSize, int bord 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 - const bool is9x9 = (sigma <= 1.50 && sigmaCornerOffset == 0.0); - const bool is7x7 = (sigma <= 1.15 && sigmaCornerOffset == 0.0); - const bool is5x5 = (sigma <= 0.84 && sigmaCornerOffset == 0.0); - const bool is3x3 = (sigma < 0.6 && sigmaCornerOffset == 0.0); + const bool is9x9 = (sigma <= 1.5f && sigmaCornerOffset == 0.f); + const bool is7x7 = (sigma <= 1.15f && sigmaCornerOffset == 0.f); + const bool is5x5 = (sigma <= 0.84f && sigmaCornerOffset == 0.f); + const bool is3x3 = (sigma < 0.6f && sigmaCornerOffset == 0.f); float kernel13[13][13]; float kernel9[9][9]; float kernel7[7][7]; @@ -906,11 +906,11 @@ BENCHFUN } } } 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 sigmaTile = static_cast(sigma) + distanceFactor * distance; 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]; compute13x13kernel(static_cast(sigma) + distanceFactor * distance, lkernel13); for (int k = 0; k < iterations; ++k) { @@ -921,7 +921,7 @@ BENCHFUN 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]; compute9x9kernel(static_cast(sigma) + distanceFactor * distance, lkernel9); for (int k = 0; k < iterations; ++k) { @@ -932,7 +932,7 @@ BENCHFUN 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]; compute7x7kernel(static_cast(sigma) + distanceFactor * distance, lkernel7); for (int k = 0; k < iterations; ++k) { @@ -1021,7 +1021,7 @@ BENCHFUN { 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]; diff --git a/rtengine/ciecam02.cc b/rtengine/ciecam02.cc index c7e49b2ed..208ed4366 100644 --- a/rtengine/ciecam02.cc +++ b/rtengine/ciecam02.cc @@ -28,7 +28,7 @@ #endif #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)) namespace rtengine @@ -408,7 +408,7 @@ void Ciecam02::initcam1float (float yb, float pilotd, float f, float la, float x { n = yb / yw; - if (pilotd == 2.0) { + if (pilotd == 2.f) { d = d_factorfloat ( f, la ); } else { d = pilotd; @@ -434,7 +434,7 @@ void Ciecam02::initcam2float (float yb, float pilotd, float f, float la, float x { n = yb / yw; - if (pilotd == 2.0) { + if (pilotd == 2.f) { d = d_factorfloat ( f, la ); } else { d = pilotd; @@ -492,7 +492,7 @@ void Ciecam02::xyz2jchqms_ciecam02float ( float &J, float &C, float &h, float &Q myh = xatan2f ( cb, ca ); 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; @@ -620,7 +620,7 @@ void Ciecam02::xyz2jch_ciecam02float ( float &J, float &C, float &h, float aw, f myh = xatan2f ( cb, ca ); 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; diff --git a/rtengine/color.cc b/rtengine/color.cc index d7767b5f5..2de5309b9 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -16,6 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include #include "rtengine.h" #include "color.h" @@ -119,7 +120,7 @@ void MunsellDebugInfo::reinitValues() #endif -void Color::init() +void Color::init () { /*******************************************/ @@ -167,7 +168,7 @@ void Color::init() cachef[i] = 327.68 * ((kappa * i / MAXVALF + 16.0) / 116.0); } - for (; i < maxindex; i++) + for(; i < maxindex; i++) { cachef[i] = 327.68 * std::cbrt((double)i / MAXVALF); } @@ -184,7 +185,7 @@ void Color::init() cachefy[i] = 327.68 * (kappa * i / MAXVALF); } - for (; i < maxindex; i++) + for(; i < maxindex; i++) { cachefy[i] = 327.68 * (116.0 * std::cbrt((double)i / MAXVALF) - 16.0); } @@ -198,7 +199,7 @@ void Color::init() gammatab_srgb[i] = gammatab_srgb1[i] = gamma2(i / 65535.0); } gammatab_srgb *= 65535.f; - gamma2curve.share(gammatab_srgb, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); // shares the buffer with gammatab_srgb but has different clip flags + gamma2curve.share(gammatab_srgb, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); // shares the buffer with gammatab_srgb but has different clip flags } #ifdef _OPENMP #pragma omp section @@ -212,18 +213,18 @@ void Color::init() gammatab_srgb327 *= 32767.f; // gamma2curve.share(gammatab_srgb, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); // shares the buffer with gammatab_srgb but has different clip flags } - #ifdef _OPENMP #pragma omp section #endif { for (int i = 0; i < maxindex; i++) { - igammatab_srgb[i] = igammatab_srgb1[i] = igamma2(i / 65535.0); + igammatab_srgb[i] = igammatab_srgb1[i] = igamma2 (i / 65535.0); } igammatab_srgb *= 65535.f; } + #ifdef _OPENMP #pragma omp section #endif @@ -232,7 +233,7 @@ void Color::init() for (int i = 0; i < maxindex; i++) { - double val = pow(i / 65535.0, rsRGBGamma); + double val = pow (i / 65535.0, rsRGBGamma); gammatab[i] = 65535.0 * val; gammatabThumb[i] = (unsigned char)(255.0 * val); } @@ -246,24 +247,24 @@ void Color::init() // but noting to do with real gamma !!!: it's only for data Lab # data RGB // finally I opted for gamma55 and with options we can change - switch (settings->denoiselabgamma) { + switch(settings->denoiselabgamma) { case 0: for (int i = 0; i < maxindex; i++) { - denoiseGammaTab[i] = 65535.0 * gamma26_11(i / 65535.0); + denoiseGammaTab[i] = 65535.0 * gamma26_11 (i / 65535.0); } break; case 1: for (int i = 0; i < maxindex; i++) { - denoiseGammaTab[i] = 65535.0 * gamma4(i / 65535.0); + denoiseGammaTab[i] = 65535.0 * gamma4 (i / 65535.0); } break; default: for (int i = 0; i < maxindex; i++) { - denoiseGammaTab[i] = 65535.0 * gamma55(i / 65535.0); + denoiseGammaTab[i] = 65535.0 * gamma55 (i / 65535.0); } break; @@ -277,24 +278,24 @@ void Color::init() // but noting to do with real gamma !!!: it's only for data Lab # data RGB // finally I opted for gamma55 and with options we can change - switch (settings->denoiselabgamma) { + switch(settings->denoiselabgamma) { case 0: for (int i = 0; i < maxindex; i++) { - denoiseIGammaTab[i] = 65535.0 * igamma26_11(i / 65535.0); + denoiseIGammaTab[i] = 65535.0 * igamma26_11 (i / 65535.0); } break; case 1: for (int i = 0; i < maxindex; i++) { - denoiseIGammaTab[i] = 65535.0 * igamma4(i / 65535.0); + denoiseIGammaTab[i] = 65535.0 * igamma4 (i / 65535.0); } break; default: for (int i = 0; i < maxindex; i++) { - denoiseIGammaTab[i] = 65535.0 * igamma55(i / 65535.0); + denoiseIGammaTab[i] = 65535.0 * igamma55 (i / 65535.0); } break; @@ -315,12 +316,13 @@ void Color::init() for (int i = 0; i < maxindex; i++) { igammatab_bt709[i] = 65535.0 * igamma709(i / 65535.0); } + #ifdef _OPENMP #pragma omp section #endif for (int i = 0; i < maxindex; i++) { - gammatab_13_2[i] = 65535.0 * gamma13_2(i / 65535.0); + gammatab_13_2[i] = 65535.0 * gamma13_2 (i / 65535.0); } #ifdef _OPENMP @@ -328,7 +330,7 @@ void Color::init() #endif for (int i = 0; i < maxindex; i++) { - igammatab_13_2[i] = 65535.0 * igamma13_2(i / 65535.0); + igammatab_13_2[i] = 65535.0 * igamma13_2 (i / 65535.0); } #ifdef _OPENMP @@ -336,7 +338,7 @@ void Color::init() #endif for (int i = 0; i < maxindex; i++) { - gammatab_115_2[i] = 65535.0 * gamma115_2(i / 65535.0); + gammatab_115_2[i] = 65535.0 * gamma115_2 (i / 65535.0); } #ifdef _OPENMP @@ -344,7 +346,7 @@ void Color::init() #endif for (int i = 0; i < maxindex; i++) { - igammatab_115_2[i] = 65535.0 * igamma115_2(i / 65535.0); + igammatab_115_2[i] = 65535.0 * igamma115_2 (i / 65535.0); } #ifdef _OPENMP @@ -352,7 +354,7 @@ void Color::init() #endif for (int i = 0; i < maxindex; i++) { - gammatab_145_3[i] = 65535.0 * gamma145_3(i / 65535.0); + gammatab_145_3[i] = 65535.0 * gamma145_3 (i / 65535.0); } #ifdef _OPENMP @@ -360,7 +362,7 @@ void Color::init() #endif for (int i = 0; i < maxindex; i++) { - igammatab_145_3[i] = 65535.0 * igamma145_3(i / 65535.0); + igammatab_145_3[i] = 65535.0 * igamma145_3 (i / 65535.0); } #ifdef _OPENMP @@ -376,7 +378,7 @@ void Color::init() #endif for (int i = 0; i < maxindex; i++) { - igammatab_24_17[i] = 65535.0 * igamma24_17(i / 65535.0); + igammatab_24_17[i] = 65535.0 * igamma24_17 (i / 65535.0); } #ifdef _OPENMP @@ -391,22 +393,20 @@ void Color::init() } } -void Color::cleanup() +void Color::cleanup () { if (linearGammaTRC) { cmsFreeToneCurve(linearGammaTRC); } } -void Color::rgb2lab01(const Glib::ustring &profile, const Glib::ustring &profileW, float r, float g, float b, float &LAB_l, float &LAB_a, float &LAB_b, bool workingSpace) -{ - // do not use this function in a loop. It really eats processing time caused by Glib::ustring comparisons +void Color::rgb2lab01 (const Glib::ustring &profile, const Glib::ustring &profileW, float r, float g, float b, float &LAB_l, float &LAB_a, float &LAB_b, bool workingSpace) +{ // do not use this function in a loop. It really eats processing time caused by Glib::ustring comparisons Glib::ustring profileCalc = "sRGB"; //default if (workingSpace) {//display working profile profileCalc = profileW; - if (profileW == "sRGB") { //apply sRGB inverse gamma if (r > 0.04045f) { @@ -517,9 +517,9 @@ void Color::rgb2lab01(const Glib::ustring &profile, const Glib::ustring &profile const TMatrix wprof = rtengine::ICCStore::getInstance()->workingSpaceMatrix(profileCalc); const float xyz_rgb[3][3] = { {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, - {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, - {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} - }; + {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, + {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} + }; const float var_X = (xyz_rgb[0][0] * r + xyz_rgb[0][1] * g + xyz_rgb[0][2] * b) / Color::D50x; const float var_Y = (xyz_rgb[1][0] * r + xyz_rgb[1][1] * g + xyz_rgb[1][2] * b); @@ -538,16 +538,16 @@ void Color::rgb2lab01(const Glib::ustring &profile, const Glib::ustring &profile void Color::rgb2hsl(float r, float g, float b, float &h, float &s, float &l) { - double var_R = double (r) / 65535.0; - double var_G = double (g) / 65535.0; - double var_B = double (b) / 65535.0; + double var_R = double(r) / 65535.0; + double var_G = double(g) / 65535.0; + double var_B = double(b) / 65535.0; double m = min(var_R, var_G, var_B); double M = max(var_R, var_G, var_B); double C = M - m; double l_ = (M + m) / 2.; - l = float (l_); + l = float(l_); if (C < 0.00001 && C > -0.00001) { // no fabs, slow! h = 0.f; @@ -556,26 +556,26 @@ void Color::rgb2hsl(float r, float g, float b, float &h, float &s, float &l) double h_; if (l_ <= 0.5) { - s = float ((M - m) / (M + m)); + s = float( (M - m) / (M + m) ); } else { - s = float ((M - m) / (2.0 - M - m)); + s = float( (M - m) / (2.0 - M - m) ); } - if (var_R == M) { - h_ = (var_G - var_B) / C; - } else if (var_G == M) { + if ( var_R == M ) { + h_ = (var_G - var_B) / C; + } else if ( var_G == M ) { h_ = 2. + (var_B - var_R) / C; } else { h_ = 4. + (var_R - var_G) / C; } - h = float (h_ / 6.0); + h = float(h_ / 6.0); - if (h < 0.f) { + if ( h < 0.f ) { h += 1.f; } - if (h > 1.f) { + if ( h > 1.f ) { h -= 1.f; } } @@ -610,11 +610,11 @@ double Color::hue2rgb(double p, double q, double t) { if (t < 0.) { t += 6.; - } else if (t > 6.) { + } else if( t > 6.) { t -= 6.; } - if (t < 1.) { + if (t < 1.) { return p + (q - p) * t; } else if (t < 3.) { return q; @@ -629,11 +629,11 @@ float Color::hue2rgbfloat(float p, float q, float t) { if (t < 0.f) { t += 6.f; - } else if (t > 6.f) { + } else if( t > 6.f) { t -= 6.f; } - if (t < 1.f) { + if (t < 1.f) { return p + (q - p) * t; } else if (t < 3.f) { return q; @@ -661,16 +661,16 @@ vfloat Color::hue2rgb(vfloat p, vfloat q, vfloat t) } #endif -void Color::hsl2rgb(float h, float s, float l, float &r, float &g, float &b) +void Color::hsl2rgb (float h, float s, float l, float &r, float &g, float &b) { if (s == 0) { r = g = b = 65535.0f * l; // achromatic } else { double m2; - double h_ = double (h); - double s_ = double (s); - double l_ = double (l); + double h_ = double(h); + double s_ = double(s); + double l_ = double(l); if (l <= 0.5f) { m2 = l_ * (1.0 + s_); @@ -680,14 +680,14 @@ void Color::hsl2rgb(float h, float s, float l, float &r, float &g, float &b) double m1 = 2.0 * l_ - m2; - r = float (65535.0 * hue2rgb(m1, m2, h_ * 6.0 + 2.0)); - g = float (65535.0 * hue2rgb(m1, m2, h_ * 6.0)); - b = float (65535.0 * hue2rgb(m1, m2, h_ * 6.0 - 2.0)); + r = float(65535.0 * hue2rgb (m1, m2, h_ * 6.0 + 2.0)); + g = float(65535.0 * hue2rgb (m1, m2, h_ * 6.0)); + b = float(65535.0 * hue2rgb (m1, m2, h_ * 6.0 - 2.0)); } } #ifdef __SSE2__ -void Color::hsl2rgb(vfloat h, vfloat s, vfloat l, vfloat &r, vfloat &g, vfloat &b) +void Color::hsl2rgb (vfloat h, vfloat s, vfloat l, vfloat &r, vfloat &g, vfloat &b) { vfloat m2 = s * l; @@ -699,9 +699,9 @@ void Color::hsl2rgb(vfloat h, vfloat s, vfloat l, vfloat &r, vfloat &g, vfloat & vfloat m1 = l + l - m2; h *= F2V(6.f); - r = c65535v * hue2rgb(m1, m2, h + twov); - g = c65535v * hue2rgb(m1, m2, h); - b = c65535v * hue2rgb(m1, m2, h - twov); + r = c65535v * hue2rgb (m1, m2, h + twov); + g = c65535v * hue2rgb (m1, m2, h); + b = c65535v * hue2rgb (m1, m2, h - twov); vmask selectsMask = vmaskf_eq(ZEROV, s); vfloat lc65535v = c65535v * l; @@ -711,16 +711,16 @@ void Color::hsl2rgb(vfloat h, vfloat s, vfloat l, vfloat &r, vfloat &g, vfloat & } #endif -void Color::hsl2rgb01(float h, float s, float l, float &r, float &g, float &b) +void Color::hsl2rgb01 (float h, float s, float l, float &r, float &g, float &b) { if (s == 0) { r = g = b = l; // achromatic } else { double m2; - double h_ = double (h); - double s_ = double (s); - double l_ = double (l); + double h_ = double(h); + double s_ = double(s); + double l_ = double(l); if (l <= 0.5f) { m2 = l_ * (1.0 + s_); @@ -730,9 +730,9 @@ void Color::hsl2rgb01(float h, float s, float l, float &r, float &g, float &b) double m1 = 2.0 * l_ - m2; - r = float (hue2rgb(m1, m2, h_ * 6.0 + 2.0)); - g = float (hue2rgb(m1, m2, h_ * 6.0)); - b = float (hue2rgb(m1, m2, h_ * 6.0 - 2.0)); + r = float(hue2rgb (m1, m2, h_ * 6.0 + 2.0)); + g = float(hue2rgb (m1, m2, h_ * 6.0)); + b = float(hue2rgb (m1, m2, h_ * 6.0 - 2.0)); } } @@ -804,20 +804,20 @@ void Color::rgb2hsv01(float r, float g, float b, float &h, float &s, float &v) } } -void Color::hsv2rgb(float h, float s, float v, float &r, float &g, float &b) +void Color::hsv2rgb (float h, float s, float v, float &r, float &g, float &b) { float h1 = h * 6.f; // sector 0 to 5 int i = (int)h1; // floor() is very slow, and h1 is always >0 float f = h1 - i; // fractional part of h - float p = v * (1.f - s); - float q = v * (1.f - s * f); - float t = v * (1.f - s * (1.f - f)); + float p = v * ( 1.f - s ); + float q = v * ( 1.f - s * f ); + float t = v * ( 1.f - s * ( 1.f - f ) ); float r1, g1, b1; - if (i == 1) { + if (i == 1) { r1 = q; g1 = v; b1 = p; @@ -850,17 +850,17 @@ void Color::hsv2rgb(float h, float s, float v, float &r, float &g, float &b) // Function copied for speed concerns // Not exactly the same as above ; this one return a result in the [0.0 ; 1.0] range -void Color::hsv2rgb01(float h, float s, float v, float &r, float &g, float &b) +void Color::hsv2rgb01 (float h, float s, float v, float &r, float &g, float &b) { float h1 = h * 6; // sector 0 to 5 - int i = int (h1); + int i = int(h1); float f = h1 - i; // fractional part of h - float p = v * (1 - s); - float q = v * (1 - s * f); - float t = v * (1 - s * (1 - f)); + float p = v * ( 1 - s ); + float q = v * ( 1 - s * f ); + float t = v * ( 1 - s * ( 1 - f ) ); - if (i == 1) { + if (i == 1) { r = q; g = v; b = p; @@ -887,16 +887,16 @@ void Color::hsv2rgb01(float h, float s, float v, float &r, float &g, float &b) } } -void Color::hsv2rgb(float h, float s, float v, int &r, int &g, int &b) +void Color::hsv2rgb (float h, float s, float v, int &r, int &g, int &b) { float h1 = h * 6; // sector 0 to 5 - int i = floor(h1); + int i = floor( h1 ); float f = h1 - i; // fractional part of h - float p = v * (1 - s); - float q = v * (1 - s * f); - float t = v * (1 - s * (1 - f)); + float p = v * ( 1 - s ); + float q = v * ( 1 - s * f ); + float t = v * ( 1 - s * ( 1 - f ) ); float r1, g1, b1; @@ -920,20 +920,20 @@ void Color::hsv2rgb(float h, float s, float v, int &r, int &g, int &b) r1 = t; g1 = p; b1 = v; - } else { /*if (i == 5)*/ + } else /*if (i == 5)*/ { r1 = v; g1 = p; b1 = q; } - r = (int)(r1 * 65535); - g = (int)(g1 * 65535); - b = (int)(b1 * 65535); + r = (int)( r1 * 65535); + g = (int)( g1 * 65535); + b = (int)( b1 * 65535); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void Color::xyz2srgb(float x, float y, float z, float &r, float &g, float &b) +void Color::xyz2srgb (float x, float y, float z, float &r, float &g, float &b) { //Transform to output color. Standard sRGB is D65, but internal representation is D50 @@ -956,27 +956,38 @@ void Color::xyz2srgb(float x, float y, float z, float &r, float &g, float &b) b = ((sRGB_xyz[2][0] * x + sRGB_xyz[2][1] * y + sRGB_xyz[2][2] * z)) ; } -void Color::xyz2Prophoto(float x, float y, float z, float &r, float &g, float &b) +void Color::xyz2Prophoto (float x, float y, float z, float &r, float &g, float &b) { 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)) ; b = ((prophoto_xyz[2][0] * x + prophoto_xyz[2][1] * y + prophoto_xyz[2][2] * z)) ; } -void Color::Prophotoxyz(float r, float g, float b, float &x, float &y, float &z) +void Color::Prophotoxyz (float r, float g, float b, float &x, float &y, float &z) { x = ((xyz_prophoto[0][0] * r + xyz_prophoto[0][1] * g + xyz_prophoto[0][2] * b)) ; y = ((xyz_prophoto[1][0] * r + xyz_prophoto[1][1] * g + xyz_prophoto[1][2] * b)) ; z = ((xyz_prophoto[2][0] * r + xyz_prophoto[2][1] * g + xyz_prophoto[2][2] * b)) ; } -void Color::rgbxyz(float r, float g, float b, float &x, float &y, float &z, const double xyz_rgb[3][3]) +void Color::rgbxyz (float r, float g, float b, float &x, float &y, float &z, const double xyz_rgb[3][3]) { x = ((xyz_rgb[0][0] * r + xyz_rgb[0][1] * g + xyz_rgb[0][2] * b)) ; y = ((xyz_rgb[1][0] * r + xyz_rgb[1][1] * g + xyz_rgb[1][2] * b)) ; z = ((xyz_rgb[2][0] * r + xyz_rgb[2][1] * g + xyz_rgb[2][2] * b)) ; } -void Color::rgbxyz(float r, float g, float b, float &x, float &y, float &z, const float xyz_rgb[3][3]) +void Color::rgbxyY(float r, float g, float b, float &x, float &y, float &Y, const float xyz_rgb[3][3]) +{ + const float xx = xyz_rgb[0][0] * r + xyz_rgb[0][1] * g + xyz_rgb[0][2] * b; + const float yy = xyz_rgb[1][0] * r + xyz_rgb[1][1] * g + xyz_rgb[1][2] * b; + const float zz = xyz_rgb[2][0] * r + xyz_rgb[2][1] * g + xyz_rgb[2][2] * b; + const float som = xx + yy + zz; + x = xx / som; + y = yy / som; + Y = yy / 65535.f; +} + +void Color::rgbxyz (float r, float g, float b, float &x, float &y, float &z, const float xyz_rgb[3][3]) { x = ((xyz_rgb[0][0] * r + xyz_rgb[0][1] * g + xyz_rgb[0][2] * b)) ; y = ((xyz_rgb[1][0] * r + xyz_rgb[1][1] * g + xyz_rgb[1][2] * b)) ; @@ -984,7 +995,7 @@ void Color::rgbxyz(float r, float g, float b, float &x, float &y, float &z, cons } #ifdef __SSE2__ -void Color::rgbxyz(vfloat r, vfloat g, vfloat b, vfloat &x, vfloat &y, vfloat &z, const vfloat xyz_rgb[3][3]) +void Color::rgbxyz (vfloat r, vfloat g, vfloat b, vfloat &x, vfloat &y, vfloat &z, const vfloat xyz_rgb[3][3]) { x = ((xyz_rgb[0][0] * r + xyz_rgb[0][1] * g + xyz_rgb[0][2] * b)) ; y = ((xyz_rgb[1][0] * r + xyz_rgb[1][1] * g + xyz_rgb[1][2] * b)) ; @@ -992,7 +1003,7 @@ void Color::rgbxyz(vfloat r, vfloat g, vfloat b, vfloat &x, vfloat &y, vfloat &z } #endif -void Color::xyz2rgb(float x, float y, float z, float &r, float &g, float &b, const double rgb_xyz[3][3]) +void Color::xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const double rgb_xyz[3][3]) { //Transform to output color. Standard sRGB is D65, but internal representation is D50 //Note that it is only at this point that we should have need of clipping color data @@ -1014,7 +1025,7 @@ void Color::xyz2rgb(float x, float y, float z, float &r, float &g, float &b, con b = ((rgb_xyz[2][0] * x + rgb_xyz[2][1] * y + rgb_xyz[2][2] * z)) ; } -void Color::xyz2r(float x, float y, float z, float &r, const double rgb_xyz[3][3]) // for black & white we need only r channel +void Color::xyz2r (float x, float y, float z, float &r, const double rgb_xyz[3][3]) // for black & white we need only r channel { //Transform to output color. Standard sRGB is D65, but internal representation is D50 //Note that it is only at this point that we should have need of clipping color data @@ -1023,7 +1034,7 @@ void Color::xyz2r(float x, float y, float z, float &r, const double rgb_xyz[3][3 } // same for float -void Color::xyz2rgb(float x, float y, float z, float &r, float &g, float &b, const float rgb_xyz[3][3]) +void Color::xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const float rgb_xyz[3][3]) { r = ((rgb_xyz[0][0] * x + rgb_xyz[0][1] * y + rgb_xyz[0][2] * z)) ; g = ((rgb_xyz[1][0] * x + rgb_xyz[1][1] * y + rgb_xyz[1][2] * z)) ; @@ -1031,7 +1042,7 @@ void Color::xyz2rgb(float x, float y, float z, float &r, float &g, float &b, con } #ifdef __SSE2__ -void Color::xyz2rgb(vfloat x, vfloat y, vfloat z, vfloat &r, vfloat &g, vfloat &b, const vfloat rgb_xyz[3][3]) +void Color::xyz2rgb (vfloat x, vfloat y, vfloat z, vfloat &r, vfloat &g, vfloat &b, const vfloat rgb_xyz[3][3]) { r = ((rgb_xyz[0][0] * x + rgb_xyz[0][1] * y + rgb_xyz[0][2] * z)) ; g = ((rgb_xyz[1][0] * x + rgb_xyz[1][1] * y + rgb_xyz[1][2] * z)) ; @@ -1040,10 +1051,10 @@ void Color::xyz2rgb(vfloat x, vfloat y, vfloat z, vfloat &r, vfloat &g, vfloat & #endif // __SSE2__ #ifdef __SSE2__ -void Color::trcGammaBW(float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb) +void Color::trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb) { // correct gamma for black and white image : pseudo TRC curve of ICC profile - vfloat rgbv = _mm_set_ps(0.f, r, r, r); // input channel is always r + vfloat rgbv = _mm_set_ps(0.f, r, r, r); // input channel is always r vfloat gammabwv = _mm_set_ps(0.f, gammabwb, gammabwg, gammabwr); vfloat c65535v = F2V(65535.f); rgbv /= c65535v; @@ -1056,7 +1067,7 @@ void Color::trcGammaBW(float &r, float &g, float &b, float gammabwr, float gamma g = temp[1]; b = temp[2]; } -void Color::trcGammaBWRow(float *r, float *g, float *b, int width, float gammabwr, float gammabwg, float gammabwb) +void Color::trcGammaBWRow (float *r, float *g, float *b, int width, float gammabwr, float gammabwg, float gammabwb) { // correct gamma for black and white image : pseudo TRC curve of ICC profile vfloat c65535v = F2V(65535.f); @@ -1064,9 +1075,8 @@ void Color::trcGammaBWRow(float *r, float *g, float *b, int width, float gammabw vfloat gammabwgv = F2V(gammabwg); vfloat gammabwbv = F2V(gammabwb); int i = 0; - - for (; i < width - 3; i += 4) { - vfloat inv = _mm_loadu_ps(&r[i]); // input channel is always r + for(; i < width - 3; i += 4 ) { + vfloat inv = _mm_loadu_ps(&r[i]); // input channel is always r inv /= c65535v; inv = vmaxf(inv, ZEROV); vfloat rv = pow_F(inv, gammabwrv); @@ -1079,24 +1089,23 @@ void Color::trcGammaBWRow(float *r, float *g, float *b, int width, float gammabw _mm_storeu_ps(&g[i], gv); _mm_storeu_ps(&b[i], bv); } - - for (; i < width; i++) { + for(; i < width; i++) { trcGammaBW(r[i], g[i], b[i], gammabwr, gammabwg, gammabwb); } } #else -void Color::trcGammaBW(float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb) +void Color::trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb) { // correct gamma for black and white image : pseudo TRC curve of ICC profile float in = r; // input channel is always r in /= 65535.0f; in = max(in, 0.f); - b = pow_F(in, gammabwb); + b = pow_F (in, gammabwb); b *= 65535.0f; - r = pow_F(in, gammabwr); + r = pow_F (in, gammabwr); r *= 65535.0f; - g = pow_F(in, gammabwg); + g = pow_F (in, gammabwg); g *= 65535.0f; } #endif @@ -1106,72 +1115,72 @@ void Color::trcGammaBW(float &r, float &g, float &b, float gammabwr, float gamma * @param setting BlackWhite::setting * @param setting BlackWhite::filter */ -void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::ustring &filter, const Glib::ustring &algo, float &filcor, float &mixerRed, float &mixerGreen, - float &mixerBlue, float mixerOrange, float mixerYellow, float mixerCyan, float mixerPurple, float mixerMagenta, - bool autoc, bool complement, float &kcorec, double &rrm, double &ggm, double &bbm) +void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::ustring &filter, const Glib::ustring &algo, float &filcor, float &mixerRed, float &mixerGreen, + float &mixerBlue, float mixerOrange, float mixerYellow, float mixerCyan, float mixerPurple, float mixerMagenta, + bool autoc, bool complement, float &kcorec, double &rrm, double &ggm, double &bbm) { float somm; float som = mixerRed + mixerGreen + mixerBlue; - if (som >= 0.f && som < 1.f) { + if(som >= 0.f && som < 1.f) { som = 1.f; } - if (som < 0.f && som > -1.f) { + if(som < 0.f && som > -1.f) { som = -1.f; } // rM = mixerRed, gM = mixerGreen, bM = mixerBlue ! //presets - if (setting == "RGB-Abs" || setting == "ROYGCBPM-Abs") { + if (setting == "RGB-Abs" || setting == "ROYGCBPM-Abs") { kcorec = som / 100.f; } if (!autoc) { //if (setting=="RGB-Abs" || setting=="ROYGCBPM-Abs") {} //Keep the RGB mixer values as is! //else if(setting=="RGB-Rel" || setting=="ROYGCBPM-Rel") {} //Keep the RGB mixer values as is! - if (setting == "NormalContrast") { + if (setting == "NormalContrast") { mixerRed = 43.f ; mixerGreen = 33.f; mixerBlue = 30.f; - } else if (setting == "Panchromatic") { + } else if(setting == "Panchromatic") { mixerRed = 33.3f; mixerGreen = 33.3f; mixerBlue = 33.3f; - } else if (setting == "HyperPanchromatic") { + } else if(setting == "HyperPanchromatic") { mixerRed = 41.f ; mixerGreen = 25.f; mixerBlue = 34.f; - } else if (setting == "LowSensitivity") { + } else if(setting == "LowSensitivity") { mixerRed = 27.f ; mixerGreen = 27.f; mixerBlue = 46.f; - } else if (setting == "HighSensitivity") { + } else if(setting == "HighSensitivity") { mixerRed = 30.f ; mixerGreen = 28.f; mixerBlue = 42.f; - } else if (setting == "Orthochromatic") { + } else if(setting == "Orthochromatic") { mixerRed = 0.f ; mixerGreen = 42.f; mixerBlue = 58.f; - } else if (setting == "HighContrast") { + } else if(setting == "HighContrast") { mixerRed = 40.f ; mixerGreen = 34.f; mixerBlue = 60.f; - } else if (setting == "Luminance") { + } else if(setting == "Luminance") { mixerRed = 30.f ; mixerGreen = 59.f; mixerBlue = 11.f; - } else if (setting == "Landscape") { + } else if(setting == "Landscape") { mixerRed = 66.f ; mixerGreen = 24.f; mixerBlue = 10.f; - } else if (setting == "Portrait") { + } else if(setting == "Portrait") { mixerRed = 54.f ; mixerGreen = 44.f; mixerBlue = 12.f; - } else if (setting == "InfraRed") { + } else if(setting == "InfraRed") { mixerRed = -40.f; mixerGreen = 200.f; mixerBlue = -17.f; @@ -1184,11 +1193,11 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us somm = mixerRed + mixerGreen + mixerBlue; - if (somm >= 0.f && somm < 1.f) { + if(somm >= 0.f && somm < 1.f) { somm = 1.f; } - if (somm < 0.f && somm > -1.f) { + if(somm < 0.f && somm > -1.f) { somm = -1.f; } @@ -1197,7 +1206,7 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us mixerBlue = mixerBlue / somm; float koymcp = 0.f; - if (setting == "ROYGCBPM-Abs" || setting == "ROYGCBPM-Rel") { + if(setting == "ROYGCBPM-Abs" || setting == "ROYGCBPM-Rel") { float obM = 0.f; float ogM = 0.f; float orM = 0.f; @@ -1221,15 +1230,15 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us float fcompl = 1.f; - if (complement && algo == "SP") { + if(complement && algo == "SP") { fcompl = 3.f; //special - } else if (complement && algo == "LI") { + } else if(complement && algo == "LI") { fcompl = 1.5f; //linear } // ponderate filters: report to R=G=B=33 // I ponder RGB channel, not only orange or yellow or cyan, etc...it's my choice ! - if (mixerOrange != 33) { + if(mixerOrange != 33) { if (algo == "SP") { //special if (mixerOrange >= 33) { orM = fcompl * (mixerOrange * 0.67f - 22.11f) / 100.f; @@ -1247,7 +1256,7 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us ogM = fcompl * (0.5f * mixerOrange - 16.5f) / 100.f; } - if (complement) { + if(complement) { obM = (-0.492f * mixerOrange + 16.236f) / 100.f; } @@ -1259,16 +1268,16 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us } - if (mixerYellow != 33) { + if(mixerYellow != 33) { if (algo == "SP") { yrM = fcompl * (-0.134f * mixerYellow + 4.422f) / 100.f; //22.4 } else if (algo == "LI") { yrM = fcompl * (0.5f * mixerYellow - 16.5f) / 100.f; //22.4 } - ygM = fcompl * (0.5f * mixerYellow - 16.5f) / 100.f; + ygM = fcompl * (0.5f * mixerYellow - 16.5f ) / 100.f; - if (complement) { + if(complement) { ybM = (-0.492f * mixerYellow + 16.236f) / 100.f; } @@ -1278,25 +1287,25 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us koymcp += (yrM + ygM + ybM); } - if (mixerMagenta != 33) { + if(mixerMagenta != 33) { if (algo == "SP") { - if (mixerMagenta >= 33) { - mrM = fcompl * (0.67f * mixerMagenta - 22.11f) / 100.f; + if(mixerMagenta >= 33) { + mrM = fcompl * ( 0.67f * mixerMagenta - 22.11f) / 100.f; } else { mrM = fcompl * (-0.3f * mixerMagenta + 9.9f) / 100.f; } - if (mixerMagenta >= 33) { + if(mixerMagenta >= 33) { mbM = fcompl * (-0.164f * mixerMagenta + 5.412f) / 100.f; } else { - mbM = fcompl * (0.4f * mixerMagenta - 13.2f) / 100.f; + mbM = fcompl * ( 0.4f * mixerMagenta - 13.2f) / 100.f; } } else if (algo == "LI") { mrM = fcompl * (mixerMagenta - 33.f) / 100.f; mbM = fcompl * (0.5f * mixerMagenta - 16.5f) / 100.f; } - if (complement) { + if(complement) { mgM = (-0.492f * mixerMagenta + 16.236f) / 100.f; } @@ -1306,7 +1315,7 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us koymcp += (mrM + mgM + mbM); } - if (mixerPurple != 33) { + if(mixerPurple != 33) { if (algo == "SP") { prM = fcompl * (-0.134f * mixerPurple + 4.422f) / 100.f; } else if (algo == "LI") { @@ -1315,7 +1324,7 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us pbM = fcompl * (0.5f * mixerPurple - 16.5f) / 100.f; - if (complement) { + if(complement) { pgM = (-0.492f * mixerPurple + 16.236f) / 100.f; } @@ -1325,7 +1334,7 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us koymcp += (prM + pgM + pbM); } - if (mixerCyan != 33) { + if(mixerCyan != 33) { if (algo == "SP") { cgM = fcompl * (-0.134f * mixerCyan + 4.422f) / 100.f; } else if (algo == "LI") { @@ -1334,7 +1343,7 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us cbM = fcompl * (0.5f * mixerCyan - 16.5f) / 100.f; - if (complement) { + if(complement) { crM = (-0.492f * mixerCyan + 16.236f) / 100.f; } @@ -1345,7 +1354,7 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us } } - if (setting == "ROYGCBPM-Abs") { + if(setting == "ROYGCBPM-Abs") { kcorec = koymcp + som / 100.f; } @@ -1356,47 +1365,47 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us filblue = 1.f; filcor = 1.f; - if (filter == "None") { + if (filter == "None") { filred = 1.f; filgreen = 1.f; filblue = 1.f; filcor = 1.f; - } else if (filter == "Red") { + } else if (filter == "Red") { filred = 1.f; filgreen = 0.05f; filblue = 0.f; filcor = 1.08f; - } else if (filter == "Orange") { + } else if (filter == "Orange") { filred = 1.f; filgreen = 0.6f; filblue = 0.f; filcor = 1.35f; - } else if (filter == "Yellow") { + } else if (filter == "Yellow") { filred = 1.f; filgreen = 1.f; filblue = 0.05f; filcor = 1.23f; - } else if (filter == "YellowGreen") { + } else if (filter == "YellowGreen") { filred = 0.6f; filgreen = 1.f; filblue = 0.3f; filcor = 1.32f; - } else if (filter == "Green") { + } else if (filter == "Green") { filred = 0.2f; filgreen = 1.f; filblue = 0.3f; filcor = 1.41f; - } else if (filter == "Cyan") { + } else if (filter == "Cyan") { filred = 0.05f; filgreen = 1.f; filblue = 1.f; filcor = 1.23f; - } else if (filter == "Blue") { + } else if (filter == "Blue") { filred = 0.f; filgreen = 0.05f; filblue = 1.f; filcor = 1.20f; - } else if (filter == "Purple") { + } else if (filter == "Purple") { filred = 1.f; filgreen = 0.05f; filblue = 1.f; @@ -1407,7 +1416,7 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us mixerGreen = mixerGreen * filgreen; mixerBlue = mixerBlue * filblue; - if (mixerRed + mixerGreen + mixerBlue == 0) { + if(mixerRed + mixerGreen + mixerBlue == 0) { mixerRed += 1.f; } @@ -1415,25 +1424,25 @@ void Color::computeBWMixerConstants(const Glib::ustring &setting, const Glib::us mixerGreen = filcor * mixerGreen / (mixerRed + mixerGreen + mixerBlue); mixerBlue = filcor * mixerBlue / (mixerRed + mixerGreen + mixerBlue); - if (filter != "None") { + if(filter != "None") { som = mixerRed + mixerGreen + mixerBlue; - if (som >= 0.f && som < 1.f) { + if(som >= 0.f && som < 1.f) { som = 1.f; } - if (som < 0.f && som > -1.f) { + if(som < 0.f && som > -1.f) { som = -1.f; } - if (setting == "RGB-Abs" || setting == "ROYGCBPM-Abs") { + if(setting == "RGB-Abs" || setting == "ROYGCBPM-Abs") { kcorec = kcorec * som; } } } -void Color::interpolateRGBColor(const float balance, const float r1, const float g1, const float b1, const float r2, const float g2, const float b2, int toDo, const double xyz_rgb[3][3], const double rgb_xyz[3][3], float &ro, float &go, float &bo) +void Color::interpolateRGBColor (const float balance, const float r1, const float g1, const float b1, const float r2, const float g2, const float b2, int toDo, const double xyz_rgb[3][3], const double rgb_xyz[3][3], float &ro, float &go, float &bo) { float X1, Y1, Z1, X2, Y2, Z2, X, Y, Z; float L1, L2, a_1, b_1, a_2, b_2, a, b; @@ -1480,7 +1489,7 @@ void Color::interpolateRGBColor(const float balance, const float r1, const float if (toDo & CHANNEL_LIGHTNESS) { L1 = L1 + (L2 - L1) * balance; //do not allow negative L - if (L1 < 0.f) { + if(L1 < 0.f) { L1 = 0.f; } } @@ -1488,17 +1497,17 @@ void Color::interpolateRGBColor(const float balance, const float r1, const float if (toDo & CHANNEL_CHROMATICITY) { c1 = c1 + (c2 - c1) * balance; //limit C to reasonable value - if (c1 < 0.f) { + if(c1 < 0.f) { c1 = 0.f; } - if (c1 > 180.f) { + if(c1 > 180.f) { c1 = 180.f; } } if (toDo & CHANNEL_HUE) { - h1 = interpolatePolarHue_PI (h1, h2, balance); + h1 = interpolatePolarHue_PI(h1, h2, balance); } // here I have put gamut control with gamutlchonly on final process @@ -1522,10 +1531,10 @@ void Color::interpolateRGBColor(const float balance, const float r1, const float } -void Color::interpolateRGBColor(float realL, float iplow, float iphigh, int algm, const float balance, int twoc, int metchrom, - float chromat, float luma, const float r1, const float g1, const float b1, - const float xl, const float yl, const float zl, const float x2, const float y2, const float z2, - const double xyz_rgb[3][3], const double rgb_xyz[3][3], float &ro, float &go, float &bo) +void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int algm, const float balance, int twoc, int metchrom, + float chromat, float luma, const float r1, const float g1, const float b1, + const float xl, const float yl, const float zl, const float x2, const float y2, const float z2, + const double xyz_rgb[3][3], const double rgb_xyz[3][3], float &ro, float &go, float &bo) { float X1, Y1, Z1, X2, Y2, Z2, X, Y, Z, XL, YL, ZL; float L1 = 0.f, L2, LL, a_1 = 0.f, b_1 = 0.f, a_2 = 0.f, b_2 = 0.f, a_L, b_L; @@ -1533,19 +1542,19 @@ void Color::interpolateRGBColor(float realL, float iplow, float iphigh, int algm // converting color 1 to Lab (image) Color::rgbxyz(r1, g1, b1, X1, Y1, Z1, xyz_rgb); - if (algm == 1) { //use H interpolate + if(algm == 1) {//use H interpolate Color::XYZ2Lab(X1, Y1, Z1, L1, a_1, b_1); //Color::Lab2Lch(a_1, b_1, c_1, h_1) ; } // converting color l lab(low) first color - if (twoc == 0) { // 2 colours + if(twoc == 0) { // 2 colours //Color::rgbxyz(rl, gl, bl, XL, YL, ZL, xyz_rgb); XL = xl; YL = yl; ZL = zl; - if (algm <= 1) { //use H interpolate + if(algm <= 1) {//use H interpolate Color::XYZ2Lab(XL, YL, ZL, LL, a_L, b_L); } } @@ -1555,7 +1564,7 @@ void Color::interpolateRGBColor(float realL, float iplow, float iphigh, int algm Y2 = y2; Z2 = z2; - if (algm == 1) { + if(algm == 1 ) { Color::XYZ2Lab(X2, Y2, Z2, L2, a_2, b_2); //Color::Lab2Lch(a_2, b_2, c_2, h_2) ; } @@ -1571,17 +1580,17 @@ void Color::interpolateRGBColor(float realL, float iplow, float iphigh, int algm float calby; calby = luma; - if (twoc == 0) { // 2 colours + if(twoc == 0) { // 2 colours calan = chromat; //calculate new balance chroma - if (realL > iplow && realL <= med) { + if (realL > iplow && realL <= med) { cal = realL * calan / (iplow - med) - med * calan / (iplow - med); } else if (realL <= iplow) { cal = realL * calan / iplow; } - if (realL > medH && realL <= iphigh) { + if (realL > medH && realL <= iphigh) { calH = realL * calan / (iphigh - medH) - medH * calan / (iphigh - medH); } else if (realL > iphigh) { calH = realL * calan; //*(iphigh-1.f) - calan*(iphigh-1.f);//it is better without transition in highlight @@ -1590,22 +1599,22 @@ void Color::interpolateRGBColor(float realL, float iplow, float iphigh, int algm float aaH, bbH; - if (algm <= 1) { - if (twoc == 0 && metchrom == 3) { // 2 colours only with special "ab" - if (algm == 1) { + if(algm <= 1) { + if(twoc == 0 && metchrom == 3) { // 2 colours only with special "ab" + if(algm == 1) { aaH = a_1 + (a_2 - a_1) * calH; bbH = b_1 + (b_2 - b_1) * calH; //pass to line after a_1 = aaH + (a_L - aaH) * cal * balance; b_1 = bbH + (b_L - bbH) * cal * balance; } - } else if (twoc == 1) { - if (metchrom == 0) { + } else if(twoc == 1) { + if(metchrom == 0) { a_1 = a_1 + (a_2 - a_1) * balance; b_1 = b_1 + (b_2 - b_1) * balance; - } else if (metchrom == 1) { + } else if(metchrom == 1) { a_1 = a_1 + (a_2 - a_1) * calan * balance; b_1 = b_1 + (b_2 - b_1) * calan * balance; - } else if (metchrom == 2) { + } else if(metchrom == 2) { a_1 = a_1 + (a_2 - a_1) * calan * balance; b_1 = b_1 + (b_2 - b_1) * calby * balance; } @@ -1614,10 +1623,10 @@ void Color::interpolateRGBColor(float realL, float iplow, float iphigh, int algm Color::Lab2XYZ(L1, a_1, b_1, X, Y, Z); - Color::xyz2rgb(X, Y, Z, ro, go, bo, rgb_xyz); // ro go bo in gamut + Color::xyz2rgb(X, Y, Z, ro, go, bo, rgb_xyz);// ro go bo in gamut } -void Color::calcGamma(double pwr, double ts, int mode, GammaValues &gamma) +void Color::calcGamma (double pwr, double ts, int mode, GammaValues &gamma) { //from Dcraw (D.Coffin) int i; @@ -1663,7 +1672,7 @@ void Color::calcGamma(double pwr, double ts, int mode, GammaValues &gamma) return; } } -void Color::gammaf2lut(LUTf &gammacurve, float gamma, float start, float slope, float divisor, float factor) +void Color::gammaf2lut (LUTf &gammacurve, float gamma, float start, float slope, float divisor, float factor) { #ifdef __SSE2__ // SSE2 version is more than 6 times faster than scalar version @@ -1679,20 +1688,20 @@ void Color::gammaf2lut(LUTf &gammacurve, float gamma, float start, float slope, int border2 = border1 + 4; int i = 0; - for (; i < border1; i += 4) { + for(; i < border1; i += 4) { vfloat resultv = iv * slopev; STVFU(gammacurve[i], resultv); iv += fourv; } - for (; i < border2; i += 4) { + for(; i < border2; i += 4) { vfloat result0v = iv * slopev; vfloat result1v = xexpf((xlogf(iv) - divisorv) * gammav) * factorv; STVFU(gammacurve[i], vself(vmaskf_le(iv, comparev), result0v, result1v)); iv += fourv; } - for (; i < 65536; i += 4) { + for(; i < 65536; i += 4) { vfloat resultv = xexpfNoCheck((xlogfNoCheck(iv) - divisorv) * gammav) * factorv; STVFU(gammacurve[i], resultv); iv += fourv; @@ -1707,7 +1716,7 @@ void Color::gammaf2lut(LUTf &gammacurve, float gamma, float start, float slope, #endif } -void Color::gammanf2lut(LUTf &gammacurve, float gamma, float divisor, float factor) //standard gamma without slope... +void Color::gammanf2lut (LUTf &gammacurve, float gamma, float divisor, float factor) //standard gamma without slope... { #ifdef __SSE2__ // SSE2 version is more than 6 times faster than scalar version @@ -1723,7 +1732,7 @@ void Color::gammanf2lut(LUTf &gammacurve, float gamma, float divisor, float fact iv += fourv; // inside the loop we can use xlogfNoCheck and xexpfNoCheck because we know about the input values - for (int i = 4; i < 65536; i += 4) { + for(int i = 4; i < 65536; i += 4) { resultv = xexpfNoCheck((xlogfNoCheck(iv) - divisorv) * gammav) * factorv; STVFU(gammacurve[i], resultv); iv += fourv; @@ -1751,7 +1760,14 @@ void Color::Lab2XYZ(float L, float a, float b, float &x, float &y, float &z) y = (LL > epskap) ? 65535.0f * fy * fy * fy : 65535.0f * LL / kappa; } -void Color::L2XYZ(float L, float &x, float &y, float &z) // for black & white +float Color::L2Y(float L) +{ + const float LL = L / 327.68f; + const float fy = (c1By116 * LL) + c16By116; // (L+16)/116 + return (LL > epskapf) ? 65535.f * fy * fy * fy : 65535.f * LL / kappaf; +} + +void Color::L2XYZ(float L, float &x, float &y, float &z) // for black & white { float LL = L / 327.68f; float fy = (c1By116 * LL) + c16By116; // (L+16)/116 @@ -1793,19 +1809,6 @@ inline float Color::computeXYZ2Lab(float f) } } - -inline float Color::computeXYZ2LabY(float f) -{ - if (f < 0.f) { - return 327.68 * (kappa * f / MAXVALF); - } else if (f > 65535.f) { - return 327.68f * (116.f * xcbrtf(f / MAXVALF) - 16.f); - } else { - return cachefy[f]; - } -} - - void Color::RGB2Lab(float *R, float *G, float *B, float *L, float *a, float *b, const float wp[3][3], int width) { @@ -1818,8 +1821,7 @@ void Color::RGB2Lab(float *R, float *G, float *B, float *L, float *a, float *b, int i = 0; #ifdef __SSE2__ - - for (; i < width - 3; i += 4) { + for(;i < width - 3; i+=4) { const vfloat rv = LVFU(R[i]); const vfloat gv = LVFU(G[i]); const vfloat bv = LVFU(B[i]); @@ -1829,7 +1831,7 @@ void Color::RGB2Lab(float *R, float *G, float *B, float *L, float *a, float *b, if (_mm_movemask_ps((vfloat)vorm(vmaskf_gt(vmaxf(xv, vmaxf(yv, zv)), maxvalfv), vmaskf_lt(vminf(xv, vminf(yv, zv)), minvalfv)))) { // take slower code path for all 4 pixels if one of the values is > MAXVALF. Still faster than non SSE2 version - for (int k = 0; k < 4; ++k) { + for(int k = 0; k < 4; ++k) { float x = xv[k]; float y = yv[k]; float z = zv[k]; @@ -1838,8 +1840,8 @@ void Color::RGB2Lab(float *R, float *G, float *B, float *L, float *a, float *b, float fz = computeXYZ2Lab(z); L[i + k] = computeXYZ2LabY(y); - a[i + k] = (500.f * (fx - fy)); - b[i + k] = (200.f * (fy - fz)); + a[i + k] = (500.f * (fx - fy) ); + b[i + k] = (200.f * (fy - fz) ); } } else { const vfloat fx = cachef[xv]; @@ -1851,10 +1853,8 @@ void Color::RGB2Lab(float *R, float *G, float *B, float *L, float *a, float *b, STVFU(b[i], c200v * (fy - fz)); } } - #endif - - for (; i < width; ++i) { + for(;i < width; ++i) { const float rv = R[i]; const float gv = G[i]; const float bv = B[i]; @@ -1970,8 +1970,8 @@ void Color::XYZ2Lab(float X, float Y, float Z, float &L, float &a, float &b) fz = computeXYZ2Lab(z); L = computeXYZ2LabY(y); - a = (500.0f * (fx - fy)); - b = (200.0f * (fy - fz)); + a = (500.0f * (fx - fy) ); + b = (200.0f * (fy - fz) ); } void Color::Lab2Yuv(float L, float a, float b, float &Y, float &u, float &v) @@ -2006,8 +2006,8 @@ void Color::Yuv2Lab(float Yin, float u, float v, float &L, float &a, float &b, c float fz = computeXYZ2Lab(Z); L = computeXYZ2LabY(Y); - a = (500.0 * (fx - fy)); - b = (200.0 * (fy - fz)); + a = (500.0 * (fx - fy) ); + b = (200.0 * (fy - fz) ); } void Color::Lab2Lch(float a, float b, float &c, float &h) @@ -2058,6 +2058,7 @@ void Color::Lch2Luv(float c, float h, float &u, float &v) v = c * sincosval.y; } + /* * Gamut mapping algorithm * Copyright (c) 2010-2011 Emil Martinec @@ -2092,7 +2093,7 @@ void Color::gamutmap(float &X, float &Y, float &Z, const double p[3][3]) int c1 = (c + 1) % 3; int c2 = (c + 2) % 3; - lam[c][m] = (- (p[0][c1] * p[1][c] * ((-12 + 3 * u0 + 20 * v0) * Y + 4 * m * 65535 * v0 * p[2][c2])) + + lam[c][m] = (-(p[0][c1] * p[1][c] * ((-12 + 3 * u0 + 20 * v0) * Y + 4 * m * 65535 * v0 * p[2][c2])) + p[0][c] * p[1][c1] * ((-12 + 3 * u0 + 20 * v0) * Y + 4 * m * 65535 * v0 * p[2][c2]) - 4 * v0 * p[0][c1] * (Y - m * 65535 * p[1][c2]) * p[2][c] + 4 * v0 * p[0][c] * (Y - m * 65535 * p[1][c2]) * p[2][c1] - (4 * m * 65535 * v0 * p[0][c2] - 9 * u0 * Y) * (p[1][c1] * p[2][c] - p[1][c] * p[2][c1])); @@ -2115,7 +2116,7 @@ void Color::gamutmap(float &X, float &Y, float &Z, const double p[3][3]) Z = (12 - 3 * u - 20 * v) * Y / (4 * v); } -void Color::skinred(double J, double h, double sres, double Sp, float dred, float protect_red, int sk, float rstprotection, float ko, double &s) +void Color::skinred ( double J, double h, double sres, double Sp, float dred, float protect_red, int sk, float rstprotection, float ko, double &s) { float factorskin, factorsat, factor, factorskinext, interm; float scale = 100.0f / 100.1f; //reduction in normal zone @@ -2125,42 +2126,42 @@ void Color::skinred(double J, double h, double sres, double Sp, float dred, floa bool doskin = false; //rough correspondence between h (JC) and H (lab) that has relatively little importance because transitions that blur the correspondence is not linear - if ((float)h > 8.6f && (float)h <= 74.f) { + if ((float)h > 8.6f && (float)h <= 74.f ) { HH = (1.15f / 65.4f) * (float)h - 0.0012f; //H > 0.15 H<1.3 doskin = true; - } else if ((float)h > 0.f && (float)h <= 8.6f) { - HH = (0.19f / 8.6f) * (float)h - 0.04f; //H>-0.04 H < 0.15 + } else if((float)h > 0.f && (float)h <= 8.6f ) { + HH = (0.19f / 8.6f ) * (float)h - 0.04f; //H>-0.04 H < 0.15 doskin = true; - } else if ((float)h > 355.f && (float)h <= 360.f) { - HH = (0.11f / 5.0f) * (float)h - 7.96f; //H>-0.15 <-0.04 + } else if((float)h > 355.f && (float)h <= 360.f) { + HH = (0.11f / 5.0f ) * (float)h - 7.96f; //H>-0.15 <-0.04 doskin = true; - } else if ((float)h > 74.f && (float)h < 95.f) { + } else if((float)h > 74.f && (float)h < 95.f ) { HH = (0.30f / 21.0f) * (float)h + 0.24285f; //H>1.3 H<1.6 doskin = true; } - if (doskin) { + if(doskin) { float chromapro = sres / Sp; - if (sk == 1) { //in C mode to adapt dred to J - if (J < 16.0) { + if(sk == 1) { //in C mode to adapt dred to J + if (J < 16.0) { dred = 40.0f; - } else if (J < 22.0) { + } else if(J < 22.0) { dred = 2.5f * (float)J; - } else if (J < 60.0) { + } else if(J < 60.0) { dred = 55.0f; - } else if (J < 70.0) { + } else if(J < 70.0) { dred = -1.5f * (float)J + 145.0f; } else { dred = 40.0f; } } - if (chromapro > 0.0) { - Color::scalered(rstprotection, chromapro, 0.0, HH, deltaHH, scale, scaleext); //Scale factor + if(chromapro > 0.0) { + Color::scalered ( rstprotection, chromapro, 0.0, HH, deltaHH, scale, scaleext); //Scale factor } - if (chromapro > 1.0) { + if(chromapro > 1.0) { interm = (chromapro - 1.0f) * 100.0f; factorskin = 1.0f + (interm * scale) / 100.0f; factorskinext = 1.0f + (interm * scaleext) / 100.0f; @@ -2171,56 +2172,56 @@ void Color::skinred(double J, double h, double sres, double Sp, float dred, floa factorsat = chromapro; factor = factorsat; - Color::transitred(HH, s, dred, factorskin, protect_red, factorskinext, deltaHH, factorsat, factor); //transition + Color::transitred ( HH, s, dred, factorskin, protect_red, factorskinext, deltaHH, factorsat, factor); //transition s *= factor; } else { s = ko * sres; } } -void Color::skinredfloat(float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s) +void Color::skinredfloat ( float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s) { float HH; bool doskin = false; //rough correspondence between h (JC) and H (lab) that has relatively little importance because transitions that blur the correspondence is not linear - if ((float)h > 8.6f && (float)h <= 74.f) { + if ((float)h > 8.6f && (float)h <= 74.f ) { HH = (1.15f / 65.4f) * (float)h - 0.0012f; //H > 0.15 H<1.3 doskin = true; - } else if ((float)h > 0.f && (float)h <= 8.6f) { - HH = (0.19f / 8.6f) * (float)h - 0.04f; //H>-0.04 H < 0.15 + } else if((float)h > 0.f && (float)h <= 8.6f ) { + HH = (0.19f / 8.6f ) * (float)h - 0.04f; //H>-0.04 H < 0.15 doskin = true; - } else if ((float)h > 355.f && (float)h <= 360.f) { - HH = (0.11f / 5.0f) * (float)h - 7.96f; //H>-0.15 <-0.04 + } else if((float)h > 355.f && (float)h <= 360.f) { + HH = (0.11f / 5.0f ) * (float)h - 7.96f; //H>-0.15 <-0.04 doskin = true; - } else if ((float)h > 74.f && (float)h < 95.f) { + } else if((float)h > 74.f && (float)h < 95.f ) { HH = (0.30f / 21.0f) * (float)h + 0.24285f; //H>1.3 H<1.6 doskin = true; } - if (doskin) { + if(doskin) { float factorskin, factorsat, factor, factorskinext; float deltaHH = 0.3f; //HH value transition : I have choice 0.3 radians float chromapro = sres / Sp; - if (sk == 1) { //in C mode to adapt dred to J - if (J < 16.f) { + if(sk == 1) { //in C mode to adapt dred to J + if (J < 16.f) { dred = 40.f; - } else if (J < 22.f) { + } else if(J < 22.f) { dred = 2.5f * J; - } else if (J < 60.f) { + } else if(J < 60.f) { dred = 55.f; - } else if (J < 70.f) { + } else if(J < 70.f) { dred = 145.f - 1.5f * J; } else { dred = 40.f; } } - if (chromapro > 1.0) { + if(chromapro > 1.0) { float scale = 0.999000999f; // 100.0f/100.1f; reduction in normal zone float scaleext = 1.0f; //reduction in transition zone - Color::scalered(rstprotection, chromapro, 0.0, HH, deltaHH, scale, scaleext); //Scale factor + Color::scalered ( rstprotection, chromapro, 0.0, HH, deltaHH, scale, scaleext);//Scale factor float interm = (chromapro - 1.0f); factorskin = 1.0f + (interm * scale); factorskinext = 1.0f + (interm * scaleext); @@ -2231,7 +2232,7 @@ void Color::skinredfloat(float J, float h, float sres, float Sp, float dred, flo factorsat = chromapro; factor = factorsat; - Color::transitred(HH, s, dred, factorskin, protect_red, factorskinext, deltaHH, factorsat, factor); //transition + Color::transitred ( HH, s, dred, factorskin, protect_red, factorskinext, deltaHH, factorsat, factor); //transition s *= factor; } else { s = ko * sres; @@ -2244,19 +2245,19 @@ void Color::skinredfloat(float J, float h, float sres, float Sp, float dred, flo -void Color::scalered(const float rstprotection, const float param, const float limit, const float HH, const float deltaHH, float &scale, float &scaleext) +void Color::scalered ( const float rstprotection, const float param, const float limit, const float HH, const float deltaHH, float &scale, float &scaleext) { - if (rstprotection < 99.9999f) { - if (param > limit) { + if(rstprotection < 99.9999f) { + if(param > limit) { scale = rstprotection / 100.1f; } - if ((HH < (1.3f + deltaHH) && HH >= 1.3f)) + if((HH < (1.3f + deltaHH) && HH >= 1.3f)) // scaleext=HH*(1.0f-scale)/deltaHH + 1.0f - (1.3f+deltaHH)*(1.0f-scale)/deltaHH; //transition for Hue (red - yellow) // optimized formula { scaleext = (HH * (1.0f - scale) + deltaHH - (1.3f + deltaHH) * (1.0f - scale)) / deltaHH; //transition for Hue (red - yellow) - } else if ((HH < 0.15f && HH > (0.15f - deltaHH))) + } else if((HH < 0.15f && HH > (0.15f - deltaHH))) // scaleext=HH*(scale-1.0f)/deltaHH + 1.0f - (0.15f-deltaHH)*(scale-1.0f)/deltaHH; //transition for hue (red purple) // optimized formula { @@ -2265,15 +2266,15 @@ void Color::scalered(const float rstprotection, const float param, const float l } } -void Color::transitred(const float HH, float const Chprov1, const float dred, const float factorskin, const float protect_red, const float factorskinext, const float deltaHH, const float factorsat, float &factor) +void Color::transitred (const float HH, float const Chprov1, const float dred, const float factorskin, const float protect_red, const float factorskinext, const float deltaHH, const float factorsat, float &factor) { - if (HH >= 0.15f && HH < 1.3f) { + if(HH >= 0.15f && HH < 1.3f) { if (Chprov1 < dred) { factor = factorskin; - } else if (Chprov1 < (dred + protect_red)) { + } else if(Chprov1 < (dred + protect_red)) { factor = ((factorsat - factorskin) * Chprov1 + factorsat * protect_red - (dred + protect_red) * (factorsat - factorskin)) / protect_red; } - } else if (HH > (0.15f - deltaHH) && HH < (1.3f + deltaHH)) { // test if chroma is in the extended range + } else if ( HH > (0.15f - deltaHH) && HH < (1.3f + deltaHH) ) { // test if chroma is in the extended range if (Chprov1 < dred) { factor = factorskinext; // C=dred=55 => real max of skin tones } else if (Chprov1 < (dred + protect_red)) {// transition @@ -2309,7 +2310,7 @@ void Color::AllMunsellLch(bool lumaMuns, float Lprov1, float Loldd, float HH, fl float correctionHue = 0.0, correctionHueLum = 0.0; bool correctL; - if (CC >= 6.0 && CC < 140) { //if C > 140 we say C=140 (only in Prophoto ...with very large saturation) + if(CC >= 6.0 && CC < 140) { //if C > 140 we say C=140 (only in Prophoto ...with very large saturation) static const float huelimit[8] = { -2.48, -0.55, 0.44, 1.52, 1.87, 3.09, -0.27, 0.44}; //limits hue of blue-purple, red-yellow, green-yellow, red-purple if (Chprov1 > 140.f) { @@ -2320,16 +2321,16 @@ void Color::AllMunsellLch(bool lumaMuns, float Lprov1, float Loldd, float HH, fl Chprov1 = 6.f; } - for (int zo = 1; zo <= 4; zo++) { - if (HH > huelimit[2 * zo - 2] && HH < huelimit[2 * zo - 1]) { + for(int zo = 1; zo <= 4; zo++) { + if(HH > huelimit[2 * zo - 2] && HH < huelimit[2 * zo - 1]) { //zone=zo; contin1 = contin2 = false; correctL = false; - MunsellLch(Lprov1, HH, Chprov1, CC, correctionHue, zo, correctionHueLum, correctL); //munsell chroma correction + MunsellLch (Lprov1, HH, Chprov1, CC, correctionHue, zo, correctionHueLum, correctL); //munsell chroma correction #ifdef _DEBUG float absCorrectionHue = fabs(correctionHue); - if (correctionHue != 0.0) { + if(correctionHue != 0.0) { int idx = zo - 1; #pragma omp critical (maxdhue) { @@ -2337,18 +2338,18 @@ void Color::AllMunsellLch(bool lumaMuns, float Lprov1, float Loldd, float HH, fl } } - if (absCorrectionHue > 0.45) + if(absCorrectionHue > 0.45) #pragma omp atomic munsDbgInfo->depass++; //verify if no bug in calculation #endif correctionHuechroma = correctionHue; //preserve - if (lumaMuns) { + if(lumaMuns) { float correctlumprov = 0.f; float correctlumprov2 = 0.f; - if (correctL) { + if(correctL) { //for Munsell luminance correction correctlumprov = correctionHueLum; contin1 = true; @@ -2358,11 +2359,11 @@ void Color::AllMunsellLch(bool lumaMuns, float Lprov1, float Loldd, float HH, fl correctionHueLum = 0.0; correctionHue = 0.0; - if (fabs(Lprov1 - Loldd) > 6.0) { + if(fabs(Lprov1 - Loldd) > 6.0) { // correction if delta L significative..Munsell luminance - MunsellLch(Loldd, HH, Chprov1, Chprov1, correctionHue, zo, correctionHueLum, correctL); + MunsellLch (Loldd, HH, Chprov1, Chprov1, correctionHue, zo, correctionHueLum, correctL); - if (correctL) { + if(correctL) { correctlumprov2 = correctionHueLum; contin2 = true; correctL = false; @@ -2370,14 +2371,14 @@ void Color::AllMunsellLch(bool lumaMuns, float Lprov1, float Loldd, float HH, fl correctionHueLum = 0.0; - if (contin1 && contin2) { + if(contin1 && contin2) { correctlum = correctlumprov2 - correctlumprov; } #ifdef _DEBUG float absCorrectLum = fabs(correctlum); - if (correctlum != 0.0) { + if(correctlum != 0.0) { int idx = zo - 1; #pragma omp critical (maxdhuelum) { @@ -2385,7 +2386,7 @@ void Color::AllMunsellLch(bool lumaMuns, float Lprov1, float Loldd, float HH, fl } } - if (absCorrectLum > 0.35) + if(absCorrectLum > 0.35) #pragma omp atomic munsDbgInfo->depassLum++; //verify if no bug in calculation @@ -2399,15 +2400,15 @@ void Color::AllMunsellLch(bool lumaMuns, float Lprov1, float Loldd, float HH, fl #ifdef _DEBUG - if (correctlum < -0.35f) { + if (correctlum < -0.35f) { correctlum = -0.35f; - } else if (correctlum > 0.35f) { + } else if(correctlum > 0.35f) { correctlum = 0.35f; } - if (correctionHuechroma < -0.45f) { + if (correctionHuechroma < -0.45f) { correctionHuechroma = -0.45f; - } else if (correctionHuechroma > 0.45f) { + } else if(correctionHuechroma > 0.45f) { correctionHuechroma = 0.45f; } @@ -2472,9 +2473,9 @@ void Color::AllMunsellLch(float Lprov1, float HH, float Chprov1, float CC, float * bool neg and moreRGB : only in DEBUG mode to calculate iterations for negatives values and > 65535 */ #ifdef _DEBUG -void Color::gamutLchonly(float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb) +void Color::gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb) #else -void Color::gamutLchonly(float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef) +void Color::gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef) #endif { const float ClipLevel = 65535.0f; @@ -2492,7 +2493,7 @@ void Color::gamutLchonly(float HH, float &Lprov1, float &Chprov1, float &R, floa float bprov1 = Chprov1 * sincosval.x; //conversion Lab RGB to limit Lab values - this conversion is useful before Munsell correction - float fy = (c1By116 * Lprov1) + c16By116; + float fy = (c1By116 * Lprov1 ) + c16By116; float fx = (0.002f * aprov1) + fy; float fz = fy - (0.005f * bprov1); @@ -2514,32 +2515,32 @@ void Color::gamutLchonly(float HH, float &Lprov1, float &Chprov1, float &R, floa } //gamut for L with ultra blue : we can improve the algorithm ... thinner, and other color ??? - if (HH < -0.9f && HH > -1.55f) { //ultra blue - if (Chprov1 > 160.f) if (Lprov1 < 5.f) { + if(HH < -0.9f && HH > -1.55f ) {//ultra blue + if(Chprov1 > 160.f) if (Lprov1 < 5.f) { Lprov1 = 5.f; //very very very very high chroma } - if (Chprov1 > 140.f) if (Lprov1 < 3.5f) { + if(Chprov1 > 140.f) if (Lprov1 < 3.5f) { Lprov1 = 3.5f; } - if (Chprov1 > 120.f) if (Lprov1 < 2.f) { + if(Chprov1 > 120.f) if (Lprov1 < 2.f) { Lprov1 = 2.f; } - if (Chprov1 > 105.f) if (Lprov1 < 1.f) { + if(Chprov1 > 105.f) if (Lprov1 < 1.f) { Lprov1 = 1.f; } - if (Chprov1 > 90.f) if (Lprov1 < 0.7f) { + if(Chprov1 > 90.f) if (Lprov1 < 0.7f) { Lprov1 = 0.7f; } - if (Chprov1 > 50.f) if (Lprov1 < 0.5f) { + if(Chprov1 > 50.f) if (Lprov1 < 0.5f) { Lprov1 = 0.5f; } - if (Chprov1 > 20.f) if (Lprov1 < 0.4f) { + if(Chprov1 > 20.f) if (Lprov1 < 0.4f) { Lprov1 = 0.4f; } } @@ -2593,9 +2594,9 @@ void Color::gamutLchonly(float HH, float &Lprov1, float &Chprov1, float &R, floa * bool neg and moreRGB : only in DEBUG mode to calculate iterations for negatives values and > 65535 */ #ifdef _DEBUG -void Color::gamutLchonly(float HH, float2 sincosval, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb) +void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb) #else -void Color::gamutLchonly(float HH, float2 sincosval, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef) +void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef) #endif { constexpr float ClipLevel = 65535.0f; @@ -2612,7 +2613,7 @@ void Color::gamutLchonly(float HH, float2 sincosval, float &Lprov1, float &Chpro float bprov1 = Chprov1 * sincosval.x; //conversion Lab RGB to limit Lab values - this conversion is useful before Munsell correction - float fy = (c1By116 * Lprov1) + c16By116; + float fy = (c1By116 * Lprov1 ) + c16By116; float fx = (0.002f * aprov1) + fy; float fz = fy - (0.005f * bprov1); @@ -2639,32 +2640,32 @@ void Color::gamutLchonly(float HH, float2 sincosval, float &Lprov1, float &Chpro } //gamut for L with ultra blue : we can improve the algorithm ... thinner, and other color ??? - if (HH < -0.9f && HH > -1.55f) { //ultra blue - if (Chprov1 > 160.f) if (Lprov1 < 5.f) { + if(HH < -0.9f && HH > -1.55f ) {//ultra blue + if(Chprov1 > 160.f) if (Lprov1 < 5.f) { Lprov1 = 5.f; //very very very very high chroma } - if (Chprov1 > 140.f) if (Lprov1 < 3.5f) { + if(Chprov1 > 140.f) if (Lprov1 < 3.5f) { Lprov1 = 3.5f; } - if (Chprov1 > 120.f) if (Lprov1 < 2.f) { + if(Chprov1 > 120.f) if (Lprov1 < 2.f) { Lprov1 = 2.f; } - if (Chprov1 > 105.f) if (Lprov1 < 1.f) { + if(Chprov1 > 105.f) if (Lprov1 < 1.f) { Lprov1 = 1.f; } - if (Chprov1 > 90.f) if (Lprov1 < 0.7f) { + if(Chprov1 > 90.f) if (Lprov1 < 0.7f) { Lprov1 = 0.7f; } - if (Chprov1 > 50.f) if (Lprov1 < 0.5f) { + if(Chprov1 > 50.f) if (Lprov1 < 0.5f) { Lprov1 = 0.5f; } - if (Chprov1 > 20.f) if (Lprov1 < 0.4f) { + if(Chprov1 > 20.f) if (Lprov1 < 0.4f) { Lprov1 = 0.4f; } } @@ -2805,9 +2806,9 @@ void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chpr #ifdef _DEBUG -void Color::gamutLchonly(float2 sincosval, float &Lprov1, float &Chprov1, const float wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb) +void Color::gamutLchonly (float2 sincosval, float &Lprov1, float &Chprov1, const float wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb) #else -void Color::gamutLchonly(float2 sincosval, float &Lprov1, float &Chprov1, const float wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef) +void Color::gamutLchonly (float2 sincosval, float &Lprov1, float &Chprov1, const float wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef) #endif { const float ClipLevel = 65535.0f; @@ -2824,7 +2825,7 @@ void Color::gamutLchonly(float2 sincosval, float &Lprov1, float &Chprov1, const float bprov1 = Chprov1 * sincosval.x; //conversion Lab RGB to limit Lab values - this conversion is useful before Munsell correction - float fy = (c1By116 * Lprov1) + c16By116; + float fy = (c1By116 * Lprov1 ) + c16By116; float fx = (0.002f * aprov1) + fy; float fz = fy - (0.005f * bprov1); @@ -2927,7 +2928,7 @@ void Color::LabGamutMunsell(float *labL, float *laba, float *labb, const int N, _mm_storeu_ps(&CCBuffer[k], vsqrtf(SQRV(av) + SQRV(bv)) / c327d68v); } - for (; k < N; k++) { + for(; k < N; k++) { HHBuffer[k] = xatan2f(labb[k], laba[k]); CCBuffer[k] = sqrt(SQR(laba[k]) + SQR(labb[k])) / 327.68f; } @@ -2947,14 +2948,14 @@ void Color::LabGamutMunsell(float *labL, float *laba, float *labb, const int N, float Coldd = Chprov1; float2 sincosval; - if (gamut) { + if(gamut) { #ifdef _DEBUG bool neg, more_rgb; #endif // According to mathematical laws we can get the sin and cos of HH by simple operations float R, G, B; - if (Chprov1 == 0.f) { + if(Chprov1 == 0.f) { sincosval.y = 1.f; sincosval.x = 0.f; } else { @@ -2971,11 +2972,11 @@ void Color::LabGamutMunsell(float *labL, float *laba, float *labb, const int N, #ifdef _DEBUG - if (neg) { + if(neg) { negat++; } - if (more_rgb) { + if(more_rgb) { moreRGB++; } @@ -2986,7 +2987,7 @@ void Color::LabGamutMunsell(float *labL, float *laba, float *labb, const int N, correctionHuechroma = 0.f; correctlum = 0.f; - if (corMunsell) + if(corMunsell) #ifdef _DEBUG AllMunsellLch(lumaMuns, Lprov1, Loldd, HH, Chprov1, Coldd, correctionHuechroma, correctlum, MunsDebugInfo); @@ -2994,9 +2995,9 @@ void Color::LabGamutMunsell(float *labL, float *laba, float *labb, const int N, AllMunsellLch(lumaMuns, Lprov1, Loldd, HH, Chprov1, Coldd, correctionHuechroma, correctlum); #endif - if (correctlum == 0.f && correctionHuechroma == 0.f) { - if (!gamut) { - if (Coldd == 0.f) { + if(correctlum == 0.f && correctionHuechroma == 0.f) { + if(!gamut) { + if(Coldd == 0.f) { sincosval.y = 1.f; sincosval.x = 0.f; } else { @@ -3023,7 +3024,7 @@ void Color::LabGamutMunsell(float *labL, float *laba, float *labb, const int N, if (MunsDebugInfo) { printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%u\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass); - printf(" Munsell luminance : MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%u\n", MunsDebugInfo->maxdhuelum[0], MunsDebugInfo->maxdhuelum[1], MunsDebugInfo->maxdhuelum[2], MunsDebugInfo->maxdhuelum[3], MunsDebugInfo->depassLum); + printf(" Munsell luminance : MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%u\n", MunsDebugInfo->maxdhuelum[0] , MunsDebugInfo->maxdhuelum[1], MunsDebugInfo->maxdhuelum[2], MunsDebugInfo->maxdhuelum[3], MunsDebugInfo->depassLum); } else { printf(" Munsell correction wasn't requested\n"); } @@ -3037,1384 +3038,6 @@ void Color::LabGamutMunsell(float *labL, float *laba, float *labb, const int N, } -/* - * MunsellLch correction - * Copyright (c) 2012 Jacques Desmis - * - * Find the right LUT and calculate the correction - */ -void Color::MunsellLch(float lum, float hue, float chrom, float memChprov, float &correction, int zone, float &lbe, bool &correctL) -{ - - int x = int (memChprov); - int y = int (chrom); - - //begin PB correction + sky - if (zone == 1) { - if (lum > 5.0) { - if (lum < 15.0) { - if ((hue >= (_15PB10[x] - 0.035)) && (hue < (_15PB10[x] + 0.052) && x <= 45)) { - if (y > 49) { - y = 49; - } - - correction = _15PB10[y] - _15PB10[x] ; - lbe = _15PB10[y]; - correctL = true; - } else if ((hue >= (_3PB10[x] - 0.052)) && (hue < (_45PB10[x] + _3PB10[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _3PB10[y] - _3PB10[x]; - lbe = _3PB10[y]; - correctL = true; - } else if ((hue >= (_45PB10[x] + _3PB10[x]) / 2.0) && (hue < (_45PB10[x] + 0.052)) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _45PB10[y] - _45PB10[x] ; - lbe = _45PB10[y]; - correctL = true; - } else if ((hue >= (_6PB10[x] - 0.052) && (hue < (_6PB10[x] + _75PB10[x]) / 2.0))) { - correction = _6PB10[y] - _6PB10[x] ; - lbe = _6PB10[y]; - correctL = true; - } else if ((hue >= (_6PB10[x] + _75PB10[x]) / 2.0) && (hue < (_9PB10[x] + _75PB10[x]) / 2.0)) { - correction = _75PB10[y] - _75PB10[x] ; - lbe = _75PB10[y]; - correctL = true; - } else if ((hue >= (_9PB10[x] + _75PB10[x]) / 2.0) && (hue < (_9PB10[x] + _10PB10[x]) / 2.0)) { - correction = _9PB10[y] - _9PB10[x] ; - lbe = _9PB10[y]; - correctL = true; - } else if ((hue >= (_10PB10[x] + _9PB10[x]) / 2.0) && (hue < (_1P10[x] + _10PB10[x]) / 2.0)) { - correction = _10PB10[y] - _10PB10[x] ; - lbe = _10PB10[y]; - correctL = true; - } else if ((hue >= (_10PB10[x] + _1P10[x]) / 2.0) && (hue < (_1P10[x] + _4P10[x]) / 2.0)) { - correction = _1P10[y] - _1P10[x]; - lbe = _1P10[y]; - correctL = true; - } else if ((hue >= (_1P10[x] + _4P10[x]) / 2.0) && (hue < (0.035 + _4P10[x]) / 2.0)) { - correction = _4P10[y] - _4P10[x] ; - lbe = _4P10[y]; - correctL = true; - } - } else if (lum < 25.0) { - if ((hue >= (_15PB20[x] - 0.035)) && (hue < (_15PB20[x] + _3PB20[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _15PB20[y] - _15PB20[x] ; - lbe = _15PB20[y]; - correctL = true; - } else if ((hue >= (_15PB20[x] + _3PB20[x]) / 2.0) && (hue < (_45PB20[x] + _3PB20[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _3PB20[y] - _3PB20[x] ; - lbe = _3PB20[y]; - correctL = true; - } else if ((hue >= (_45PB20[x] + _3PB20[x]) / 2.0) && (hue < (_45PB20[x] + 0.052)) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _45PB20[y] - _45PB20[x] ; - lbe = _45PB20[y]; - correctL = true; - } else if ((hue >= (_45PB20[x] + 0.052)) && (hue < (_6PB20[x] + _75PB20[x]) / 2.0)) { - correction = _6PB20[y] - _6PB20[x]; - lbe = _6PB20[y]; - correctL = true; - } else if ((hue >= (_6PB20[x] + _75PB20[x]) / 2.0) && (hue < (_9PB20[x] + _75PB20[x]) / 2.0)) { - correction = _75PB20[y] - _75PB20[x] ; - lbe = _75PB20[y]; - correctL = true; - } else if ((hue >= (_9PB20[x] + _75PB20[x]) / 2.0) && (hue < (_9PB20[x] + _10PB20[x]) / 2.0)) { - correction = _9PB20[y] - _9PB20[x] ; - lbe = _9PB20[y]; - correctL = true; - } else if ((hue >= (_10PB20[x] + _9PB20[x]) / 2.0) && (hue < (_1P20[x] + _10PB20[x]) / 2.0)) { - correction = _10PB20[y] - _10PB20[x] ; - lbe = _10PB20[y]; - correctL = true; - } else if ((hue >= (_10PB20[x] + _1P20[x]) / 2.0) && (hue < (_1P20[x] + _4P20[x]) / 2.0)) { - correction = _1P20[y] - _1P20[x] ; - lbe = _1P20[y]; - correctL = true; - } else if ((hue >= (_1P20[x] + _4P20[x]) / 2.0) && (hue < (0.035 + _4P20[x]) / 2.0)) { - correction = _4P20[y] - _4P20[x] ; - lbe = _4P20[y]; - correctL = true; - } - } else if (lum < 35.0) { - if ((hue >= (_15PB30[x] - 0.035)) && (hue < (_15PB30[x] + _3PB30[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _15PB30[y] - _15PB30[x] ; - lbe = _15PB30[y]; - correctL = true; - } else if ((hue >= (_15PB30[x] + _3PB30[x]) / 2.0) && (hue < (_45PB30[x] + _3PB30[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _3PB30[y] - _3PB30[x] ; - lbe = _3PB30[y]; - correctL = true; - } else if ((hue >= (_45PB30[x] + _3PB30[x]) / 2.0) && (hue < (_45PB30[x] + 0.052)) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _45PB30[y] - _45PB30[x] ; - lbe = _45PB30[y]; - correctL = true; - } else if ((hue >= (_45PB30[x] + 0.052)) && (hue < (_6PB30[x] + _75PB30[x]) / 2.0)) { - correction = _6PB30[y] - _6PB30[x] ; - lbe = _6PB30[y]; - correctL = true; - } else if ((hue >= (_6PB30[x] + _75PB30[x]) / 2.0) && (hue < (_9PB30[x] + _75PB30[x]) / 2.0)) { - correction = _75PB30[y] - _75PB30[x] ; - lbe = _75PB30[y] ; - correctL = true; - } else if ((hue >= (_9PB30[x] + _75PB30[x]) / 2.0) && (hue < (_9PB30[x] + _10PB30[x]) / 2.0)) { - correction = _9PB30[y] - _9PB30[x] ; - lbe = _9PB30[y]; - correctL = true; - } else if ((hue >= (_10PB30[x] + _9PB30[x]) / 2.0) && (hue < (_1P30[x] + _10PB30[x]) / 2.0)) { - correction = _10PB30[y] - _10PB30[x] ; - lbe = _10PB30[y]; - correctL = true; - } else if ((hue >= (_10PB30[x] + _1P30[x]) / 2.0) && (hue < (_1P30[x] + _4P30[x]) / 2.0)) { - correction = _1P30[y] - _1P30[x] ; - lbe = _1P30[y]; - correctL = true; - } else if ((hue >= (_1P30[x] + _4P30[x]) / 2.0) && (hue < (0.035 + _4P30[x]) / 2.0)) { - correction = _4P30[y] - _4P30[x] ; - lbe = _4P30[y]; - correctL = true; - } - } else if (lum < 45.0) { - if ((hue <= (_05PB40[x] + _15PB40[x]) / 2.0) && (hue > (_05PB40[x] + _10B40[x]) / 2.0) && x < 75) { - if (y > 75) { - y = 75; - } - - correction = _05PB40[y] - _05PB40[x] ; - lbe = _05PB40[y]; - correctL = true; - } else if ((hue <= (_05PB40[x] + _10B40[x]) / 2.0) && (hue > (_10B40[x] + _9B40[x]) / 2.0) && x < 70) { - if (y > 70) { - y = 70; - } - - correction = _10B40[y] - _10B40[x] ; - lbe = _10B40[y]; - correctL = true; - } else if ((hue <= (_10B40[x] + _9B40[x]) / 2.0) && (hue > (_9B40[x] + _7B40[x]) / 2.0) && x < 70) { - if (y > 70) { - y = 70; - } - - correction = _9B40[y] - _9B40[x] ; - lbe = _9B40[y]; - correctL = true; - } else if ((hue <= (_9B40[x] + _7B40[x]) / 2.0) && (hue > (_5B40[x] + _7B40[x]) / 2.0) && x < 70) { - if (y > 70) { - y = 70; - } - - correction = _7B40[y] - _7B40[x] ; - lbe = _7B40[y]; - correctL = true; - } else if ((hue <= (_5B40[x] + _7B40[x]) / 2.0) && (hue > (_5B40[x] - 0.035)) && x < 70) { - if (y > 70) { - y = 70; // - } - - correction = _5B40[y] - _5B40[x] ; - lbe = _5B40[y]; - correctL = true; - } - - else if ((hue >= (_15PB40[x] - 0.035)) && (hue < (_15PB40[x] + _3PB40[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _15PB40[y] - _15PB40[x] ; - lbe = _15PB40[y]; - correctL = true; - } else if ((hue >= (_15PB40[x] + _3PB40[x]) / 2.0) && (hue < (_45PB40[x] + _3PB40[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _3PB40[y] - _3PB40[x] ; - lbe = _3PB40[y]; - correctL = true; - } else if ((hue >= (_45PB40[x] + _3PB40[x]) / 2.0) && (hue < (_45PB40[x] + 0.052)) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _45PB40[y] - _45PB40[x] ; - lbe = _45PB40[y] ; - correctL = true; - } else if ((hue >= (_45PB40[x] + 0.052)) && (hue < (_6PB40[x] + _75PB40[x]) / 2.0)) { - correction = _6PB40[y] - _6PB40[x] ; - lbe = _6PB40[y]; - correctL = true; - } else if ((hue >= (_6PB40[x] + _75PB40[x]) / 2.0) && (hue < (_9PB40[x] + _75PB40[x]) / 2.0)) { - correction = _75PB40[y] - _75PB40[x] ; - lbe = _75PB40[y]; - correctL = true; - } else if ((hue >= (_9PB40[x] + _75PB40[x]) / 2.0) && (hue < (_9PB40[x] + _10PB40[x]) / 2.0)) { - correction = _9PB40[y] - _9PB40[x] ; - lbe = _9PB40[y]; - correctL = true; - } else if ((hue >= (_10PB40[x] + _9PB40[x]) / 2.0) && (hue < (_1P40[x] + _10PB40[x]) / 2.0)) { - correction = _10PB40[y] - _10PB40[x] ; - lbe = _10PB40[y]; - correctL = true; - } else if ((hue >= (_10PB40[x] + _1P40[x]) / 2.0) && (hue < (_1P40[x] + _4P40[x]) / 2.0)) { - correction = _1P40[y] - _1P40[x] ; - lbe = _1P40[y]; - correctL = true; - } else if ((hue >= (_1P40[x] + _4P40[x]) / 2.0) && (hue < (0.035 + _4P40[x]) / 2.0)) { - correction = _4P40[y] - _4P40[x] ; - lbe = _4P40[y]; - correctL = true; - } - } else if (lum < 55.0) { - if ((hue <= (_05PB50[x] + _15PB50[x]) / 2.0) && (hue > (_05PB50[x] + _10B50[x]) / 2.0) && x < 79) { - if (y > 79) { - y = 79; - } - - correction = _05PB50[y] - _05PB50[x] ; - lbe = _05PB50[y]; - correctL = true; - } else if ((hue <= (_05PB50[x] + _10B50[x]) / 2.0) && (hue > (_10B50[x] + _9B50[x]) / 2.0) && x < 79) { - if (y > 79) { - y = 79; - } - - correction = _10B50[y] - _10B50[x] ; - lbe = _10B50[y]; - correctL = true; - } else if ((hue <= (_10B50[x] + _9B50[x]) / 2.0) && (hue > (_9B50[x] + _7B50[x]) / 2.0) && x < 79) { - if (y > 79) { - y = 79; - } - - correction = _9B50[y] - _9B50[x] ; - lbe = _9B50[y]; - correctL = true; - } else if ((hue <= (_9B50[x] + _7B50[x]) / 2.0) && (hue > (_5B50[x] + _7B50[x]) / 2.0) && x < 79) { - if (y > 79) { - y = 79; - } - - correction = _7B50[y] - _7B50[x] ; - lbe = _7B50[y]; - correctL = true; - } else if ((hue <= (_5B50[x] + _7B50[x]) / 2.0) && (hue > (_5B50[x] - 0.035)) && x < 79) { - if (y > 79) { - y = 79; // - } - - correction = _5B50[y] - _5B50[x] ; - lbe = _5B50[y]; - correctL = true; - } - - else if ((hue >= (_15PB50[x] - 0.035)) && (hue < (_15PB50[x] + _3PB50[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _15PB50[y] - _15PB50[x] ; - lbe = _15PB50[y]; - correctL = true; - } else if ((hue >= (_15PB50[x] + _3PB50[x]) / 2.0) && (hue < (_45PB50[x] + _3PB50[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _3PB50[y] - _3PB50[x] ; - lbe = _3PB50[y]; - correctL = true; - } else if ((hue >= (_45PB50[x] + _3PB50[x]) / 2.0) && (hue < (_6PB50[x] + _45PB50[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _45PB50[y] - _45PB50[x] ; - lbe = _45PB50[y]; - correctL = true; - } else if ((hue >= (_6PB50[x] + _45PB50[x]) / 2.0) && (hue < (_6PB50[x] + _75PB50[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _6PB50[y] - _6PB50[x] ; - lbe = _6PB50[y]; - correctL = true; - } else if ((hue >= (_6PB50[x] + _75PB50[x]) / 2.0) && (hue < (_9PB50[x] + _75PB50[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _75PB50[y] - _75PB50[x] ; - lbe = _75PB50[y]; - correctL = true; - } else if ((hue >= (_9PB50[x] + _75PB50[x]) / 2.0) && (hue < (_9PB50[x] + _10PB50[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _9PB50[y] - _9PB50[x] ; - lbe = _9PB50[y]; - correctL = true; - } else if ((hue >= (_10PB50[x] + _9PB50[x]) / 2.0) && (hue < (_1P50[x] + _10PB50[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _10PB50[y] - _10PB50[x] ; - lbe = _10PB50[y]; - correctL = true; - } else if ((hue >= (_10PB50[x] + _1P50[x]) / 2.0) && (hue < (_1P50[x] + _4P50[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _1P50[y] - _1P50[x] ; - lbe = _1P50[y]; - correctL = true; - } else if ((hue >= (_1P50[x] + _4P50[x]) / 2.0) && (hue < (0.035 + _4P50[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _4P50[y] - _4P50[x] ; - lbe = _4P50[y]; - correctL = true; - } - } else if (lum < 65.0) { - if ((hue <= (_05PB60[x] + _15PB60[x]) / 2.0) && (hue > (_05PB60[x] + _10B60[x]) / 2.0) && x < 79) { - if (y > 79) { - y = 79; - } - - correction = _05PB60[y] - _05PB60[x] ; - lbe = _05PB60[y]; - correctL = true; - } else if ((hue <= (_05PB60[x] + _10B60[x]) / 2.0) && (hue > (_10B60[x] + _9B60[x]) / 2.0) && x < 79) { - if (y > 79) { - y = 79; - } - - correction = _10B60[y] - _10B60[x] ; - lbe = _10B60[y]; - correctL = true; - } else if ((hue <= (_10B60[x] + _9B60[x]) / 2.0) && (hue > (_9B60[x] + _7B60[x]) / 2.0) && x < 79) { - if (y > 79) { - y = 79; - } - - correction = _9B60[y] - _9B60[x] ; - lbe = _9B60[y]; - correctL = true; - } else if ((hue <= (_9B60[x] + _7B60[x]) / 2.0) && (hue > (_5B60[x] + _7B60[x]) / 2.0) && x < 79) { - if (y > 79) { - y = 79; - } - - correction = _7B60[y] - _7B60[x] ; - lbe = _7B60[y]; - correctL = true; - } else if ((hue <= (_5B60[x] + _7B60[x]) / 2.0) && (hue > (_5B60[x] - 0.035)) && x < 79) { - if (y > 79) { - y = 79; // - } - - correction = _5B60[y] - _5B60[x] ; - lbe = _5B60[y]; - correctL = true; - } - - else if ((hue >= (_15PB60[x] - 0.035)) && (hue < (_15PB60[x] + _3PB60[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _15PB60[y] - _15PB60[x] ; - lbe = _15PB60[y]; - correctL = true; - } else if ((hue >= (_15PB60[x] + _3PB60[x]) / 2.0) && (hue < (_45PB60[x] + _3PB60[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _3PB60[y] - _3PB60[x] ; - lbe = _3PB60[y]; - correctL = true; - } else if ((hue >= (_45PB60[x] + _3PB60[x]) / 2.0) && (hue < (_6PB60[x] + _45PB60[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _45PB60[y] - _45PB60[x] ; - lbe = _45PB60[y]; - correctL = true; - } else if ((hue >= (_6PB60[x] + _45PB60[x]) / 2.0) && (hue < (_6PB60[x] + _75PB60[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _6PB60[y] - _6PB60[x] ; - lbe = _6PB60[y]; - correctL = true; - } else if ((hue >= (_6PB60[x] + _75PB60[x]) / 2.0) && (hue < (_9PB60[x] + _75PB60[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _75PB60[y] - _75PB60[x] ; - lbe = _75PB60[y]; - correctL = true; - } else if ((hue >= (_9PB60[x] + _75PB60[x]) / 2.0) && (hue < (_9PB60[x] + _10PB60[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _9PB60[y] - _9PB60[x] ; - lbe = _9PB60[y]; - correctL = true; - } else if ((hue >= (_10PB60[x] + _9PB60[x]) / 2.0) && (hue < (_1P60[x] + _10PB60[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _10PB60[y] - _10PB60[x] ; - lbe = _10PB60[y]; - correctL = true; - } else if ((hue >= (_10PB60[x] + _1P60[x]) / 2.0) && (hue < (_1P60[x] + _4P60[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _1P60[y] - _1P60[x] ; - lbe = _1P60[y]; - correctL = true; - } else if ((hue >= (_1P60[x] + _4P60[x]) / 2.0) && (hue < (0.035 + _4P60[x]) / 2.0) && x <= 85) { - if (y > 89) { - y = 89; - } - - correction = _4P60[y] - _4P60[x] ; - lbe = _4P60[y]; - correctL = true; - } - } else if (lum < 75.0) { - if ((hue <= (_05PB70[x] + _15PB70[x]) / 2.0) && (hue > (_05PB70[x] + _10B70[x]) / 2.0) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _05PB70[y] - _05PB70[x] ; - lbe = _05PB70[y]; - correctL = true; - } else if ((hue <= (_05PB70[x] + _10B70[x]) / 2.0) && (hue > (_10B70[x] + _9B70[x]) / 2.0) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _10B70[y] - _10B70[x] ; - lbe = _10B70[y]; - correctL = true; - } else if ((hue <= (_10B70[x] + _9B70[x]) / 2.0) && (hue > (_9B70[x] + _7B70[x]) / 2.0) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _9B70[y] - _9B70[x] ; - lbe = _9B70[y]; - correctL = true; - } else if ((hue <= (_9B70[x] + _7B70[x]) / 2.0) && (hue > (_5B70[x] + _7B70[x]) / 2.0) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _7B70[y] - _7B70[x] ; - lbe = _7B70[y]; - correctL = true; - } else if ((hue <= (_5B70[x] + _7B70[x]) / 2.0) && (hue > (_5B70[x] - 0.035)) && x < 50) { - if (y > 49) { - y = 49; // - } - - correction = _5B70[y] - _5B70[x] ; - lbe = _5B70[y]; - correctL = true; - } - - else if ((hue >= (_15PB70[x] - 0.035)) && (hue < (_15PB70[x] + _3PB70[x]) / 2.0) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _15PB70[y] - _15PB70[x] ; - lbe = _15PB70[y]; - correctL = true; - } else if ((hue >= (_45PB70[x] + _3PB70[x]) / 2.0) && (hue < (_6PB70[x] + _45PB70[x]) / 2.0) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _45PB70[y] - _45PB70[x] ; - lbe = _45PB70[y]; - correctL = true; - } else if ((hue >= (_6PB70[x] + _45PB70[x]) / 2.0) && (hue < (_6PB70[x] + _75PB70[x]) / 2.0) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _6PB70[y] - _6PB70[x] ; - lbe = _6PB70[y]; - correctL = true; - } else if ((hue >= (_6PB70[x] + _75PB70[x]) / 2.0) && (hue < (_9PB70[x] + _75PB70[x]) / 2.0) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _75PB70[y] - _75PB70[x] ; - lbe = _75PB70[y]; - correctL = true; - } else if ((hue >= (_9PB70[x] + _75PB70[x]) / 2.0) && (hue < (_9PB70[x] + 0.035)) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _9PB70[y] - _9PB70[x] ; - lbe = _9PB70[y]; - correctL = true; - } - } else if (lum < 85.0) { - if ((hue <= (_05PB80[x] + _15PB80[x]) / 2.0) && (hue > (_05PB80[x] + _10B80[x]) / 2.0) && x < 40) { - if (y > 39) { - y = 39; - } - - correction = _05PB80[y] - _05PB80[x] ; - lbe = _05PB80[y] ; - correctL = true; - } else if ((hue <= (_05PB80[x] + _10B80[x]) / 2.0) && (hue > (_10B80[x] + _9B80[x]) / 2.0) && x < 40) { - if (y > 39) { - y = 39; - } - - correction = _10B80[y] - _10B80[x] ; - lbe = _10B80[y]; - correctL = true; - } else if ((hue <= (_10B80[x] + _9B80[x]) / 2.0) && (hue > (_9B80[x] + _7B80[x]) / 2.0) && x < 40) { - if (y > 39) { - y = 39; - } - - correction = _9B80[y] - _9B80[x] ; - lbe = _9B80[y]; - correctL = true; - } else if ((hue <= (_9B80[x] + _7B80[x]) / 2.0) && (hue > (_5B80[x] + _7B80[x]) / 2.0) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _7B80[y] - _7B80[x] ; - lbe = _7B80[y]; - correctL = true; - } else if ((hue <= (_5B80[x] + _7B80[x]) / 2.0) && (hue > (_5B80[x] - 0.035)) && x < 50) { - if (y > 49) { - y = 49; // - } - - correction = _5B80[y] - _5B80[x] ; - lbe = _5B80[y]; - correctL = true; - } - - else if ((hue >= (_15PB80[x] - 0.035)) && (hue < (_15PB80[x] + _3PB80[x]) / 2.0) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _15PB80[y] - _15PB80[x] ; - lbe = _15PB80[y]; - correctL = true; - } else if ((hue >= (_45PB80[x] + _3PB80[x]) / 2.0) && (hue < (_6PB80[x] + _45PB80[x]) / 2.0) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _45PB80[y] - _45PB80[x] ; - lbe = _45PB80[y]; - correctL = true; - } else if ((hue >= (_6PB80[x] + _45PB80[x]) / 2.0) && (hue < (_6PB80[x] + _75PB80[x]) / 2.0) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _6PB80[y] - _6PB80[x] ; - lbe = _6PB80[y]; - correctL = true; - } else if ((hue >= (_6PB80[x] + _75PB80[x]) / 2.0) && (hue < (_9PB80[x] + _75PB80[x]) / 2.0) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _75PB80[y] - _75PB80[x] ; - lbe = _75PB80[y]; - correctL = true; - } else if ((hue >= (_9PB80[x] + _75PB80[x]) / 2.0) && (hue < (_9PB80[x] + 0.035)) && x < 50) { - if (y > 49) { - y = 49; - } - - correction = _9PB80[y] - _9PB80[x] ; - lbe = _9PB80[y]; - correctL = true; - } - } - } - } - // end PB correction - - //red yellow correction - else if (zone == 2) { - if (lum > 15.0) { - if (lum < 25.0) { - if ((hue <= (_10YR20[x] + 0.035)) && (hue > (_10YR20[x] + _85YR20[x]) / 2.0) && x <= 45) { - if (y > 49) { - y = 49; - } - - correction = _10YR20[y] - _10YR20[x] ; - lbe = _10YR20[y]; - correctL = true; - } else if ((hue <= (_85YR20[x] + _10YR20[x]) / 2.0) && (hue > (_85YR20[x] + 0.035) && x <= 45)) { - if (y > 49) { - y = 49; - } - - correction = _85YR20[y] - _85YR20[x] ; - lbe = _85YR20[y]; - correctL = true; - } - } else if (lum < 35.0) { - if ((hue <= (_10YR30[x] + 0.035)) && (hue > (_10YR30[x] + _85YR30[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _10YR30[y] - _10YR30[x] ; - lbe = _10YR30[y]; - correctL = true; - } else if ((hue <= (_10YR30[x] + _85YR30[x]) / 2.0) && (hue > (_85YR30[x] + _7YR30[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _85YR30[y] - _85YR30[x] ; - lbe = _85YR30[y]; - correctL = true; - } else if ((hue <= (_85YR30[x] + _7YR30[x]) / 2.0) && (hue > (_7YR30[x] + _55YR30[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _7YR30[y] - _7YR30[x] ; - lbe = _7YR30[y]; - correctL = true; - } else if ((hue <= (_7YR30[x] + _55YR30[x]) / 2.0) && (hue > (_55YR30[x] + _4YR30[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _55YR30[y] - _55YR30[x] ; - lbe = _55YR30[y]; - correctL = true; - } else if ((hue <= (_55YR30[x] + _4YR30[x]) / 2.0) && (hue > (_4YR30[x] + _25YR30[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _4YR30[y] - _4YR30[x] ; - lbe = _4YR30[y]; - correctL = true; - } else if ((hue <= (_4YR30[x] + _25YR30[x]) / 2.0) && (hue > (_25YR30[x] + _10R30[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _25YR30[y] - _25YR30[x] ; - lbe = _25YR30[y]; - correctL = true; - } else if ((hue <= (_25YR30[x] + _10R30[x]) / 2.0) && (hue > (_10R30[x] + _9R30[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _10R30[y] - _10R30[x] ; - lbe = _10R30[y]; - correctL = true; - } else if ((hue <= (_10R30[x] + _9R30[x]) / 2.0) && (hue > (_9R30[x] + _7R30[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _9R30[y] - _9R30[x] ; - lbe = _9R30[y]; - correctL = true; - } else if ((hue <= (_9R30[x] + _7R30[x]) / 2.0) && (hue > (_7R30[x] - 0.035)) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _7R30[y] - _7R30[x] ; - lbe = _7R30[y] ; - correctL = true; - } - } else if (lum < 45.0) { - if ((hue <= (_10YR40[x] + 0.035)) && (hue > (_10YR40[x] + _85YR40[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _10YR40[y] - _10YR40[x] ; - lbe = _10YR40[y]; - correctL = true; - } else if ((hue <= (_10YR40[x] + _85YR40[x]) / 2.0) && (hue > (_85YR40[x] + _7YR40[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _85YR40[y] - _85YR40[x] ; - lbe = _85YR40[y]; - correctL = true; - } else if ((hue <= (_85YR40[x] + _7YR40[x]) / 2.0) && (hue > (_7YR40[x] + _55YR40[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _7YR40[y] - _7YR40[x] ; - lbe = _7YR40[y]; - correctL = true; - } else if ((hue <= (_7YR40[x] + _55YR40[x]) / 2.0) && (hue > (_55YR40[x] + _4YR40[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _55YR40[y] - _55YR40[x] ; - lbe = _55YR40[y]; - correctL = true; - } else if ((hue <= (_55YR40[x] + _4YR40[x]) / 2.0) && (hue > (_4YR40[x] + _25YR40[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _4YR40[y] - _4YR40[x] ; - lbe = _4YR40[y]; - correctL = true; - } else if ((hue <= (_4YR40[x] + _25YR40[x]) / 2.0) && (hue > (_25YR40[x] + _10R40[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _25YR40[y] - _25YR40[x] ; - lbe = _25YR40[y] ; - correctL = true; - } else if ((hue <= (_25YR40[x] + _10R40[x]) / 2.0) && (hue > (_10R40[x] + _9R40[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _10R40[y] - _10R40[x] ; - lbe = _10R40[y]; - correctL = true; - } else if ((hue <= (_10R40[x] + _9R40[x]) / 2.0) && (hue > (_9R40[x] + _7R40[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _9R40[y] - _9R40[x] ; - lbe = _9R40[y]; - correctL = true; - } else if ((hue <= (_9R40[x] + _7R40[x]) / 2.0) && (hue > (_7R40[x] - 0.035)) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _7R40[y] - _7R40[x] ; - lbe = _7R40[y]; - correctL = true; - } - } else if (lum < 55.0) { - if ((hue <= (_10YR50[x] + 0.035)) && (hue > (_10YR50[x] + _85YR50[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _10YR50[y] - _10YR50[x] ; - lbe = _10YR50[y]; - correctL = true; - } else if ((hue <= (_10YR50[x] + _85YR50[x]) / 2.0) && (hue > (_85YR50[x] + _7YR50[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _85YR50[y] - _85YR50[x] ; - lbe = _85YR50[y]; - correctL = true; - } else if ((hue <= (_85YR50[x] + _7YR50[x]) / 2.0) && (hue > (_7YR50[x] + _55YR50[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _7YR50[y] - _7YR50[x] ; - lbe = _7YR50[y]; - correctL = true; - } else if ((hue <= (_7YR50[x] + _55YR50[x]) / 2.0) && (hue > (_55YR50[x] + _4YR50[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _55YR50[y] - _55YR50[x] ; - lbe = _55YR50[y]; - correctL = true; - } else if ((hue <= (_55YR50[x] + _4YR50[x]) / 2.0) && (hue > (_4YR50[x] + _25YR50[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _4YR50[y] - _4YR50[x] ; - lbe = _4YR50[y]; - correctL = true; - } else if ((hue <= (_4YR50[x] + _25YR50[x]) / 2.0) && (hue > (_25YR50[x] + _10R50[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _25YR50[y] - _25YR50[x] ; - lbe = _25YR50[y]; - correctL = true; - } else if ((hue <= (_25YR50[x] + _10R50[x]) / 2.0) && (hue > (_10R50[x] + _9R50[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _10R50[y] - _10R50[x] ; - lbe = _10R50[y]; - correctL = true; - } else if ((hue <= (_10R50[x] + _9R50[x]) / 2.0) && (hue > (_9R50[x] + _7R50[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _9R50[y] - _9R50[x] ; - lbe = _9R50[y]; - correctL = true; - } else if ((hue <= (_9R50[x] + _7R50[x]) / 2.0) && (hue > (_7R50[x] - 0.035)) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _7R50[y] - _7R50[x] ; - lbe = _7R50[y]; - correctL = true; - } - } else if (lum < 65.0) { - if ((hue <= (_10YR60[x] + 0.035)) && (hue > (_10YR60[x] + _85YR60[x]) / 2.0)) { - ; - correction = _10YR60[y] - _10YR60[x] ; - lbe = _10YR60[y]; - correctL = true; - } else if ((hue <= (_10YR60[x] + _85YR60[x]) / 2.0) && (hue > (_85YR60[x] + _7YR60[x]) / 2.0)) { - ; - correction = _85YR60[y] - _85YR60[x] ; - lbe = _85YR60[y]; - correctL = true; - } else if ((hue <= (_85YR60[x] + _7YR60[x]) / 2.0) && (hue > (_7YR60[x] + _55YR60[x]) / 2.0)) { - correction = _7YR60[y] - _7YR60[x] ; - lbe = _7YR60[y]; - correctL = true; - } else if ((hue <= (_7YR60[x] + _55YR60[x]) / 2.0) && (hue > (_55YR60[x] + _4YR60[x]) / 2.0)) { - correction = _55YR60[y] - _55YR60[x] ; - lbe = _55YR60[y]; - correctL = true; - } else if ((hue <= (_55YR60[x] + _4YR60[x]) / 2.0) && (hue > (_4YR60[x] + _25YR60[x]) / 2.0)) { - correction = _4YR60[y] - _4YR60[x] ; - lbe = _4YR60[y]; - correctL = true; - } else if ((hue <= (_4YR60[x] + _25YR60[x]) / 2.0) && (hue > (_25YR60[x] + _10R60[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _25YR60[y] - _25YR60[x] ; - lbe = _25YR60[y]; - correctL = true; - } else if ((hue <= (_25YR60[x] + _10R60[x]) / 2.0) && (hue > (_10R60[x] + _9R60[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _10R60[y] - _10R60[x] ; - lbe = _10R60[y]; - correctL = true; - } else if ((hue <= (_10R60[x] + _9R60[x]) / 2.0) && (hue > (_9R60[x] + _7R60[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _9R60[y] - _9R60[x] ; - lbe = _9R60[y]; - correctL = true; - } else if ((hue <= (_9R60[x] + _7R60[x]) / 2.0) && (hue > (_7R60[x] - 0.035)) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _7R60[y] - _7R60[x] ; - lbe = _7R60[y]; - correctL = true; - } - } else if (lum < 75.0) { - if ((hue <= (_10YR70[x] + 0.035)) && (hue > (_10YR70[x] + _85YR70[x]) / 2.0)) { - correction = _10YR70[y] - _10YR70[x] ; - lbe = _10YR70[y]; - correctL = true; - } else if ((hue <= (_10YR70[x] + _85YR70[x]) / 2.0) && (hue > (_85YR70[x] + _7YR70[x]) / 2.0)) { - correction = _85YR70[y] - _85YR70[x] ; - lbe = _85YR70[y]; - correctL = true; - } - - if ((hue <= (_85YR70[x] + _7YR70[x]) / 2.0) && (hue > (_7YR70[x] + _55YR70[x]) / 2.0)) { - correction = _7YR70[y] - _7YR70[x] ; - lbe = _7YR70[y]; - correctL = true; - } else if ((hue <= (_7YR70[x] + _55YR70[x]) / 2.0) && (hue > (_55YR70[x] + _4YR70[x]) / 2.0)) { - correction = _55YR70[y] - _55YR70[x] ; - lbe = _55YR70[y]; - correctL = true; - } else if ((hue <= (_55YR70[x] + _4YR70[x]) / 2.0) && (hue > (_4YR70[x] + _25YR70[x]) / 2.0)) { - correction = _4YR70[y] - _4YR70[x] ; - lbe = _4YR70[y]; - correctL = true; - } else if ((hue <= (_4YR70[x] + _25YR70[x]) / 2.0) && (hue > (_25YR70[x] + _10R70[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _25YR70[y] - _25YR70[x] ; - lbe = _25YR70[y]; - correctL = true; - } else if ((hue <= (_25YR70[x] + _10R70[x]) / 2.0) && (hue > (_10R70[x] + _9R70[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _10R70[y] - _10R70[x] ; - lbe = _10R70[y]; - correctL = true; - } else if ((hue <= (_10R70[x] + _9R70[x]) / 2.0) && (hue > (_9R70[x] + _7R70[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _9R70[y] - _9R70[x] ; - lbe = _9R70[y] ; - correctL = true; - } else if ((hue <= (_9R70[x] + _7R70[x]) / 2.0) && (hue > (_7R70[x] - 0.035)) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _7R70[y] - _7R70[x] ; - lbe = _7R70[y]; - correctL = true; - } - } else if (lum < 85.0) { - if ((hue <= (_10YR80[x] + 0.035)) && (hue > (_10YR80[x] + _85YR80[x]) / 2.0)) { - correction = _10YR80[y] - _10YR80[x] ; - lbe = _10YR80[y]; - correctL = true; - } else if ((hue <= (_10YR80[x] + _85YR80[x]) / 2.0) && (hue > (_85YR80[x] + _7YR80[x]) / 2.0)) { - correction = _85YR80[y] - _85YR80[x] ; - lbe = _85YR80[y]; - } else if ((hue <= (_85YR80[x] + _7YR80[x]) / 2.0) && (hue > (_7YR80[x] + _55YR80[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _7YR80[y] - _7YR80[x] ; - lbe = _7YR80[y]; - correctL = true; - } else if ((hue <= (_7YR80[x] + _55YR80[x]) / 2.0) && (hue > (_55YR80[x] + _4YR80[x]) / 2.0) && x < 45) { - correction = _55YR80[y] - _55YR80[x] ; - lbe = _55YR80[y]; - correctL = true; - } else if ((hue <= (_55YR80[x] + _4YR80[x]) / 2.0) && (hue > (_4YR80[x] - 0.035) && x < 45)) { - if (y > 49) { - y = 49; - } - - correction = _4YR80[y] - _4YR80[x] ; - lbe = _4YR80[y] ; - correctL = true; - } - } else if (lum < 95.0) { - if ((hue <= (_10YR90[x] + 0.035)) && (hue > (_10YR90[x] - 0.035) && x < 85)) { - if (y > 89) { - y = 89; - } - - correction = _10YR90[y] - _10YR90[x] ; - lbe = _10YR90[y]; - correctL = true; - } else if (hue <= (_85YR90[x] + 0.035) && hue > (_85YR90[x] - 0.035) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _85YR90[y] - _85YR90[x] ; - lbe = _85YR90[y]; - correctL = true; - } else if ((hue <= (_55YR90[x] + 0.035) && (hue > (_55YR90[x] - 0.035) && x < 45))) { - if (y > 49) { - y = 49; - } - - correction = _55YR90[y] - _55YR90[x] ; - lbe = _55YR90[y]; - correctL = true; - } - } - } - } - //end red yellow - - //Green yellow correction - else if (zone == 3) { - if (lum >= 25.0) { - if (lum < 35.0) { - if ((hue <= (_7G30[x] + 0.035)) && (hue > (_7G30[x] + _5G30[x]) / 2.0)) { - correction = _7G30[y] - _7G30[x] ; - lbe = _7G30[y]; - correctL = true; - } else if ((hue <= (_7G30[x] + _5G30[x]) / 2.0) && (hue > (_5G30[x] + _25G30[x]) / 2.0)) { - correction = _5G30[y] - _5G30[x] ; - lbe = _5G30[y]; - correctL = true; - } else if ((hue <= (_25G30[x] + _5G30[x]) / 2.0) && (hue > (_25G30[x] + _1G30[x]) / 2.0)) { - correction = _25G30[y] - _25G30[x] ; - lbe = _25G30[y]; - correctL = true; - } else if ((hue <= (_1G30[x] + _25G30[x]) / 2.0) && (hue > (_1G30[x] + _10GY30[x]) / 2.0)) { - correction = _1G30[y] - _1G30[x] ; - lbe = _1G30[y]; - correctL = true; - } else if ((hue <= (_1G30[x] + _10GY30[x]) / 2.0) && (hue > (_10GY30[x] + _75GY30[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _10GY30[y] - _10GY30[x] ; - lbe = _10GY30[y]; - correctL = true; - } else if ((hue <= (_10GY30[x] + _75GY30[x]) / 2.0) && (hue > (_75GY30[x] + _5GY30[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _75GY30[y] - _75GY30[x] ; - lbe = _75GY30[y]; - correctL = true; - } else if ((hue <= (_5GY30[x] + _75GY30[x]) / 2.0) && (hue > (_5GY30[x] - 0.035)) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _5GY30[y] - _5GY30[x] ; - lbe = _5GY30[y] ; - correctL = true; - } - } else if (lum < 45.0) { - if ((hue <= (_7G40[x] + 0.035)) && (hue > (_7G40[x] + _5G40[x]) / 2.0)) { - correction = _7G40[y] - _7G40[x] ; - lbe = _7G40[y]; - correctL = true; - } else if ((hue <= (_7G40[x] + _5G40[x]) / 2.0) && (hue > (_5G40[x] + _25G40[x]) / 2.0)) { - correction = _5G40[y] - _5G40[x] ; - lbe = _5G40[y]; - correctL = true; - } else if ((hue <= (_25G40[x] + _5G40[x]) / 2.0) && (hue > (_25G40[x] + _1G40[x]) / 2.0)) { - correction = _25G40[y] - _25G40[x] ; - lbe = _25G40[y]; - correctL = true; - } else if ((hue <= (_1G40[x] + _25G40[x]) / 2.0) && (hue > (_1G40[x] + _10GY40[x]) / 2.0)) { - correction = _1G40[y] - _1G40[x] ; - lbe = _1G40[y]; - correctL = true; - } else if ((hue <= (_1G40[x] + _10GY40[x]) / 2.0) && (hue > (_10GY40[x] + _75GY40[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _10GY40[y] - _10GY40[x] ; - lbe = _10GY40[y]; - correctL = true; - } else if ((hue <= (_10GY40[x] + _75GY40[x]) / 2.0) && (hue > (_75GY40[x] + _5GY40[x]) / 2.0) && x < 85) { - if (y > 89) { - y = 89; - } - - correction = _75GY40[y] - _75GY40[x] ; - lbe = _75GY40[y]; - correctL = true; - } else if ((hue <= (_5GY40[x] + _75GY40[x]) / 2.0) && (hue > (_5GY40[x] - 0.035)) && x < 85) { - if (y > 89) { - y = 89; // - } - - correction = _5GY40[y] - _5GY40[x] ; - lbe = _5GY40[y]; - correctL = true; - } - } else if (lum < 55.0) { - if ((hue <= (_7G50[x] + 0.035)) && (hue > (_7G50[x] + _5G50[x]) / 2.0)) { - correction = _7G50[y] - _7G50[x] ; - lbe = _7G50[y]; - correctL = true; - } else if ((hue <= (_7G50[x] + _5G50[x]) / 2.0) && (hue > (_5G50[x] + _25G50[x]) / 2.0)) { - correction = _5G50[y] - _5G50[x] ; - lbe = _5G50[y]; - correctL = true; - } else if ((hue <= (_25G50[x] + _5G50[x]) / 2.0) && (hue > (_25G50[x] + _1G50[x]) / 2.0)) { - correction = _25G50[y] - _25G50[x] ; - lbe = _25G50[y]; - correctL = true; - } else if ((hue <= (_1G50[x] + _25G50[x]) / 2.0) && (hue > (_1G50[x] + _10GY50[x]) / 2.0)) { - correction = _1G50[y] - _1G50[x] ; - lbe = _1G50[y]; - correctL = true; - } else if ((hue <= (_1G50[x] + _10GY50[x]) / 2.0) && (hue > (_10GY50[x] + _75GY50[x]) / 2.0)) { - correction = _10GY50[y] - _10GY50[x] ; - lbe = _10GY50[y]; - correctL = true; - } else if ((hue <= (_10GY50[x] + _75GY50[x]) / 2.0) && (hue > (_75GY50[x] + _5GY50[x]) / 2.0)) { - correction = _75GY50[y] - _75GY50[x] ; - lbe = _75GY50[y]; - correctL = true; - } else if ((hue <= (_5GY50[x] + _75GY50[x]) / 2.0) && (hue > (_5GY50[x] - 0.035))) { - correction = _5GY50[y] - _5GY50[x] ; - lbe = _5GY50[y]; - correctL = true; - } - } else if (lum < 65.0) { - if ((hue <= (_7G60[x] + 0.035)) && (hue > (_7G60[x] + _5G60[x]) / 2.0)) { - correction = _7G60[y] - _7G60[x] ; - lbe = _7G60[y]; - correctL = true; - } else if ((hue <= (_7G60[x] + _5G60[x]) / 2.0) && (hue > (_5G60[x] + _25G60[x]) / 2.0)) { - correction = _5G60[y] - _5G60[x] ; - lbe = _5G60[y]; - correctL = true; - } else if ((hue <= (_25G60[x] + _5G60[x]) / 2.0) && (hue > (_25G60[x] + _1G60[x]) / 2.0)) { - correction = _25G60[y] - _25G60[x] ; - lbe = _25G60[y]; - correctL = true; - } else if ((hue <= (_1G60[x] + _25G60[x]) / 2.0) && (hue > (_1G60[x] + _10GY60[x]) / 2.0)) { - correction = _1G60[y] - _1G60[x] ; - lbe = _1G60[y]; - correctL = true; - } else if ((hue <= (_1G60[x] + _10GY60[x]) / 2.0) && (hue > (_10GY60[x] + _75GY60[x]) / 2.0)) { - correction = _10GY60[y] - _10GY60[x] ; - lbe = _10GY60[y]; - correctL = true; - } else if ((hue <= (_10GY60[x] + _75GY60[x]) / 2.0) && (hue > (_75GY60[x] + _5GY60[x]) / 2.0)) { - correction = _75GY60[y] - _75GY60[x] ; - lbe = _75GY60[y] ; - correctL = true; - } else if ((hue <= (_5GY60[x] + _75GY60[x]) / 2.0) && (hue > (_5GY60[x] - 0.035))) { - correction = _5GY60[y] - _5GY60[x] ; - lbe = _5GY60[y]; - correctL = true; - } - } else if (lum < 75.0) { - if ((hue <= (_7G70[x] + 0.035)) && (hue > (_7G70[x] + _5G70[x]) / 2.0)) { - correction = _7G70[y] - _7G70[x] ; - lbe = _7G70[y]; - correctL = true; - } else if ((hue <= (_7G70[x] + _5G70[x]) / 2.0) && (hue > (_5G70[x] + _25G70[x]) / 2.0)) { - correction = _5G70[y] - _5G70[x] ; - lbe = _5G70[y]; - correctL = true; - } else if ((hue <= (_25G70[x] + _5G70[x]) / 2.0) && (hue > (_25G70[x] + _1G70[x]) / 2.0)) { - correction = _25G70[y] - _25G70[x] ; - lbe = _25G70[y]; - correctL = true; - } else if ((hue <= (_1G70[x] + _25G70[x]) / 2.0) && (hue > (_1G70[x] + _10GY70[x]) / 2.0)) { - correction = _1G70[y] - _1G70[x] ; - lbe = _1G70[y] ; - correctL = true; - } else if ((hue <= (_1G70[x] + _10GY70[x]) / 2.0) && (hue > (_10GY70[x] + _75GY70[x]) / 2.0)) { - correction = _10GY70[y] - _10GY70[x] ; - lbe = _10GY70[y]; - correctL = true; - } else if ((hue <= (_10GY70[x] + _75GY70[x]) / 2.0) && (hue > (_75GY70[x] + _5GY70[x]) / 2.0)) { - correction = _75GY70[y] - _75GY70[x] ; - lbe = _75GY70[y]; - correctL = true; - } else if ((hue <= (_5GY70[x] + _75GY70[x]) / 2.0) && (hue > (_5GY70[x] - 0.035))) { - correction = _5GY70[y] - _5GY70[x] ; - lbe = _5GY70[y]; - correctL = true; - } - } else if (lum < 85.0) { - if ((hue <= (_7G80[x] + 0.035)) && (hue > (_7G80[x] + _5G80[x]) / 2.0)) { - correction = _7G80[y] - _7G80[x] ; - lbe = _7G80[y]; - correctL = true; - } else if ((hue <= (_7G80[x] + _5G80[x]) / 2.0) && (hue > (_5G80[x] + _25G80[x]) / 2.0)) { - correction = _5G80[y] - _5G80[x] ; - lbe = _5G80[y]; - correctL = true; - } else if ((hue <= (_25G80[x] + _5G80[x]) / 2.0) && (hue > (_25G80[x] + _1G80[x]) / 2.0)) { - correction = _25G80[y] - _25G80[x] ; - lbe = _25G80[y]; - correctL = true; - } else if ((hue <= (_1G80[x] + _25G80[x]) / 2.0) && (hue > (_1G80[x] + _10GY80[x]) / 2.0)) { - correction = _1G80[y] - _1G80[x] ; - lbe = _1G80[y]; - correctL = true; - } else if ((hue <= (_1G80[x] + _10GY80[x]) / 2.0) && (hue > (_10GY80[x] + _75GY80[x]) / 2.0)) { - correction = _10GY80[y] - _10GY80[x] ; - lbe = _10GY80[y]; - correctL = true; - } else if ((hue <= (_10GY80[x] + _75GY80[x]) / 2.0) && (hue > (_75GY80[x] + _5GY80[x]) / 2.0)) { - correction = _75GY80[y] - _75GY80[x] ; - lbe = _75GY80[y]; - correctL = true; - } else if ((hue <= (_5GY80[x] + _75GY80[x]) / 2.0) && (hue > (_5GY80[x] - 0.035))) { - correction = _5GY80[y] - _5GY80[x] ; - lbe = _5GY80[y]; - correctL = true; - } - } - } - } - //end green yellow - - //Red purple correction : only for L < 30 - else if (zone == 4) { - if (lum > 5.0) { - if (lum < 15.0) { - if ((hue <= (_5R10[x] + 0.035)) && (hue > (_5R10[x] - 0.043)) && x < 45) { - if (y > 44) { - y = 44; - } - - correction = _5R10[y] - _5R10[x] ; - lbe = _5R10[y]; - correctL = true; - } else if ((hue <= (_25R10[x] + 0.043)) && (hue > (_25R10[x] + _10RP10[x]) / 2.0) && x < 45) { - if (y > 44) { - y = 44; - } - - correction = _25R10[y] - _25R10[x] ; - lbe = _25R10[y]; - correctL = true; - } else if ((hue <= (_25R10[x] + _10RP10[x]) / 2.0) && (hue > (_10RP10[x] - 0.035)) && x < 45) { - if (y > 44) { - y = 44; - } - - correction = _10RP10[y] - _10RP10[x] ; - lbe = _10RP10[y]; - correctL = true; - } - } else if (lum < 25.0) { - if ((hue <= (_5R20[x] + 0.035)) && (hue > (_5R20[x] + _25R20[x]) / 2.0) && x < 70) { - if (y > 70) { - y = 70; - } - - correction = _5R20[y] - _5R20[x] ; - lbe = _5R20[y]; - correctL = true; - } else if ((hue <= (_5R20[x] + _25R20[x]) / 2.0) && (hue > (_10RP20[x] + _25R20[x]) / 2.0) && x < 70) { - if (y > 70) { - y = 70; - } - - correction = _25R20[y] - _25R20[x] ; - lbe = _25R20[y]; - correctL = true; - } else if ((hue <= (_10RP20[x] + _25R20[x]) / 2.0) && (hue > (_10RP20[x] - 0.035)) && x < 70) { - if (y > 70) { - y = 70; - } - - correction = _10RP20[y] - _10RP20[x] ; - lbe = _10RP20[y]; - correctL = true; - } - } else if (lum < 35.0) { - if ((hue <= (_5R30[x] + 0.035)) && (hue > (_5R30[x] + _25R30[x]) / 2.0) && x < 85) { - if (y > 85) { - y = 85; - } - - correction = _5R30[y] - _5R30[x] ; - lbe = _5R30[y]; - correctL = true; - } else if ((hue <= (_5R30[x] + _25R30[x]) / 2.0) && (hue > (_10RP30[x] + _25R30[x]) / 2.0) && x < 85) { - if (y > 85) { - y = 85; - } - - correction = _25R30[y] - _25R30[x] ; - lbe = _25R30[y]; - correctL = true; - } else if ((hue <= (_10RP30[x] + _25R30[x]) / 2.0) && (hue > (_10RP30[x] - 0.035)) && x < 85) { - if (y > 85) { - y = 85; - } - - correction = _10RP30[y] - _10RP30[x] ; - lbe = _10RP30[y]; - correctL = true; - } - } - } - } - - //end red purple -} - - /* * SkinSat * Copyright (c)2011 Jacques Desmis @@ -4424,7 +3047,7 @@ void Color::MunsellLch(float lum, float hue, float chrom, float memChprov, float * pay attention to white balance, and do not change hue and saturation, upstream of the modification * */ -void Color::SkinSat(float lum, float hue, float chrom, float &satreduc) +void Color::SkinSat (float lum, float hue, float chrom, float &satreduc) { // to be adapted...by tests @@ -4436,10 +3059,10 @@ void Color::SkinSat(float lum, float hue, float chrom, float &satreduc) constexpr float H9 = 0.05f, H8 = 0.25f, H7 = 0.1f, H4 = 0.02f, H3 = 0.02f, H2 = 0.1f, H1 = 0.1f, H10 = -0.2f, H11 = -0.2f; //H10 and H11 are curious...H11=-0.8 ?? if (lum >= 85.f) { - if ((hue > (0.78f - H9) && hue < (1.18f + H9)) && (chrom > 8.f && chrom < (14.f + C9))) { + if((hue > (0.78f - H9) && hue < (1.18f + H9)) && (chrom > 8.f && chrom < (14.f + C9))) { satreduc = reduction; } else if (lum >= 92.f) { - if ((hue > 0.8f && hue < 1.65f) && (chrom > 7.f && chrom < (15.f))) { + if((hue > 0.8f && hue < 1.65f) && (chrom > 7.f && chrom < (15.f))) { satreduc = extendedreduction; } else if ((hue > -0.1f && hue < 1.65f) && (chrom > 7.f && chrom < (18.f))) { satreduc = extendedreduction2; @@ -4450,51 +3073,51 @@ void Color::SkinSat(float lum, float hue, float chrom, float &satreduc) satreduc = extendedreduction2; } } else if (lum >= 70.f) { - if ((hue > 0.4f && hue < (1.04f + H8)) && (chrom > 8.f && chrom < (35.f + C8))) { + if((hue > 0.4f && hue < (1.04f + H8)) && (chrom > 8.f && chrom < (35.f + C8))) { satreduc = reduction; - } else if ((hue > (0.02f + H11) && hue < 1.5f) && (chrom > 7.0f && chrom < (48.f + C9))) { + } else if ((hue > (0.02f + H11) && hue < 1.5f) && (chrom > 7.0f && chrom < (48.f + C9) )) { satreduc = extendedreduction; - } else if ((hue > (0.02f + H11) && hue < 1.65f) && (chrom > 7.f && chrom < (55.f + C9))) { + } else if ((hue > (0.02f + H11) && hue < 1.65f) && (chrom > 7.f && chrom < (55.f + C9) )) { satreduc = extendedreduction2; } } else if (lum >= 52.f) { - if ((hue > 0.3f && hue < (1.27f + H7)) && (chrom > 11.f && chrom < (35.f + C7))) { + if((hue > 0.3f && hue < (1.27f + H7)) && (chrom > 11.f && chrom < (35.f + C7))) { satreduc = reduction; - } else if ((hue > (0.02f + H11) && hue < 1.5f) && (chrom > 7.0f && chrom < (48.f + C9))) { + } else if ((hue > (0.02f + H11) && hue < 1.5f) && (chrom > 7.0f && chrom < (48.f + C9) )) { satreduc = extendedreduction; - } else if ((hue > (0.02f + H11) && hue < 1.65f) && (chrom > 7.f && chrom < (55.f + C9))) { + } else if ((hue > (0.02f + H11) && hue < 1.65f) && (chrom > 7.f && chrom < (55.f + C9) )) { satreduc = extendedreduction2; } } else if (lum >= 35.f) { - if ((hue > 0.3f && hue < (1.25f + H4)) && (chrom > 13.f && chrom < (37.f + C4))) { + if((hue > 0.3f && hue < (1.25f + H4)) && (chrom > 13.f && chrom < (37.f + C4))) { satreduc = reduction; - } else if ((hue > (0.02f + H11) && hue < 1.5f) && (chrom > 7.0f && chrom < (48.f + C9))) { + } else if ((hue > (0.02f + H11) && hue < 1.5f) && (chrom > 7.0f && chrom < (48.f + C9) )) { satreduc = extendedreduction; - } else if ((hue > (0.02f + H11) && hue < 1.65f) && (chrom > 7.f && chrom < (55.f + C9))) { + } else if ((hue > (0.02f + H11) && hue < 1.65f) && (chrom > 7.f && chrom < (55.f + C9) )) { satreduc = extendedreduction2; } } else if (lum >= 20.f) { - if ((hue > 0.3f && hue < (1.2f + H3)) && (chrom > 7.f && chrom < (35.f + C3))) { + if((hue > 0.3f && hue < (1.2f + H3)) && (chrom > 7.f && chrom < (35.f + C3) )) { satreduc = reduction; - } else if ((hue > (0.02f + H11) && hue < 1.5f) && (chrom > 7.0f && chrom < (48.f + C9))) { + } else if ((hue > (0.02f + H11) && hue < 1.5f) && (chrom > 7.0f && chrom < (48.f + C9) )) { satreduc = extendedreduction; - } else if ((hue > (0.02f + H11) && hue < 1.65f) && (chrom > 7.f && chrom < (55.f + C9))) { + } else if ((hue > (0.02f + H11) && hue < 1.65f) && (chrom > 7.f && chrom < (55.f + C9) )) { satreduc = extendedreduction2; } } else if (lum > 10.f) { - if ((hue > (0.f + H10) && hue < (0.95f + H2)) && (chrom > 8.f && chrom < (23.f + C2))) { + if((hue > (0.f + H10) && hue < (0.95f + H2)) && (chrom > 8.f && chrom < (23.f + C2))) { satreduc = reduction; - } else if ((hue > (0.02f + H11) && hue < 1.f) && (chrom > 7.f && chrom < (35.f + C1))) { + } else if ((hue > (0.02f + H11) && hue < 1.f) && (chrom > 7.f && chrom < (35.f + C1) )) { satreduc = extendedreduction; - } else if ((hue > (0.02f + H11) && hue < 1.6f) && (chrom > 7.f && chrom < (45.f + C1))) { + } else if ((hue > (0.02f + H11) && hue < 1.6f) && (chrom > 7.f && chrom < (45.f + C1) )) { satreduc = extendedreduction2; } } else { - if ((hue > (0.02f + H10) && hue < (0.9f + H1)) && (chrom > 8.f && chrom < (23.f + C1))) { + if((hue > (0.02f + H10) && hue < (0.9f + H1)) && (chrom > 8.f && chrom < (23.f + C1))) { satreduc = reduction; // no data : extrapolate - } else if ((hue > (0.02f + H11) && hue < 1.f) && (chrom > 7.f && chrom < (35.f + C1))) { + } else if ((hue > (0.02f + H11) && hue < 1.f) && (chrom > 7.f && chrom < (35.f + C1) )) { satreduc = extendedreduction; - } else if ((hue > (0.02f + H11) && hue < 1.6f) && (chrom > 7.f && chrom < (45.f + C1))) { + } else if ((hue > (0.02f + H11) && hue < 1.6f) && (chrom > 7.f && chrom < (45.f + C1) )) { satreduc = extendedreduction2; } @@ -4515,7 +3138,7 @@ void Color::SkinSat(float lum, float hue, float chrom, float &satreduc) * errors due to a different illuminant "Daylight" than "C" are low, about 10%. For example, a theoretical correction of 0.1 radian will be made with a real correction of 0.09 or 0.11 depending on the color illuminant D50 * errors due to the use of a very different illuminant "C", for example illuminant "A" (tungsten) are higher, about 20%. Theoretical correction of 0.52 radians will be made with a real correction of 0.42 */ -void Color::initMunsell() +void Color::initMunsell () { #ifdef _DEBUG MyTime t1e, t2e; @@ -5181,7 +3804,7 @@ void Color::initMunsell() //printf("60 %1.2f %1.2f %1.2f\n",_6PB40[44],_6PB40[84],_6PB40[139]); - _6PB50(maxInd2); //limits -1.3 -1.11 + _6PB50(maxInd2);//limits -1.3 -1.11 _6PB50.clear(); for (int i = 0; i < maxInd2; i++) { @@ -5194,7 +3817,7 @@ void Color::initMunsell() //printf("60 %1.2f %1.2f \n",_6PB50[44],_6PB50[89]); - _6PB60(maxInd2); //limits -1.3 -1.11 + _6PB60(maxInd2);//limits -1.3 -1.11 _6PB60.clear(); for (int i = 0; i < maxInd2; i++) { @@ -5229,7 +3852,7 @@ void Color::initMunsell() //_75PB : notation Munsell for maximum deviation blue purple - _75PB10(maxInd); //limits hue -1.23 -0.71 _75PBx x=Luminance eg_75PB10 for L >5 and L<=15 + _75PB10(maxInd);//limits hue -1.23 -0.71 _75PBx x=Luminance eg_75PB10 for L >5 and L<=15 _75PB10.clear(); for (int i = 0; i < maxInd; i++) { //i = chromaticity 0==>140 @@ -5244,7 +3867,7 @@ void Color::initMunsell() //printf("75 %1.2f %1.2f %1.2f\n",_75PB10[44],_75PB10[84],_75PB10[139]); - _75PB20(maxInd); //limits -1.24 -0.79 for L>15 <=25 + _75PB20(maxInd);//limits -1.24 -0.79 for L>15 <=25 _75PB20.clear(); for (int i = 0; i < maxInd; i++) { @@ -5259,7 +3882,7 @@ void Color::initMunsell() //printf("75 %1.2f %1.2f %1.2f\n",_75PB20[44],_75PB20[84],_75PB20[139]); - _75PB30(maxInd); //limits -1.25 -0.85 + _75PB30(maxInd);//limits -1.25 -0.85 _75PB30.clear(); for (int i = 0; i < maxInd; i++) { @@ -5274,7 +3897,7 @@ void Color::initMunsell() //printf("75 %1.2f %1.2f %1.2f\n",_75PB30[44],_75PB30[84],_75PB30[139]); - _75PB40(maxInd); //limits -1.27 -0.92 + _75PB40(maxInd);//limits -1.27 -0.92 _75PB40.clear(); for (int i = 0; i < maxInd; i++) { @@ -5289,7 +3912,7 @@ void Color::initMunsell() //printf("75 %1.2f %1.2f %1.2f\n",_75PB40[44],_75PB40[84],_75PB40[139]); - _75PB50(maxInd2); //limits -1.3 -1.11 + _75PB50(maxInd2);//limits -1.3 -1.11 _75PB50.clear(); for (int i = 0; i < maxInd2; i++) { diff --git a/rtengine/color.h b/rtengine/color.h index ad51dd49b..1e83ad6f5 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -23,17 +23,12 @@ #include "rt_math.h" #include "LUT.h" -#include "iccmatrices.h" #include "lcms2.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 @@ -98,7 +93,7 @@ private: static LUTf _5GY30, _5GY40, _5GY50, _5GY60, _5GY70, _5GY80; // Separated from init() to keep the code clear - static void initMunsell(); + static void initMunsell (); static double hue2rgb(double p, double q, double t); static float hue2rgbfloat(float p, float q, float t); #ifdef __SSE2__ @@ -106,7 +101,6 @@ private: #endif static float computeXYZ2Lab(float f); - static float computeXYZ2LabY(float f); public: @@ -138,7 +132,7 @@ public: constexpr static double sRGBGammaCurve = 2.4; 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 kappaInv = 27.0 / 24389.0; constexpr static double epsilonExpInv3 = 6.0 / 29.0; @@ -150,9 +144,10 @@ public: constexpr static float D50x = 0.9642f; //0.96422; constexpr static float D50z = 0.8249f; //0.82521; - constexpr static double u0 = 4.0 * D50x / (D50x + 15 + 3 * D50z); - constexpr static double v0 = 9.0 / (D50x + 15 + 3 * D50z); + constexpr static double u0 = 4.0 * static_cast(D50x) / (static_cast(D50x) + 15 + 3 * static_cast(D50z)); + constexpr static double v0 = 9.0 / (static_cast(D50x) + 15 + 3 * static_cast(D50z)); constexpr static double epskap = 8.0; + constexpr static float epskapf = epskap; constexpr static float c1By116 = 1.0 / 116.0; constexpr static float c16By116 = 16.0 / 116.0; @@ -189,9 +184,19 @@ public: static LUTuc gammatabThumb; // for thumbnails - static void init(); - static void cleanup(); + static void init (); + static void cleanup (); + static inline float computeXYZ2LabY(float f) + { + if (f < 0.f) { + return 327.68f * (kappa * f / MAXVALF); + } else if (f > 65535.f) { + return 327.68f * (116.f * xcbrtf(f / MAXVALF) - 16.f); + } else { + return cachefy[f]; + } + } /** * @brief Extract luminance "sRGB" from red/green/blue values @@ -215,7 +220,7 @@ public: 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(r) * workingspace[1][0] + static_cast(g) * workingspace[1][1] + static_cast(b) * workingspace[1][2]; } #ifdef __SSE2__ @@ -239,7 +244,7 @@ public: * @param workingSpace true: compute the Lab value using the Working color space ; false: use the Output color space */ // do not use this function in a loop. It really eats processing time caused by Glib::ustring comparisons - static void rgb2lab01(const Glib::ustring &profile, const Glib::ustring &profileW, float r, float g, float b, float &LAB_l, float &LAB_a, float &LAB_b, bool workingSpace); + static void rgb2lab01 (const Glib::ustring &profile, const Glib::ustring &profileW, float r, float g, float b, float &LAB_l, float &LAB_a, float &LAB_b, bool workingSpace); /** * @brief Convert red/green/blue to hue/saturation/luminance @@ -250,7 +255,7 @@ public: * @param s saturation channel [0 ; 1] (return value) * @param l luminance channel [0; 1] (return value) */ - static void rgb2hsl(float r, float g, float b, float &h, float &s, float &l); + static void rgb2hsl (float r, float g, float b, float &h, float &s, float &l); static inline void rgb2slfloat(float r, float g, float b, float &s, float &l) { @@ -303,14 +308,14 @@ public: h /= (6.f * C); - if (h < 0.f) { + if ( h < 0.f ) { h += 1.f; } } } #ifdef __SSE2__ - static void rgb2hsl(vfloat r, vfloat g, vfloat b, vfloat &h, vfloat &s, vfloat &l); + static void rgb2hsl (vfloat r, vfloat g, vfloat b, vfloat &h, vfloat &s, vfloat &l); #endif /** @@ -322,9 +327,9 @@ public: * @param g green channel [0 ; 65535] (return value) * @param b blue channel [0 ; 65535] (return value) */ - static void hsl2rgb(float h, float s, float l, float &r, float &g, float &b); + static void hsl2rgb (float h, float s, float l, float &r, float &g, float &b); - static inline void hsl2rgbfloat(float h, float s, float l, float &r, float &g, float &b) + static inline void hsl2rgbfloat (float h, float s, float l, float &r, float &g, float &b) { if (s == 0.f) { @@ -340,14 +345,14 @@ public: float m1 = 2.f * l - m2; - r = 65535.f * hue2rgbfloat(m1, m2, h * 6.f + 2.f); - g = 65535.f * hue2rgbfloat(m1, m2, h * 6.f); - b = 65535.f * hue2rgbfloat(m1, m2, h * 6.f - 2.f); + r = 65535.f * hue2rgbfloat (m1, m2, h * 6.f + 2.f); + g = 65535.f * hue2rgbfloat (m1, m2, h * 6.f); + b = 65535.f * hue2rgbfloat (m1, m2, h * 6.f - 2.f); } } #ifdef __SSE2__ - static void hsl2rgb(vfloat h, vfloat s, vfloat l, vfloat &r, vfloat &g, vfloat &b); + static void hsl2rgb (vfloat h, vfloat s, vfloat l, vfloat &r, vfloat &g, vfloat &b); #endif /** @@ -359,7 +364,7 @@ public: * @param g green channel [0 ; 1] (return value) * @param b blue channel [0 ; 1] (return value) */ - static void hsl2rgb01(float h, float s, float l, float &r, float &g, float &b); + static void hsl2rgb01 (float h, float s, float l, float &r, float &g, float &b); /** @@ -371,7 +376,7 @@ public: * @param s saturation channel [0 ; 1] (return value) * @param v value channel [0 ; 1] (return value) */ - static void rgb2hsv(float r, float g, float b, float &h, float &s, float &v); + static void rgb2hsv (float r, float g, float b, float &h, float &s, float &v); /** * @brief Convert red green blue to hue saturation value @@ -382,9 +387,9 @@ public: * @param s saturation channel [0 ; 1] (return value) * @param v value channel [0 ; 1] (return value) */ - static void rgb2hsv01(float r, float g, float b, float &h, float &s, float &v); + static void rgb2hsv01 (float r, float g, float b, float &h, float &s, float &v); - static inline float rgb2s(float r, float g, float b) // fast version if only saturation is needed + static inline float rgb2s(float r, float g, float b) // fast version if only saturation is needed { float var_Min = min(r, g, b); float var_Max = max(r, g, b); @@ -398,7 +403,7 @@ public: float var_Min = min(r, g, b); - if (var_Min < 0.f) { + if(var_Min < 0.f) { return false; } else { float var_Max = max(r, g, b); @@ -411,17 +416,17 @@ public: } else { s = del_Max / var_Max; - if (r == var_Max) { + if ( r == var_Max ) { h = (g - b) / del_Max; - } else if (g == var_Max) { + } else if ( g == var_Max ) { h = 2.f + (b - r) / del_Max; } else { /*if ( b == var_Max ) */ h = 4.f + (r - g) / del_Max; } - if (h < 0.f) { + if ( h < 0.f ) { h += 6.f; - } else if (h > 6.f) { + } else if ( h > 6.f ) { h -= 6.f; } } @@ -463,9 +468,9 @@ public: * @param g green channel [0 ; 65535] (return value) * @param b blue channel [0 ; 65535] (return value) */ - static void hsv2rgb(float h, float s, float v, float &r, float &g, float &b); + static void hsv2rgb (float h, float s, float v, float &r, float &g, float &b); - static inline void hsv2rgbdcp(float h, float s, float v, float &r, float &g, float &b) + static inline void hsv2rgbdcp (float h, float s, float v, float &r, float &g, float &b) { // special version for dcp which saves 1 division (in caller) and six multiplications (inside this function) const int sector = h; // sector 0 to 5, floor() is very slow, and h is always > 0 @@ -515,7 +520,7 @@ public: } } - static void hsv2rgb(float h, float s, float v, int &r, int &g, int &b); + static void hsv2rgb (float h, float s, float v, int &r, int &g, int &b); /** @@ -527,7 +532,7 @@ public: * @param g green channel [0 ; 1] (return value) * @param b blue channel [0 ; 1] (return value) */ - static void hsv2rgb01(float h, float s, float v, float &r, float &g, float &b); + static void hsv2rgb01 (float h, float s, float v, float &r, float &g, float &b); /** @@ -540,7 +545,7 @@ public: * @param g green channel [same range than xyz channel] (return value) * @param b blue channel [same range than xyz channel] (return value) */ - static void xyz2srgb(float x, float y, float z, float &r, float &g, float &b); + static void xyz2srgb (float x, float y, float z, float &r, float &g, float &b); /** @@ -553,7 +558,7 @@ public: * @param g green channel [same range than xyz channel] (return value) * @param b blue channel [same range than xyz channel] (return value) */ - static void xyz2Prophoto(float x, float y, float z, float &r, float &g, float &b); + static void xyz2Prophoto (float x, float y, float z, float &r, float &g, float &b); /** @@ -566,7 +571,7 @@ public: * @param y Y coordinate [same range than xyz channel] * @param z Z coordinate [same range than xyz channel] */ - static void Prophotoxyz(float r, float g, float b, float &x, float &y, float &z); + static void Prophotoxyz (float r, float g, float b, float &x, float &y, float &z); /** @@ -580,11 +585,11 @@ public: * @param b blue channel [same range than xyz channel] (return value) * @param rgb_xyz[3][3] transformation matrix to use for the conversion */ - static void xyz2rgb(float x, float y, float z, float &r, float &g, float &b, const double rgb_xyz[3][3]); - static void xyz2r(float x, float y, float z, float &r, const double rgb_xyz[3][3]); - static void xyz2rgb(float x, float y, float z, float &r, float &g, float &b, const float rgb_xyz[3][3]); + static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const double rgb_xyz[3][3]); + static void xyz2r (float x, float y, float z, float &r, const double rgb_xyz[3][3]); + static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const float rgb_xyz[3][3]); #ifdef __SSE2__ - static void xyz2rgb(vfloat x, vfloat y, vfloat z, vfloat &r, vfloat &g, vfloat &b, const vfloat rgb_xyz[3][3]); + static void xyz2rgb (vfloat x, vfloat y, vfloat z, vfloat &r, vfloat &g, vfloat &b, const vfloat rgb_xyz[3][3]); #endif @@ -599,10 +604,11 @@ public: * @param z Z coordinate [same range than rgb channel] (return value) * @param xyz_rgb[3][3] transformation matrix to use for the conversion */ - static void rgbxyz(float r, float g, float b, float &x, float &y, float &z, const double xyz_rgb[3][3]); - static void rgbxyz(float r, float g, float b, float &x, float &y, float &z, const float xyz_rgb[3][3]); + static void rgbxyz (float r, float g, float b, float &x, float &y, float &z, const double xyz_rgb[3][3]); + static void rgbxyY(float r, float g, float b, float &x, float &y, float &Y, const float xyz_rgb[3][3]); + static void rgbxyz (float r, float g, float b, float &x, float &y, float &z, const float xyz_rgb[3][3]); #ifdef __SSE2__ - static void rgbxyz(vfloat r, vfloat g, vfloat b, vfloat &x, vfloat &y, vfloat &z, const vfloat xyz_rgb[3][3]); + static void rgbxyz (vfloat r, vfloat g, vfloat b, vfloat &x, vfloat &y, vfloat &z, const vfloat xyz_rgb[3][3]); #endif /** @@ -616,6 +622,7 @@ public: */ static void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z); static void L2XYZ(float L, float &x, float &y, float &z); + static float L2Y(float L); #ifdef __SSE2__ static void Lab2XYZ(vfloat L, vfloat a, vfloat b, vfloat &x, vfloat &y, vfloat &z); @@ -735,7 +742,7 @@ public: * @param path Path to follow (shortest/longest) * @return The interpolation direction */ - static inline eInterpolationDirection getHueInterpolationDirection(double h1, double h2, eInterpolationPath path) + static inline eInterpolationDirection getHueInterpolationDirection (double h1, double h2, eInterpolationPath path) { if (path == IP_SHORTEST) { if (h2 > h1) { @@ -777,7 +784,7 @@ public: * @param dir Tells which direction the interpolation have to follow. You can get the value with getHueInterpolationDirection * @return The interpolated hue */ - static inline double interpolateHueHSV(double h1, double h2, double balance, eInterpolationDirection dir) + static inline double interpolateHueHSV (double h1, double h2, double balance, eInterpolationDirection dir) { if (h1 == h2) { return h1; @@ -936,7 +943,7 @@ public: * @return the interpolated value [0;1] */ template - static inline T interpolatePolarHue_01(T h1, T h2, U balance) + static inline T interpolatePolarHue_01 (T h1, T h2, U balance) { float d = h2 - h1; float f; @@ -949,7 +956,7 @@ public: f = 1.f - f; } - if (d < T(-rtengine::RT_PI) || d < T(0) || d > T(rtengine::RT_PI)) { //there was an inversion here !! d > T(rtengine::RT_PI) + if (d < T(-rtengine::RT_PI) || d < T(0) || d > T(rtengine::RT_PI)) { //there was an inversion here !! d > T(rtengine::RT_PI) h1 += T(2 * rtengine::RT_PI); h = h1 + f * (h2 - h1); h = std::fmod(h, 2 * rtengine::RT_PI); @@ -958,11 +965,11 @@ public: } // not strictly necessary..but in case of - if (h < T(-rtengine::RT_PI)) { + if(h < T(-rtengine::RT_PI)) { h = T(2 * rtengine::RT_PI) - h; } - if (h > T(rtengine::RT_PI)) { + if(h > T(rtengine::RT_PI)) { h = h - T(2 * rtengine::RT_PI); } @@ -979,12 +986,12 @@ public: * @return the interpolated value [-PI ; +PI ] */ template - 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; - float f; + T d = h2 - h1; + T f; f = T(balance); - double h; + T h; if (h1 > h2) { std::swap(h1, h2); @@ -992,20 +999,20 @@ public: f = 1.f - f; } - 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.); h = h1 + f * (h2 - h1); - h = std::fmod(h, 1.); + h = std::fmod(h, T(1.)); } else { h = h1 + f * d; } // not strictly necessary..but in case of - if (h < T(0)) { + if(h < T(0)) { h = T(1.) - h; } - if (h > T(1)) { + if(h > T(1)) { h = h - T(1.); } @@ -1026,7 +1033,7 @@ public: * gamma4 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value) * gamma5 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value) */ - static void calcGamma(double pwr, double ts, int mode, GammaValues &gamma); + static void calcGamma (double pwr, double ts, int mode, GammaValues &gamma); /** @@ -1038,9 +1045,9 @@ public: * @param gammabwg gamma value for red channel [>0] * @param gammabwb gamma value for red channel [>0] */ - static void trcGammaBW(float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb); + static void trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb); #ifdef __SSE2__ - static void trcGammaBWRow(float *r, float *g, float *b, int width, float gammabwr, float gammabwg, float gammabwb); + static void trcGammaBWRow (float *r, float *g, float *b, int width, float gammabwr, float gammabwg, float gammabwb); #endif @@ -1063,9 +1070,9 @@ public: * @param ggm green channel of the mixer (return value) * @param bbm blue channel of the mixer (return value) */ - static void computeBWMixerConstants(const Glib::ustring &setting, const Glib::ustring &filter, const Glib::ustring &algo, float &filcor, float &mixerRed, float &mixerGreen, - float &mixerBlue, float mixerOrange, float mixerYellow, float mixerCyan, float mixerPurple, float mixerMagenta, - bool autoc, bool complement, float &kcorec, double &rrm, double &ggm, double &bbm); + static void computeBWMixerConstants (const Glib::ustring &setting, const Glib::ustring &filter, const Glib::ustring &algo, float &filcor, float &mixerRed, float &mixerGreen, + float &mixerBlue, float mixerOrange, float mixerYellow, float mixerCyan, float mixerPurple, float mixerMagenta, + bool autoc, bool complement, float &kcorec, double &rrm, double &ggm, double &bbm); // standard srgb gamma and its inverse @@ -1076,7 +1083,7 @@ public: * @param x red, green or blue channel's value [0 ; 1] * @return the gamma modified's value [0 ; 1] */ - static inline double gamma2(double x) // g3 1+g4 + static inline double gamma2 (double x) // g3 1+g4 { // return x <= 0.003041 ? x * 12.92310 : 1.055 * exp(log(x) / 2.39990) - 0.055;//calculate with calcgamma //return x <= 0.0031308 ? x * 12.92310 : 1.055 * exp(log(x) / sRGBGammaCurve) - 0.055;//standard discontinuous @@ -1092,7 +1099,7 @@ public: * @param x red, green or blue channel's value [0 ; 1] * @return the inverse gamma modified's value [0 ; 1] */ - static inline double igamma2(double x) //g2 + static inline double igamma2 (double x) //g2 { // return x <= 0.039289 ? x / 12.92310 : exp(log((x + 0.055) / 1.055) * 2.39990);//calculate with calcgamma // return x <= 0.04045 ? x / 12.92310 : exp(log((x + 0.055) / 1.055) * sRGBGammaCurve);//standard discontinuous @@ -1107,9 +1114,9 @@ public: * @param x red, green or blue channel's value [0 ; 1] * @return the gamma modified's value [0 ; 1] */ - static inline double gamma55(double x) // g3 1+g4 + static inline double gamma55 (double x) // g3 1+g4 { - return x <= 0.013189 ? x * 10.0 : 1.593503 * exp(log(x) / 5.5) - 0.593503; // 5.5 10 + return x <= 0.013189 ? x * 10.0 : 1.593503 * exp(log(x) / 5.5) - 0.593503; // 5.5 10 } @@ -1118,9 +1125,9 @@ public: * @param x red, green or blue channel's value [0 ; 1] * @return the inverse gamma modified's value [0 ; 1] */ - static inline double igamma55(double x) //g2 + static inline double igamma55 (double x) //g2 { - return x <= 0.131889 ? x / 10.0 : exp(log((x + 0.593503) / 1.593503) * 5.5); // 5.5 10 + return x <= 0.131889 ? x / 10.0 : exp(log((x + 0.593503) / 1.593503) * 5.5); // 5.5 10 } @@ -1129,9 +1136,9 @@ public: * @param x red, green or blue channel's value [0 ; 1] * @return the gamma modified's value [0 ; 1] */ - static inline double gamma4(double x) // g3 1+g4 + static inline double gamma4 (double x) // g3 1+g4 { - return x <= 0.03089 ? x * 5.0 : 1.478793 * exp(log(x) / 4.1) - 0.478793; // 4 5 + return x <= 0.03089 ? x * 5.0 : 1.478793 * exp(log(x) / 4.1) - 0.478793; // 4 5 } @@ -1140,31 +1147,31 @@ public: * @param x red, green or blue channel's value [0 ; 1] * @return the inverse gamma modified's value [0 ; 1] */ - static inline double igamma4(double x) //g2 + static inline double igamma4 (double x) //g2 { - return x <= 0.154449 ? x / 5.0 : exp(log((x + 0.478793) / 1.478793) * 4.1); // 4 5 + return x <= 0.154449 ? x / 5.0 : exp(log((x + 0.478793) / 1.478793) * 4.1); // 4 5 } - /** +/* * @brief Get the gamma value for Gamma=2.2 Slope=4.5 * @param x red, green or blue channel's value [0 ; 1] * @return the gamma modified's value [0 ; 1] * - **/ +*/ static inline double gamma709 (double x) { return x <= 0.0176 ? x*4.5 : 1.0954*exp(log(x)/2.2)-0.0954; } - /** +/* * @brief Get the inverse gamma value for Gamma=2.2 Slope=4.5 * @param x red, green or blue channel's value [0 ; 1] * @return the inverse gamma modified's value [0 ; 1] * - **/ +*/ static inline double igamma709 (double x) { return x <= 0.0795 ? x/4.5 : exp(log((x+0.0954)/1.0954)*2.2); } - + @@ -1173,7 +1180,7 @@ public: * @param x red, green or blue channel's value [0 ; 1] * @return the gamma modified's value [0 ; 1] */ - static inline double gamma24_17(double x) + static inline double gamma24_17 (double x) { return x <= 0.001867 ? x * 17.0 : 1.044445 * exp(log(x) / 2.4) - 0.044445; } @@ -1184,7 +1191,7 @@ public: * @param x red, green or blue channel's value [0 ; 1] * @return the inverse gamma modified's value [0 ; 1] */ - static inline double igamma24_17(double x) + static inline double igamma24_17 (double x) { return x <= 0.031746 ? x / 17.0 : exp(log((x + 0.044445) / 1.044445) * 2.4); } @@ -1195,7 +1202,7 @@ public: * @param x red, green or blue channel's value [0 ; 1] * @return the gamma modified's value [0 ; 1] */ - static inline double gamma26_11(double x) + static inline double gamma26_11 (double x) { return x <= 0.004921 ? x * 11.0 : 1.086603 * exp(log(x) / 2.6) - 0.086603; } @@ -1206,7 +1213,7 @@ public: * @param x red, green or blue channel's value [0 ; 1] * @return the inverse gamma modified's value [0 ; 1] */ - static inline double igamma26_11(double x) + static inline double igamma26_11 (double x) { return x <= 0.054127 ? x / 11.0 : exp(log((x + 0.086603) / 1.086603) * 2.6); } @@ -1215,44 +1222,44 @@ public: * @param x red, green or blue channel's value [0 ; 1] * @return the gamma modified's value [0 ; 1] */ - static inline double gamma13_2(double x) + static inline double gamma13_2 (double x) { return x <= 0.016613 ? x * 2.0 : 1.009968 * exp(log(x) / 1.3) - 0.009968; } - static inline double igamma13_2(double x) + static inline double igamma13_2 (double x) { return x <= 0.033226 ? x / 2.0 : exp(log((x + 0.009968) / 1.009968) * 1.3); } - static inline double gamma115_2(double x) + static inline double gamma115_2 (double x) { return x <= 0.001692 ? x * 2.0 : 1.000508 * exp(log(x) / 1.15) - 0.000508; } - static inline double igamma115_2(double x) + static inline double igamma115_2 (double x) { return x <= 0.003384 ? x / 2.0 : exp(log((x + 0.000508) / 1.000508) * 1.15); } - static inline double gamma145_3(double x) + static inline double gamma145_3 (double x) { return x <= 0.009115 ? x * 3.0 : 1.012305 * exp(log(x) / 1.45) - 0.012305; } - static inline double igamma145_3(double x) + static inline double igamma145_3 (double x) { return x <= 0.027345 ? x / 3.0 : exp(log((x + 0.012305) / 1.012305) * 1.45); } //gamma for Retinex - static inline double gammareti(double x, double gamma, double start, double slope, double mul, double add) + static inline double gammareti (double x, double gamma, double start, double slope, double mul, double add) { return (x <= start ? x*slope : exp(log(x) / gamma) * mul - add); } - static inline double igammareti(double x, double gamma, double start, double slope, double mul, double add) + static inline double igammareti (double x, double gamma, double start, double slope, double mul, double add) { - return (x <= start * slope ? x / slope : exp(log((x + add) / mul) * gamma)); + return (x <= start * slope ? x / slope : exp(log((x + add) / mul) * gamma) ); } @@ -1260,22 +1267,22 @@ public: // gamma function with adjustable parameters //same as above with values calculate with Calcgamma above // X range 0..1 - 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) { return (x <= start ? x*slope : exp(log(x) / gamma) * mul - add); } - static inline float gammaf(float x, float gamma, float start, float slope) + static inline float gammaf (float x, float gamma, float start, float slope) { return x <= start ? x * slope : xexpf(xlogf(x) / gamma); } //fills a LUT of size 65536 using gamma with slope... - static void gammaf2lut(LUTf &gammacurve, float gamma, float start, float slope, float divisor, float factor); + static void gammaf2lut (LUTf &gammacurve, float gamma, float start, float slope, float divisor, float factor); - static inline double igamma(double x, double gamma, double start, double slope, double mul, double add) + static inline double igamma (double x, double gamma, double start, double slope, double mul, double add) { - return (x <= start * slope ? x / slope : exp(log((x + add) / mul) * gamma)); + return (x <= start * slope ? x / slope : exp(log((x + add) / mul) * gamma) ); } @@ -1285,7 +1292,7 @@ public: * @param gamma gamma value [1 ; 5] * @return the gamma modified's value [0 ; 1] */ - static inline double gamman(double x, double gamma) //standard gamma without slope... + static inline double gamman (double x, double gamma) //standard gamma without slope... { return exp(log(x) / gamma); } @@ -1296,12 +1303,12 @@ public: * @param gamma gamma value [1 ; 5] * @return the gamma modified's value [0 ; 1] */ - static inline float gammanf(float x, float gamma) //standard gamma without slope... + static inline float gammanf (float x, float gamma) //standard gamma without slope... { return xexpf(xlogf(x) / gamma); } //fills a LUT of size 65536 using gamma without slope... - static void gammanf2lut(LUTf &gammacurve, float gamma, float divisor, float factor); + static void gammanf2lut (LUTf &gammacurve, float gamma, float divisor, float factor); /** * @brief Very simply inverse gamma @@ -1309,7 +1316,7 @@ public: * @param gamma gamma value [1 ; 5] * @return the inverse gamma modified's value [0 ; 1] */ - static inline double igamman(double x, double gamma) //standard inverse gamma without slope... + static inline double igamman (double x, double gamma) //standard inverse gamma without slope... { return exp(log(x) * gamma); } @@ -1323,48 +1330,43 @@ public: * @param x [0 ; 1] * @return the gamma modified's value [0 ; 65535] */ - static inline float gamma_srgb(char x) + static inline float gamma_srgb (char x) { return gammatab_srgb[x]; } - static inline float gamma_srgb327(char x) - { - return gammatab_srgb327[x]; - } - - static inline float gamma(char x) + static inline float gamma (char x) { return gammatab[x]; } - static inline float igamma_srgb(char x) + static inline float igamma_srgb (char x) { return igammatab_srgb[x]; } - static inline float gamma_srgb(int x) + static inline float gamma_srgb (int x) { return gammatab_srgb[x]; } - static inline float gamma(int x) + static inline float gamma (int x) { return gammatab[x]; } - static inline float igamma_srgb(int x) + static inline float igamma_srgb (int x) { return igammatab_srgb[x]; } - static inline float gamma_srgb(float x) + static inline float gamma_srgb (float x) { return gammatab_srgb[x]; } - static inline float gamma_srgbclipped(float x) + static inline float gamma_srgbclipped (float x) { return gamma2curve[x]; } - static inline float gamma(float x) + static inline float gamma (float x) { return gammatab[x]; } - static inline float igamma_srgb(float x) + static inline float igamma_srgb (float x) { return igammatab_srgb[x]; } @@ -1394,9 +1396,9 @@ public: */ #ifdef _DEBUG - static void AllMunsellLch(bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHueChroma, float &correctlum, MunsellDebugInfo* munsDbgInfo); + static void AllMunsellLch (bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHueChroma, float &correctlum, MunsellDebugInfo* munsDbgInfo); #else - static void AllMunsellLch(bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHueChroma, float &correctlum); + static void AllMunsellLch (bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHueChroma, float &correctlum); #endif static void AllMunsellLch (float Lprov1, float HH, float Chprov1, float CC, float &correctionHueChroma); @@ -1470,7 +1472,7 @@ public: * @param satreduc [0.1 ; 1] (return value) * @param chromx [0 or 1], actually only 0 is used */ - static void SkinSat(float lum, float hue, float chrom, float &satreduc); //jacques Skin color + static void SkinSat (float lum, float hue, float chrom, float &satreduc);//jacques Skin color /** @@ -1485,7 +1487,7 @@ public: * @param zone [1 ; 4] 1=PB correction + sky 2=red yellow correction 3=Green yellow correction 4=Red purple correction * @param correctL true=enable the Luminance correction */ - static void MunsellLch(float lum, float hue, float chrom, float memChprov, float &correction, int zone, float &lbe, bool &correctL); //jacques: Munsell correction + static void MunsellLch (float lum, float hue, float chrom, float memChprov, float &correction, int zone, float &lbe, bool &correctL);//jacques: Munsell correction // -------------------------------- end Munsell @@ -1493,8 +1495,8 @@ public: static void scalered ( float rstprotection, float param, float limit, float HH, float deltaHH, float &scale, float &scaleext); static void transitred (float HH, float Chprov1, float dred, float factorskin, float protect_red, float factorskinext, float deltaHH, float factorsat, float &factor); - static void skinred(double J, double h, double sres, double Sp, float dred, float protect_red, int sk, float rstprotection, float ko, double &s); - static void skinredfloat(float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s); + static void skinred ( double J, double h, double sres, double Sp, float dred, float protect_red, int sk, float rstprotection, float ko, double &s); + static void skinredfloat ( float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s); // static void scaleredcdbl ( float skinprot, float param, float limit, float HH, float deltaHH, float &scale,float &scaleext); static inline void pregamutlab(float lum, float hue, float &chr) //big approximation to limit gamut (Prophoto) before good gamut procedure for locallab chroma, to avoid crash @@ -1547,7 +1549,8 @@ public: // } } - static inline void SkinSatCbdl(float lum, float hue, float chrom, float skinprot, float &scale, bool neg, float b_l, float t_l, float t_r) + + static inline void SkinSatCbdl (float lum, float hue, float chrom, float skinprot, float &scale, bool neg, float b_l, float t_l, float t_r) { static const float C9 = 8.f, C8 = 15.f, C7 = 12.f, C4 = 7.f, C3 = 5.f, C2 = 5.f, C1 = 5.f; @@ -1557,11 +1560,11 @@ public: // wide area skin color, useful if not accurate colorimetry or if the user has changed hue and saturation, uses explicit factor 0.6 // wide area for transition, uses explicit factor 0.4 - if (lum >= 85.0f) { - if ((hue > (t_l + 0.53f - H9) && hue < (t_r + H9)) && (chrom > 8.0f && chrom < (14.0f + C9))) { + if (lum >= 85.0f) { + if((hue > (t_l + 0.53f - H9) && hue < (t_r + H9)) && (chrom > 8.0f && chrom < (14.0f + C9))) { scale = (100.f - skinprot) / 100.1f; } else if (lum >= 92.0f) { - if ((hue > t_l + 0.4f && hue < t_r) && (chrom > 7.0f && chrom < (15.0f))) { + if((hue > t_l + 0.4f && hue < t_r) && (chrom > 7.0f && chrom < (15.0f))) { scale = (100.f - skinprot * 0.6f) / 100.1f; } else if ((hue > b_l && hue < t_r) && (chrom > 7.0f && chrom < (18.0f))) { scale = (100.f - skinprot * 0.4f) / 100.1f; @@ -1572,61 +1575,61 @@ public: scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 70.0f) { - if ((hue > t_l + 0.15f && hue < (t_r - 0.2f + H8)) && (chrom > 8.0f && chrom < (35.0f + C8))) { + if((hue > t_l + 0.15f && hue < (t_r - 0.2f + H8)) && (chrom > 8.0f && chrom < (35.0f + C8))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 52.0f) { - if ((hue > t_l && hue < (t_r + H7)) && (chrom > 11.0f && chrom < (35.0f + C7))) { + if((hue > t_l && hue < (t_r + H7)) && (chrom > 11.0f && chrom < (35.0f + C7))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 35.0f) { - if ((hue > t_l && hue < (t_r + H4)) && (chrom > 13.0f && chrom < (37.0f + C4))) { + if((hue > t_l && hue < (t_r + H4)) && (chrom > 13.0f && chrom < (37.0f + C4))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 20.0f) { - if ((hue > t_l && hue < (t_r + H3)) && (chrom > 7.0f && chrom < (35.0f + C3))) { + if((hue > t_l && hue < (t_r + H3)) && (chrom > 7.0f && chrom < (35.0f + C3) )) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 10.0f) { - if ((hue > (t_l - 0.25f + H10) && hue < (t_r - 0.3f + H2)) && (chrom > 8.0f && chrom < (23.0f + C2))) { + if((hue > (t_l - 0.25f + H10) && hue < (t_r - 0.3f + H2)) && (chrom > 8.0f && chrom < (23.0f + C2))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (35.0f + C1))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (35.0f + C1) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.1f) && (chrom > 7.0f && chrom < (45.0f + C1))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.1f) && (chrom > 7.0f && chrom < (45.0f + C1) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if ((hue > (t_l - 0.2f + H10) && hue < (t_r - 0.3f + H1)) && (chrom > 8.0f && chrom < (23.0f + C1))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (35.0f + C1))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (35.0f + C1) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.1f) && (chrom > 7.0f && chrom < (45.0f + C1))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.1f) && (chrom > 7.0f && chrom < (45.0f + C1) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } //extended zone for hair, beard and if user adjust high value for skinprot - if (skinprot > 85.f && chrom < 20.f && neg) { + if(skinprot > 85.f && chrom < 20.f && neg) { float modula = -0.0666f * skinprot + 6.66f; scale *= modula; } } - static inline void SkinSatCbdl2(float lum, float hue, float chrom, float skinprot, float &scale, bool neg, float b_l, float t_l, float t_r, float b_r, int basc) + static inline void SkinSatCbdl2 (float lum, float hue, float chrom, float skinprot, float &scale, bool neg, float b_l, float t_l, float t_r, float b_r, int basc) { static const float C9 = 8.f, C8 = 15.f, C7 = 12.f, C4 = 7.f, C3 = 5.f, C2 = 5.f, C1 = 5.f; @@ -1635,12 +1638,12 @@ public: // "real" skin color : take into account a slight usage of contrast and saturation in RT if option "skin" = 1, uses implicit factor 1.0 // wide area skin color, useful if not accurate colorimetry or if the user has changed hue and saturation, uses explicit factor 0.6 // wide area for transition, uses explicit factor 0.4 - if ((b_l > -0.3f && b_r < 2.f) || basc == 0) { //range maxi skin - if (lum >= 85.0f) { - if ((hue > (t_l + 0.53f - H9) && hue < (t_r + H9)) && (chrom > 8.0f && chrom < (14.0f + C9))) { + if((b_l > -0.3f && b_r < 2.f) || basc == 0) { //range maxi skin + if (lum >= 85.0f) { + if((hue > (t_l + 0.53f - H9) && hue < (t_r + H9)) && (chrom > 8.0f && chrom < (14.0f + C9))) { scale = (100.f - skinprot) / 100.1f; } else if (lum >= 92.0f) { - if ((hue > t_l + 0.4f && hue < t_r) && (chrom > 7.0f && chrom < (15.0f))) { + if((hue > t_l + 0.4f && hue < t_r) && (chrom > 7.0f && chrom < (15.0f))) { scale = (100.f - skinprot * 0.6f) / 100.1f; } else if ((hue > b_l && hue < t_r) && (chrom > 7.0f && chrom < (18.0f))) { scale = (100.f - skinprot * 0.4f) / 100.1f; @@ -1651,69 +1654,69 @@ public: scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 70.0f) { - if ((hue > t_l + 0.15f && hue < (t_r - 0.2f + H8)) && (chrom > 8.0f && chrom < (35.0f + C8))) { + if((hue > t_l + 0.15f && hue < (t_r - 0.2f + H8)) && (chrom > 8.0f && chrom < (35.0f + C8))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 52.0f) { - if ((hue > t_l && hue < (t_r + H7)) && (chrom > 11.0f && chrom < (35.0f + C7))) { + if((hue > t_l && hue < (t_r + H7)) && (chrom > 11.0f && chrom < (35.0f + C7))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 35.0f) { - if ((hue > t_l && hue < (t_r + H4)) && (chrom > 13.0f && chrom < (37.0f + C4))) { + if((hue > t_l && hue < (t_r + H4)) && (chrom > 13.0f && chrom < (37.0f + C4))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 20.0f) { - if ((hue > t_l && hue < (t_r + H3)) && (chrom > 7.0f && chrom < (35.0f + C3))) { + if((hue > t_l && hue < (t_r + H3)) && (chrom > 7.0f && chrom < (35.0f + C3) )) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 10.0f) { - if ((hue > (t_l - 0.25f + H10) && hue < (t_r - 0.3f + H2)) && (chrom > 8.0f && chrom < (23.0f + C2))) { + if((hue > (t_l - 0.25f + H10) && hue < (t_r - 0.3f + H2)) && (chrom > 8.0f && chrom < (23.0f + C2))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (35.0f + C1))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (35.0f + C1) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.1f) && (chrom > 7.0f && chrom < (45.0f + C1))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.1f) && (chrom > 7.0f && chrom < (45.0f + C1) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if ((hue > (t_l - 0.2f + H10) && hue < (t_r - 0.3f + H1)) && (chrom > 8.0f && chrom < (23.0f + C1))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (35.0f + C1))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (35.0f + C1) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.1f) && (chrom > 7.0f && chrom < (45.0f + C1))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.1f) && (chrom > 7.0f && chrom < (45.0f + C1) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } //extended zone for hair, beard and if user adjust high value for skinprot - if (skinprot > 85.f && chrom < 20.f && neg) { + if(skinprot > 85.f && chrom < 20.f && neg) { float modula = -0.0666f * skinprot + 6.66f; scale *= modula; } } //end hue skin algo else if (basc == 1) { //not hue skin linear transition or mod chroma curve - if (hue >= t_l && hue <= t_r) { + if(hue >= t_l && hue <= t_r) { scale = (100.f - skinprot) / 100.1f; - } else if (hue > b_l && hue < t_l) { + } else if(hue > b_l && hue < t_l) { float sc = (100.f - skinprot) / 100.1f; float aa = (1.f - sc) / (b_l - t_l); float bb = 1.f - aa * b_l; scale = aa * hue + bb; - } else if (hue > t_r && hue < b_r) { + } else if(hue > t_r && hue < b_r) { float sc = (100.f - skinprot) / 100.1f; float aa = (sc - 1.f) / (t_r - b_r); float bb = 1.f - aa * b_r; @@ -1724,7 +1727,7 @@ public: - static inline void SkinSatCbdlCam(float lum, float hue, float chrom, float skinprot, float &scale, bool neg, float b_l, float t_l, float t_r) + static inline void SkinSatCbdlCam (float lum, float hue, float chrom, float skinprot, float &scale, bool neg, float b_l, float t_l, float t_r) { static const float C9 = 8.f, C8 = 15.f, C7 = 12.f, C4 = 7.f, C3 = 5.f, C2 = 5.f, C1 = 5.f; @@ -1732,17 +1735,17 @@ public: float HH = 0.f; - if (hue > 8.6f && hue <= 74.f) { + if (hue > 8.6f && hue <= 74.f ) { HH = (1.15f / 65.4f) * hue - 0.0012f; //H > 0.15 H<1.3 - } else if (hue > 0.f && hue <= 8.6f) { - HH = (0.19f / 8.6f) * hue - 0.04f; //H>-0.04 H < 0.15 - } else if (hue > 355.f && hue <= 360.f) { - HH = (0.11f / 5.0f) * hue - 7.96f; //H>-0.15 <-0.04 - } else if (hue > 74.f && hue < 95.f) { + } else if(hue > 0.f && hue <= 8.6f ) { + HH = (0.19f / 8.6f ) * hue - 0.04f; //H>-0.04 H < 0.15 + } else if(hue > 355.f && hue <= 360.f) { + HH = (0.11f / 5.0f ) * hue - 7.96f; //H>-0.15 <-0.04 + } else if(hue > 74.f && hue < 95.f ) { HH = (0.30f / 21.0f) * hue + 0.24285f; //H>1.3 H<1.6 - } else if (hue >= 95.f && hue < 137.5f) { + } else if(hue >= 95.f && hue < 137.5f) { HH = 0.01882f * hue - 0.18823f; // H>1.6 H<2.4 - } else if (hue > 285.f && hue <= 355.f) { + } else if(hue > 285.f && hue <= 355.f) { HH = 0.1642f * hue - 5.982f; //HH>-1.3 HH <-0.15 } @@ -1752,11 +1755,11 @@ public: // wide area skin color, useful if not accurate colorimetry or if the user has changed hue and saturation, uses explicit factor 0.6 // wide area for transition, uses explicit factor 0.4 - if (lum >= 85.0f) { - if ((hue > (t_l + 0.53f - H9) && hue < (t_r + H9)) && (chrom > 8.0f && chrom < (14.0f + C9))) { + if (lum >= 85.0f) { + if((hue > (t_l + 0.53f - H9) && hue < (t_r + H9)) && (chrom > 8.0f && chrom < (14.0f + C9))) { scale = (100.f - skinprot) / 100.1f; } else if (lum >= 92.0f) { - if ((hue > t_l + 0.4f && hue < t_r) && (chrom > 7.0f && chrom < (15.0f))) { + if((hue > t_l + 0.4f && hue < t_r) && (chrom > 7.0f && chrom < (15.0f))) { scale = (100.f - skinprot * 0.6f) / 100.1f; } else if ((hue > b_l && hue < t_r) && (chrom > 7.0f && chrom < (18.0f))) { scale = (100.f - skinprot * 0.4f) / 100.1f; @@ -1767,55 +1770,55 @@ public: scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 70.0f) { - if ((hue > t_l + 0.15f && hue < (t_r - 0.2f + H8)) && (chrom > 8.0f && chrom < (35.0f + C8))) { + if((hue > t_l + 0.15f && hue < (t_r - 0.2f + H8)) && (chrom > 8.0f && chrom < (35.0f + C8))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 52.0f) { - if ((hue > t_l && hue < (t_r + H7)) && (chrom > 11.0f && chrom < (35.0f + C7))) { + if((hue > t_l && hue < (t_r + H7)) && (chrom > 11.0f && chrom < (35.0f + C7))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 35.0f) { - if ((hue > t_l && hue < (t_r + H4)) && (chrom > 13.0f && chrom < (37.0f + C4))) { + if((hue > t_l && hue < (t_r + H4)) && (chrom > 13.0f && chrom < (37.0f + C4))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 20.0f) { - if ((hue > t_l && hue < (t_r + H3)) && (chrom > 7.0f && chrom < (35.0f + C3))) { + if((hue > t_l && hue < (t_r + H3)) && (chrom > 7.0f && chrom < (35.0f + C3) )) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (48.0f + C9) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f + C9) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if (lum >= 10.0f) { - if ((hue > (t_l - 0.25f + H10) && hue < (t_r - 0.3f + H2)) && (chrom > 8.0f && chrom < (23.0f + C2))) { + if((hue > (t_l - 0.25f + H10) && hue < (t_r - 0.3f + H2)) && (chrom > 8.0f && chrom < (23.0f + C2))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (35.0f + C1))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (35.0f + C1) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.1f) && (chrom > 7.0f && chrom < (45.0f + C1))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.1f) && (chrom > 7.0f && chrom < (45.0f + C1) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } } else if ((hue > (t_l - 0.2f + H10) && hue < (t_r - 0.3f + H1)) && (chrom > 8.0f && chrom < (23.0f + C1))) { scale = (100.f - skinprot) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (35.0f + C1))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.2f) && (chrom > 7.0f && chrom < (35.0f + C1) )) { scale = (100.f - skinprot * 0.6f) / 100.1f; - } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.1f) && (chrom > 7.0f && chrom < (45.0f + C1))) { + } else if ((hue > (b_l + 0.07f + H11) && hue < t_r - 0.1f) && (chrom > 7.0f && chrom < (45.0f + C1) )) { scale = (100.f - skinprot * 0.4f) / 100.1f; } //extended zone for hair, beard and if user adjust high value for skinprot - if (skinprot > 85.f && chrom < 20.f && neg) { + if(skinprot > 85.f && chrom < 20.f && neg) { float modula = -0.0666f * skinprot + 6.66f; scale *= modula; } @@ -1837,37 +1840,37 @@ public: * @param HH Lab's hue value, in radians [-PI ; +PI] * @return HSV's hue value [0 ; 1] */ - static inline double huelab_to_huehsv2(float HH) + static inline double huelab_to_huehsv2 (float HH) { //hr=translate Hue Lab value (-Pi +Pi) in approximative hr (hsv values) (0 1) [red 1/6 yellow 1/6 green 1/6 cyan 1/6 blue 1/6 magenta 1/6 ] // with multi linear correspondences (I expect there is no error !!) double hr = 0.0; //always put h between 0 and 1 - if (HH >= 0.f && HH < 0.6f) { - hr = 0.11666 * double (HH) + 0.93; //hr 0.93 1.00 full red - } else if (HH >= 0.6f && HH < 1.4f) { - hr = 0.1125 * double (HH) - 0.0675; //hr 0.00 0.09 red yellow orange - } else if (HH >= 1.4f && HH < 2.f) { - hr = 0.2666 * double (HH) - 0.2833; //hr 0.09 0.25 orange yellow + if (HH >= 0.f && HH < 0.6f ) { + hr = 0.11666 * double(HH) + 0.93; //hr 0.93 1.00 full red + } else if (HH >= 0.6f && HH < 1.4f ) { + hr = 0.1125 * double(HH) - 0.0675; //hr 0.00 0.09 red yellow orange + } else if (HH >= 1.4f && HH < 2.f ) { + hr = 0.2666 * double(HH) - 0.2833; //hr 0.09 0.25 orange yellow } else if (HH >= 2.f && HH < 3.14159f) { - hr = 0.1489 * double (HH) - 0.04785; //hr 0.25 0.42 yellow green green - } else if (HH >= -3.14159f && HH < -2.8f) { - hr = 0.23419 * double (HH) + 1.1557; //hr 0.42 0.50 green - } else if (HH >= -2.8f && HH < -2.3f) { - hr = 0.16 * double (HH) + 0.948; //hr 0.50 0.58 cyan - } else if (HH >= -2.3f && HH < -0.9f) { - hr = 0.12143 * double (HH) + 0.85928; //hr 0.58 0.75 blue blue-sky - } else if (HH >= -0.9f && HH < -0.1f) { - hr = 0.2125 * double (HH) + 0.94125; //hr 0.75 0.92 purple magenta - } else if (HH >= -0.1f && HH < 0.f) { - hr = 0.1 * double (HH) + 0.93; //hr 0.92 0.93 red + hr = 0.1489 * double(HH) - 0.04785; //hr 0.25 0.42 yellow green green + } else if (HH >= -3.14159f && HH < -2.8f ) { + hr = 0.23419 * double(HH) + 1.1557; //hr 0.42 0.50 green + } else if (HH >= -2.8f && HH < -2.3f ) { + hr = 0.16 * double(HH) + 0.948; //hr 0.50 0.58 cyan + } else if (HH >= -2.3f && HH < -0.9f ) { + hr = 0.12143 * double(HH) + 0.85928; //hr 0.58 0.75 blue blue-sky + } else if (HH >= -0.9f && HH < -0.1f ) { + hr = 0.2125 * double(HH) + 0.94125; //hr 0.75 0.92 purple magenta + } else if (HH >= -0.1f && HH < 0.f ) { + hr = 0.1 * double(HH) + 0.93; //hr 0.92 0.93 red } // in case of ! - if (hr < 0.0) { + if (hr < 0.0) { hr += 1.0; - } else if (hr > 1.0) { + } else if(hr > 1.0) { hr -= 1.0; } @@ -1896,6 +1899,7 @@ public: Y1[i] = Y2[i] = 0.2627f * r + 0.6780f * g + 0.0593f * b; } } + }; } diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index 02d3e0e6d..2780fcc84 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -27,11 +27,13 @@ #include #include "sleef.h" #include "settings.h" +#include "iccstore.h" + namespace rtengine { -static const double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desmis 2° Standard Observer. +static const double cie_colour_match_jd2[97][3] = {//350nm to 830nm 5 nm J.Desmis 2° Standard Observer. {0.0000000, 0.000000, 0.000000}, {0.0000000, 0.000000, 0.000000}, {0.0001299, 0.0003917, 0.0006061}, {0.0002321, 0.000006965, 0.001086}, {0.0004149, 0.00001239, 0.001946}, {0.0007416, 0.00002202, 0.003846}, {0.001368, 0.000039, 0.006450001}, {0.002236, 0.000064, 0.01054999}, {0.004243, 0.000120, 0.02005001}, @@ -67,6 +69,108 @@ static const double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desm {0.000001251141, 0.00000045181, 0.000000} }; + +static double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desmis 10° Standard Observer. +{0.000000000000, 0.000000000000, 0.000000000000}, +{0.000000000000, 0.000000000000, 0.000000000000}, +{0.000000122200, 0.000000013398, 0.000000535027}, +{0.000000919270, 0.000000100650, 0.000004028300}, +{0.000005958600, 0.000000651100, 0.000026143700}, +{0.000033266000, 0.000003625000, 0.000146220000}, +{0.000159952000, 0.000017364000, 0.000704776000}, +{0.000662440000, 0.000071560000, 0.002927800000}, +{0.002361600000, 0.000253400000, 0.010482200000}, +{0.007242300000, 0.000768500000, 0.032344000000}, +{0.019109700000, 0.002004400000, 0.086010900000}, +{0.043400000000, 0.004509000000, 0.197120000000}, +{0.084736000000, 0.008756000000, 0.389366000000}, +{0.140638000000, 0.014456000000, 0.656760000000}, +{0.204492000000, 0.021391000000, 0.972542000000}, +{0.264737000000, 0.029497000000, 1.282500000000}, +{0.314679000000, 0.038676000000, 1.553480000000}, +{0.357719000000, 0.049602000000, 1.798500000000}, +{0.383734000000, 0.062077000000, 1.967280000000}, +{0.386726000000, 0.074704000000, 2.027300000000}, +{0.370702000000, 0.089456000000, 1.994800000000}, +{0.342957000000, 0.106256000000, 1.900700000000}, +{0.302273000000, 0.128201000000, 1.745370000000}, +{0.254085000000, 0.152761000000, 1.554900000000}, +{0.195618000000, 0.185190000000, 1.317560000000}, +{0.132349000000, 0.219940000000, 1.030200000000}, +{0.080507000000, 0.253589000000, 0.772125000000}, +{0.041072000000, 0.297665000000, 0.570060000000}, +{0.016172000000, 0.339133000000, 0.415254000000}, +{0.005132000000, 0.395379000000, 0.302356000000}, +{0.003816000000, 0.460777000000, 0.218502000000}, +{0.015444000000, 0.531360000000, 0.159249000000}, +{0.037465000000, 0.606741000000, 0.112044000000}, +{0.071358000000, 0.685660000000, 0.082248000000}, +{0.117749000000, 0.761757000000, 0.060709000000}, +{0.172953000000, 0.823330000000, 0.043050000000}, +{0.236491000000, 0.875211000000, 0.030451000000}, +{0.304213000000, 0.923810000000, 0.020584000000}, +{0.376772000000, 0.961988000000, 0.013676000000}, +{0.451584000000, 0.982200000000, 0.007918000000}, +{0.529826000000, 0.991761000000, 0.003988000000}, +{0.616053000000, 0.999110000000, 0.001091000000}, +{0.793832000000, 0.982380000000, 0.000000000000}, +{0.878655000000, 0.955552000000, 0.000000000000}, +{0.951162000000, 0.915175000000, 0.000000000000}, +{1.014160000000, 0.868934000000, 0.000000000000}, +{1.074300000000, 0.825623000000, 0.000000000000}, +{1.118520000000, 0.777405000000, 0.000000000000}, +{1.134300000000, 0.720353000000, 0.000000000000}, +{1.123990000000, 0.658341000000, 0.000000000000}, +{1.089100000000, 0.593878000000, 0.000000000000}, +{1.030480000000, 0.527963000000, 0.000000000000}, +{0.950740000000, 0.461834000000, 0.000000000000}, +{0.856297000000, 0.398057000000, 0.000000000000}, +{0.754930000000, 0.339554000000, 0.000000000000}, +{0.647467000000, 0.283493000000, 0.000000000000}, +{0.535110000000, 0.228254000000, 0.000000000000}, +{0.431567000000, 0.179828000000, 0.000000000000}, +{0.343690000000, 0.140211000000, 0.000000000000}, +{0.268329000000, 0.107633000000, 0.000000000000}, +{0.204300000000, 0.081187000000, 0.000000000000}, +{0.152568000000, 0.060281000000, 0.000000000000}, +{0.112210000000, 0.044096000000, 0.000000000000}, +{0.081260600000, 0.031800400000, 0.000000000000}, +{0.057930000000, 0.022601700000, 0.000000000000}, +{0.040850800000, 0.015905100000, 0.000000000000}, +{0.028623000000, 0.011130300000, 0.000000000000}, +{0.019941300000, 0.007748800000, 0.000000000000}, +{0.013842000000, 0.005375100000, 0.000000000000}, +{0.009576880000, 0.003717740000, 0.000000000000}, +{0.006605200000, 0.002564560000, 0.000000000000}, +{0.004552630000, 0.001768470000, 0.000000000000}, +{0.003144700000, 0.001222390000, 0.000000000000}, +{0.002174960000, 0.000846190000, 0.000000000000}, +{0.001505700000, 0.000586440000, 0.000000000000}, +{0.001044760000, 0.000407410000, 0.000000000000}, +{0.000727450000, 0.000284041000, 0.000000000000}, +{0.000508258000, 0.000198730000, 0.000000000000}, +{0.000356380000, 0.000139550000, 0.000000000000}, +{0.000250969000, 0.000098428000, 0.000000000000}, +{0.000177730000, 0.000069819000, 0.000000000000}, +{0.000126390000, 0.000049737000, 0.000000000000}, +{0.000090151000, 0.000035540500, 0.000000000000}, +{0.000064525800, 0.000025486000, 0.000000000000}, +{0.000046339000, 0.000018338400, 0.000000000000}, +{0.000033411700, 0.000013249000, 0.000000000000}, +{0.000024209000, 0.000009619600, 0.000000000000}, +{0.000017611500, 0.000007012800, 0.000000000000}, +{0.000012855000, 0.000005129800, 0.000000000000}, +{0.000009413630, 0.000003764730, 0.000000000000}, +{0.000006913000, 0.000002770810, 0.000000000000}, +{0.000005093470, 0.000002046130, 0.000000000000}, +{0.000003767100, 0.000001516770, 0.000000000000}, +{0.000002795310, 0.000001128090, 0.000000000000}, +{0.000002082000, 0.000000842160, 0.000000000000}, +{0.000001553140, 0.000000629700, 0.000000000000} +}; + + + ColorTemp::ColorTemp (double t, double g, double e, const std::string &m) : temp(t), green(g), equal(e), method(m) { clip (temp, green, equal); @@ -395,6 +499,618 @@ const double ColorTemp::ColorchechGreE2_spect[97] = { 0.4297, 0.4837, 0.5142, 0.5446, 0.5541, 0.5636, 0.5608, 0.5579, 0.5480, 0.5381, 0.5258, 0.5135, 0.4959, 0.4783, 0.4570, 0.4356, 0.4124, 0.3891, 0.3710, 0.3529, 0.3425, 0.3320, 0.3266, 0.3211, 0.3180, 0.3149, 0.3129, 0.3108, 0.3123, 0.3137, 0.3193, 0.3248, 0.3335, 0.3422, 0.3518, 0.3613, 0.3693, 0.3772, 0.3810, 0.3847, 0.3838, 0.3829, 0.3838, 0.3847, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; +const double ColorTemp::ColorGreenM25_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0758, 0.0614, 0.0662, 0.0591, 0.0648, 0.0633, 0.0671, 0.0613, 0.0621, 0.0610, 0.0680, 0.0690, 0.0784, 0.0830, 0.0920, 0.1070, 0.1231, 0.1423, 0.1607, 0.1731, 0.1816, 0.1911, 0.1951, 0.1986, 0.1915, 0.1889, + 0.1758, 0.1673, 0.1606, 0.1505, 0.1384, 0.1317, 0.1230, 0.1149, 0.1081, 0.0992, 0.0882, 0.0785, 0.0709, 0.0629, 0.0550, 0.0502, 0.0486, 0.0474, 0.0445, 0.0434, 0.0429, 0.0423, 0.0411, 0.0405, 0.0397, 0.0387, 0.0399, 0.0398, 0.0398, 0.0407, 0.0408, 0.0426, 0.0445, 0.0443, 0.0468, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//0 658 45 0 0 131 98 84 123 104 131 112 121 121 139 128 148 199 296 389 476 689 945 1132 1326 1490 1674 1741 1775 1868 1914 1928 1961 1972 1992 2045 2064 2053 2048 2072 2086 2081 2069 2056 2073 2096 2114 2067 2089 2100 2061 2019 1983 1971 1961 2016 1956 1946 1922 1983 1991 +const double ColorTemp::ColorYellowkeltano_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0658, 0.0045, 0.0, 0.0, 0.0131, 0.0098, 0.0084, 0.0123, 0.0104, 0.0131, 0.0112, 0.0121, 0.0121, 0.0139, + 0.0128, 0.0148, 0.0199, 0.0296, 0.0389, 0.0476, 0.0689, 0.0945, 0.1132, 0.1326, 0.1490, 0.1674, 0.1741, 0.1775, 0.1868, + 0.1914, 0.1928, 0.1961, 0.1972, 0.1992, 0.2045, 0.2064, 0.2053, 0.2048, 0.2072, 0.2086, 0.2081, 0.2069, 0.2056, 0.2073, + 0.2096, 0.2114, 0.2067, 0.2089, 0.2100, 0.2061, 0.2019, 0.1983, 0.1971, 0.1961, 0.2016, 0.1956, 0.1946, 0.1922, 0.1983, 0.1991, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::ColorGreenalsi_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1732, 0.0292, 0.0315, 0.0533, 0.0469, 0.0359, 0.0404, 0.0356, 0.0345, 0.0374, 0.0348, 0.0336, 0.0332, 0.0333, 0.0342, + 0.0330, 0.0350, 0.0343, 0.0354, 0.0371, 0.0399, 0.0426, 0.0497, 0.0541, 0.0616, 0.0701, 0.0750, 0.0764, 0.0783, 0.0794, + 0.0784, 0.0732, 0.0708, 0.0652, 0.0612, 0.0595, 0.0570, 0.0531, 0.0507, 0.0501, 0.0488, 0.0458, 0.0437, 0.0420, 0.0436, + 0.0424, 0.0417, 0.0389, 0.0380, 0.0378, 0.0371, 0.0350, 0.0333, 0.0350, 0.0394, 0.0379, 0.0446, 0.0491, 0.0575, 0.0734, 0.0953, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//1890 1097 855 899 987 881 807 804 787 691 643 549 465 404 385 302 244 195 165 159 123 129 108 111 114 126 126 134 162 170 213 248 279 351 412 566 752 909 1069 1270 1526 +//1707 1858 1999 2112 2293 2422 2471 2611 2718 2710 2778 2807 2825 2856 2909 2901 2974 3042 3044 3075 +const double ColorTemp::ColorRedpetunia_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1890, 0.1097, 0.0855, 0.0899, 0.0987, 0.0881, 0.0807, 0.0804, 0.0787, 0.0691, 0.0643, 0.0549, 0.0465, 0.0404, 0.0385, + 0.0302, 0.0244, 0.0195, 0.0165, 0.0159, 0.0123, 0.0129, 0.0108, 0.0111, 0.0114, 0.0126, 0.0126, 0.0134, 0.0162, 0.0170, + 0.0213, 0.0248, 0.0279, 0.0351, 0.0412, 0.0566, 0.0752, 0.0909, 0.1069, 0.1270, 0.1526, 0.1707, 0.1858, 0.1999, 0.2112, + 0.2293, 0.2422, 0.2471, 0.2611, 0.2718, 0.2710, 0.2778, 0.2807, 0.2825, 0.2856, 0.2909, 0.2901, 0.2974, 0.3042, 0.3044, 0.3075, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//0.1588 0.1980 0.2789 0.4585 0.6059 0.6609 0.6674 0.6599 0.6551 0.6472 0.6423 0.6485 0.6515 0.6379 0.6193 0.6121 0.6026 0.5678 0.5310 0.5245 0.5305 0.5324 0.5262 0.5219 0.5247 0.5312 0.5436 0.5634 0.5832 0.5943 0.5953 0.5902 0.5805 0.5754 0.5901 0.6262 + +const double ColorTemp::JDC468_B14_75Redspect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1588, 0.1780, 0.1980, 0.2310, 0.2789, 0.3213, 0.4585, 0.5324, 0.6059, 0.6334, 0.6609, 0.6630, 0.6674, 0.6640, 0.6599, 0.6600, 0.6551, 0.6532, 0.6472, 0.6450, + 0.6423, 0.6467, 0.6485, 0.6500, 0.6515, 0.6456, 0.6379, 0.6285, 0.6193, 0.6150, 0.6121, 0.6056, 0.6026, 0.5812, 0.5678, 0.5490, 0.5310, 0.5307, 0.5245, 0.5300, + 0.5305, 0.5310, 0.5324, 0.5298, 0.5262, 0.5230, 0.5219, 0.5231, 0.5247, 0.5280, 0.5312, 0.5364, 0.5436, 0.5550, 0.5634, 0.5731, 0.5832, 0.5901, 0.5943, 0.5950, + 0.5953, 0.5926, 0.5902, 0.5850, 0.5805, 0.5770, 0.5754, 0.6012, 0.6262, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +const double ColorTemp::ColorRedkurttu_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0979, 0.1536, 0.0745, 0.1145, 0.0937, 0.0996, 0.0972, 0.0924, 0.0875, 0.0878, 0.0826, 0.0766, 0.0658, 0.0599, 0.0545, + 0.0509, 0.0443, 0.0381, 0.0356, 0.0327, 0.0318, 0.0304, 0.0295, 0.0288, 0.0285, 0.0271, 0.0281, 0.0282, 0.0278, 0.0280, + 0.0296, 0.0309, 0.0324, 0.0342, 0.0343, 0.0376, 0.0419, 0.0464, 0.0520, 0.0634, 0.0747, 0.0905, 0.1093, 0.1167, 0.1264, + 0.1439, 0.1650, 0.1928, 0.2183, 0.2380, 0.2537, 0.2754, 0.2893, 0.3009, 0.3115, 0.3213, 0.3173, 0.3222, 0.3237, 0.3192, 0.3210, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#light red flower (lupiini) +//1792 1553 1684 1882 1909 1847 2053 2084 2045 2052 2039 2084 2041 2044 2007 1984 1906 1876 1886 1855 1859 1875 1816 1800 1811 1780 1802 1816 1838 1915 1973 2018 2083 2114 2133 2226 2304 2385 2458 2494 2571 2689 2738 2774 2734 2759 2781 2831 2844 2857 2878 2876 2884 2920 2932 2860 2894 2934 2925 2928 2921 +const double ColorTemp::ColorRedlupiini_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1792, 0.1553, 0.1684, 0.1882, 0.1909, 0.1847, 0.2053, 0.2084, 0.2045, 0.2052, 0.2039, 0.2084, 0.2041, 0.2044, 0.2007, 0.1984, 0.1906, 0.1876, + 0.1886, 0.1855, 0.1859, 0.1875, 0.1816, 0.1800, 0.1811, 0.1780, 0.1802, 0.1816, 0.1838, 0.1915, 0.1973, 0.2018, 0.2083, 0.2114, 0.2133, 0.2226, + 0.2304, 0.2385, 0.2458, 0.2494, 0.2571, 0.2689, 0.2738, 0.2774, 0.2734, 0.2759, 0.2781, 0.2831, 0.2844, 0.2857, 0.2878, 0.2876, 0.2884, 0.2920, + 0.2932, 0.2860, 0.2894, 0.2934, 0.2925, 0.2928, 0.2921, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//#red flower (hevosminttu) +//1280 706 612 462 391 339 253 285 261 264 239 208 201 186 185 161 156 149 146 148 161 144 143 151 147 146 139 148 173 185 185 197 222 238 283 322 384 439 519 633 792 922 1061 1186 1235 1342 1538 1691 1839 1974 2024 2098 2128 2187 2204 2217 2267 2299 2339 2331 2322 +const double ColorTemp::ColorRedhevosminttu_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1280, 0.0706, 0.0612, 0.0462, 0.0391, 0.0339, 0.0253, 0.0285, 0.0261, 0.0264, 0.0239, 0.0208, 0.0201, 0.0186, 0.0185, 0.0161, 0.0156, 0.0149, + 0.0146, 0.0148, 0.0161, 0.0144, 0.0143, 0.0151, 0.0147, 0.0146, 0.0139, 0.0148, 0.0173, 0.0185, 0.0185, 0.0197, 0.0222, 0.0238, 0.0283, 0.0322, + 0.0384, 0.0439, 0.0519, 0.0633, 0.0792, 0.0922, 0.1061, 0.1186, 0.1235, 0.1342, 0.1538, 0.1691, 0.1839, 0.1974, 0.2024, 0.2098, 0.2128, 0.2187, 0.2204, + 0.2217, 0.2267, 0.2299, 0.2339, 0.2331, 0.2322, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//#red flower (neilikka) +//0 0 394 0 245 95 174 149 194 171 181 175 172 167 147 137 107 108 100 87 93 87 83 77 80 67 72 64 83 84 88 90 91 94 114 133 178 241 309 419 612 823 992 1153 1222 1366 1503 1658 1767 1841 1884 1992 2035 2007 2009 2045 2065 2229 2290 2395 2449 +const double ColorTemp::ColorRedneilikka_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0394, 0.0, 0.0245, 0.0095, 0.0174, 0.0149, 0.0194, 0.0171, 0.0181, 0.0175, 0.0172, 0.0167, 0.0147, 0.0137, 0.0107, 0.0108, 0.0100, + 0.0087, 0.0093, 0.0087, 0.0083, 0.0077, 0.0080, 0.0067, 0.0072, 0.0064, 0.0083, 0.0084, 0.0088, 0.0090, 0.0091, 0.0094, 0.0114, 0.0133, + 0.0178, 0.0241, 0.0309, 0.0419, 0.0612, 0.0823, 0.0992, 0.1153, 0.1222, 0.1366, 0.1503, 0.1658, 0.1767, 0.1841, 0.1884, 0.1992, 0.2035, 0.2007, 0.2009, + 0.2045, 0.2065, 0.2229, 0.2290, 0.2395, 0.2449, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#red petal (pelargonia) +//2529 2048 2087 2698 2452 2372 2531 2475 2296 2294 2159 2111 1986 1898 1854 1729 1586 1501 1392 1332 1343 1255 1217 1182 1183 1203 1230 1277 1381 1474 1615 1762 1876 2028 2214 2464 2657 2919 3051 3172 3293 3421 3395 3494 3438 3495 3506 3490 3454 3487 3431 3452 3484 3438 3422 3368 3325 3441 3356 3432 3320 +const double ColorTemp::ColorRedpelagornia_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2529, 0.2048, 0.2087, 0.2698, 0.2452, 0.2372, 0.2531, 0.2475, 0.2296, 0.2294, 0.2159, 0.2111, 0.1986, 0.1898, 0.1854, 0.1729, 0.1586, 0.1501, 0.1392, 0.1332, 0.1343, + 0.1255, 0.1217, 0.1182, 0.1183, 0.1203, 0.1230, 0.1277, 0.1381, 0.1474, 0.1615, 0.1762, 0.1876, 0.2028, 0.2214, 0.2464, 0.2657, 0.2919, 0.3051, 0.3172, 0.3293, 0.3421, + 0.3395, 0.3494, 0.3438, 0.3495, 0.3506, 0.3490, 0.3454, 0.3487, 0.3431, 0.3452, 0.3484, 0.3438, 0.3422, 0.3368, 0.3325, 0.3441, 0.3356, 0.3432, 0.3320, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#red flower (talvio) +//3131 2199 2559 2540 2844 2530 2694 2765 2594 2673 2617 2629 2491 2384 2308 2256 2081 1973 1857 1752 1719 1652 1527 1477 1459 1386 1341 1283 1318 1334 1354 1424 1495 1543 1634 1773 1950 2129 2272 2431 2642 2827 2941 3045 3082 3158 3216 3307 3364 3388 3387 3517 3573 3501 3499 3523 3495 3606 3493 3518 3522 +const double ColorTemp::ColorRedtalvio_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3131, 0.2199, 0.2559, 0.2540, 0.2844, 0.2530, 0.2694, 0.2765, 0.2594, 0.2673, 0.2617, 0.2629, 0.2491, 0.2384, 0.2308, 0.2256, 0.2081, 0.1973, 0.1857, 0.1752, 0.1719, + 0.1652, 0.1527, 0.1477, 0.1459, 0.1386, 0.1341, 0.1283, 0.1318, 0.1334, 0.1354, 0.1424, 0.1495, 0.1543, 0.1634, 0.1773, 0.1950, 0.2129, 0.2272, 0.2431, 0.2642, 0.2827, + 0.2941, 0.3045, 0.3082, 0.3158, 0.3216, 0.3307, 0.3364, 0.3388, 0.3387, 0.3517, 0.3573, 0.3501, 0.3499, 0.3523, 0.3495, 0.3606, 0.3493, 0.3518, 0.3522, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + +}; + +//#brown dry leaf (poimulehti) +//964 520 223 244 261 247 196 199 200 207 202 198 209 204 207 222 205 218 213 212 224 218 230 235 251 250 245 250 263 273 271 275 281 264 274 288 287 307 303 307 323 304 335 335 346 345 347 348 370 364 380 393 384 407 419 421 419 433 431 461 465 +//RIs 67 +const double ColorTemp::ColorBrownpoimulehti_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0964, 0.0520, 0.0223, 0.0244, 0.0261, 0.0247, 0.0196, 0.0199, 0.0200, 0.0207, 0.0202, 0.0198, 0.0209, 0.0204, 0.0207, 0.0222, 0.0205, 0.0218, 0.0213, + 0.0212, 0.0224, 0.0218, 0.0230, 0.0235, 0.0251, 0.0250, 0.0245, 0.0250, 0.0263, 0.0273, 0.0271, 0.0275, 0.0281, 0.0264, 0.0274, 0.0288, 0.0287, 0.0307, + 0.0303, 0.0307, 0.0323, 0.0304, 0.0335, 0.0335, 0.0346, 0.0345, 0.0347, 0.0348, 0.0370, 0.0364, 0.0380, 0.0393, 0.0384, 0.0407, + 0.0419, 0.0421, 0.0419, 0.0433, 0.0431, 0.0461, 0.0465, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#orange leaf (koristepensas, tuntematon) +//241 195 223 489 574 565 634 605 574 613 645 636 644 628 621 603 614 654 676 719 776 795 862 879 918 918 955 980 1013 1055 1132 1225 1258 1362 1427 1579 1796 1936 2079 2258 2440 2597 2728 2790 2777 2857 2923 2991 3031 3040 3037 3094 3066 3023 3093 3044 3082 3085 3147 3226 3192 +const double ColorTemp::ColorOrangetuntematon_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0241, 0.0195, 0.0223, 0.0489, 0.0574, 0.0565, 0.0634, 0.0605, 0.0574, 0.0613, 0.0645, 0.0636, 0.0644, 0.0628, 0.0621, 0.0603, 0.0614, 0.0654, 0.0676, + 0.0719, 0.0776, 0.0795, 0.0862, 0.0879, 0.0918, 0.0918, 0.0955, 0.0980, 0.1013, 0.1055, 0.1132, 0.1225, 0.1258, 0.1362, 0.1427, 0.1579, 0.1796, 0.1936, 0.2079, + 0.2258, 0.2440, 0.2597, 0.2728, 0.2790, 0.2777, 0.2857, 0.2923, 0.2991, 0.3031, 0.3040, 0.3037, 0.3094, 0.3066, 0.3023, 0.3093, 0.3044, 0.3082, 0.3085, 0.3147, 0.3226, 0.3192, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//,#orange leaf (lehmus) +//1062 866 443 544 496 485 492 458 450 425 458 477 497 461 451 481 454 500 515 538 529 593 638 670 686 711 718 729 741 760 796 833 895 958 1016 1128 1246 1344 1450 1505 1596 1636 1621 1631 1627 1628 1658 1583 1486 1415 1322 1265 1159 1062 975 974 1063 1326 1736 2141 2568 +const double ColorTemp::ColorOrangetlehmus_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1062, 0.0866, 0.0443, 0.0544, 0.0496, 0.0485, 0.0492, 0.0458, 0.0450, 0.0425, 0.0458, 0.0477, 0.0497, 0.0461, 0.0451, 0.0481, 0.0454, 0.0500, 0.0515, + 0.0538, 0.0529, 0.0593, 0.0638, 0.0670, 0.0686, 0.0711, 0.0718, 0.0729, 0.0741, 0.0760, 0.0796, 0.0833, 0.0895, 0.0958, 0.1016, 0.1128, 0.1246, 0.1344, 0.1450, + 0.1505, 0.1596, 0.1636, 0.1621, 0.1631, 0.1627, 0.1628, 0.1658, 0.1583, 0.1486, 0.1415, 0.1322, 0.1265, 0.1159, 0.1062, 0.0975, 0.0974, 0.1063, 0.1326, 0.1736, 0.2141, 0.2568, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#orange leaf (vaahtera) +//1517 551 664 659 521 585 460 385 424 389 375 374 359 380 371 373 379 387 378 394 405 416 463 496 536 542 577 579 619 642 678 710 777 829 894 1035 1174 1334 1484 1611 1798 1941 2012 2065 2135 2229 2286 2317 2332 2357 2323 2330 2292 2236 2137 2093 2180 2240 2368 2487 2528 +const double ColorTemp::ColorOrangvaahtera_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1517, 0.0551, 0.0664, 0.0659, 0.0521, 0.0585, 0.0460, 0.0385, 0.0424, 0.0389, 0.0375, 0.0374, 0.0359, 0.0380, 0.0371, 0.0373, 0.0379, 0.0387, 0.0378, + 0.0394, 0.0405, 0.0416, 0.0463, 0.0496, 0.0536, 0.0542, 0.0577, 0.0579, 0.0619, 0.0642, 0.0678, 0.0710, 0.0777, 0.0829, 0.0894, 0.1035, 0.1174, 0.1334, 0.1484, + 0.1611, 0.1798, 0.1941, 0.2012, 0.2065, 0.2135, 0.2229, 0.2286, 0.2317, 0.2332, 0.2357, 0.2323, 0.2330, 0.2292, 0.2236, 0.2137, 0.2093, 0.2180, 0.2240, 0.2368, 0.2487, 0.2528, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#brown dry leaf (lehmus) +//758 236 148 430 347 435 438 495 439 454 472 471 461 459 458 479 492 482 499 513 520 545 567 594 623 647 698 717 744 792 803 834 864 876 916 932 963 1013 1025 1060 1099 1118 1153 1175 1207 1242 1268 1266 1284 1305 1305 1304 1353 1360 1330 1332 1413 1502 1610 1682 1737 +const double ColorTemp::ColorBrownlehmus_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0758, 0.0236, 0.0148, 0.0430, 0.0347, 0.0435, 0.0438, 0.0495, 0.0439, 0.0454, 0.0472, 0.0471, 0.0461, 0.0459, 0.0458, 0.0479, 0.0492, 0.0482, 0.0499, 0.0513, + 0.0520, 0.0545, 0.0567, 0.0594, 0.0623, 0.0647, 0.0698, 0.0717, 0.0744, 0.0792, 0.0803, 0.0834, 0.0864, 0.0876, 0.0916, 0.0932, 0.0963, 0.1013, 0.1025, 0.1060, + 0.1099, 0.1118, 0.1153, 0.1175, 0.1207, 0.1242, 0.1268, 0.1266, 0.1284, 0.1305, 0.1305, 0.1304, 0.1353, 0.1360, 0.1330, 0.1332, 0.1413, 0.1502, 0.1610, 0.1682, 0.1737, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//#brown moss (nuotiosammal) +//482 260 178 92 104 88 92 40 43 52 58 64 70 63 67 67 62 76 82 82 91 96 104 116 135 141 142 155 168 179 198 199 193 201 212 218 226 240 242 238 255 265 277 266 265 283 289 275 289 277 291 288 277 252 262 260 264 299 375 411 446 +const double ColorTemp::ColorBrownuotiosammal_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0482, 0.0260, 0.0178, 0.0092, 0.0104, 0.0088, 0.0092, 0.0040, 0.0043, 0.0052, 0.0058, 0.0064, 0.0070, 0.0063, 0.0067, 0.0067, 0.0062, 0.0076, 0.0082, 0.0082, 0.0091, 0.0096, + 0.0104, 0.0116, 0.0135, 0.0141, 0.0142, 0.0155, 0.0168, 0.0179, 0.0198, 0.0199, 0.0193, 0.0201, 0.0212, 0.0218, 0.0226, 0.0240, 0.0242, 0.0238, 0.0255, 0.0265, + 0.0277, 0.0266, 0.0265, 0.0283, 0.0289, 0.0275, 0.0289, 0.0277, 0.0291, 0.0288, 0.0277, 0.0252, 0.0262, 0.0260, 0.0264, 0.0299, 0.0375, 0.0411, 0.0446, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#black soil +//0 0 89 122 52 53 104 127 130 134 137 137 134 136 138 139 134 140 142 148 154 153 152 150 151 156 153 166 154 171 163 163 166 166 169 169 166 174 174 170 170 168 176 177 176 174 179 180 180 183 177 193 178 187 194 193 182 196 184 195 195 +const double ColorTemp::ColorBlacksoil_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0089, 0.0122, 0.0052, 0.0053, 0.0104, 0.0127, 0.0130, 0.0134, 0.0137, 0.0137, 0.0134, 0.0136, 0.0138, 0.0139, 0.0134, 0.0140, 0.0142, 0.0148, 0.0154, 0.0153, + 0.0152, 0.0150, 0.0151, 0.0156, 0.0153, 0.0166, 0.0154, 0.0171, 0.0163, 0.0163, 0.0166, 0.0166, 0.0169, 0.0169, 0.0166, 0.0174, 0.0174, 0.0170, 0.0170, 0.0168, 0.0176, 0.0177, + 0.0176, 0.0174, 0.0179, 0.0180, 0.0180, 0.0183, 0.0177, 0.0193, 0.0178, 0.0187, 0.0194, 0.0193, 0.0182, 0.0196, 0.0184, 0.0195, 0.0195, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#black, dry leaf (pihlaja) +//0 79 111 172 174 201 214 211 207 207 191 200 196 206 196 194 203 207 204 208 210 212 211 208 209 219 222 224 231 241 232 244 249 250 267 264 262 269 282 277 289 284 279 302 289 308 313 315 310 325 313 319 356 340 331 347 356 352 364 373 352 +const double ColorTemp::ColorBlackpihlaja[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0079, 0.0111, 0.0172, 0.0174, 0.0201, 0.0214, 0.0211, 0.0207, 0.0207, 0.0191, 0.0200, 0.0196, 0.0206, 0.0196, 0.0194, 0.0203, 0.0207, 0.0204, 0.0208, 0.0210, 0.0212, + 0.0211, 0.0208, 0.0209, 0.0219, 0.0222, 0.0224, 0.0231, 0.0241, 0.0232, 0.0244, 0.0249, 0.0250, 0.0267, 0.0264, 0.0262, 0.0269, 0.0282, 0.0277, 0.0289, 0.0284, 0.0279, 0.0302, + 0.0289, 0.0308, 0.0313, 0.0315, 0.0310, 0.0325, 0.0313, 0.0319, 0.0356, 0.0340, 0.0331, 0.0347, 0.0356, 0.0352, 0.0364, 0.0373, 0.0352, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + + +//#gray lichen (nahkajaekaelae) +//1204 585 1113 733 600 653 715 685 726 682 713 691 719 691 683 693 711 715 701 700 720 697 706 696 723 714 726 738 729 735 737 739 742 746 746 761 743 735 722 717 728 749 721 712 705 737 733 758 780 785 775 771 755 744 743 742 755 779 849 940 1042 +//RIS 74 +const double ColorTemp::ColorGraynahjajaekaelae_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1204, 0.0585, 0.1113, 0.0733, 0.0600, 0.0653, 0.0715, 0.0685, 0.0726, 0.0682, 0.0713, 0.0691, 0.0719, 0.0691, 0.0683, 0.0693, 0.0711, 0.0715, 0.0701, 0.0700, + 0.0720, 0.0697, 0.0706, 0.0696, 0.0723, 0.0714, 0.0726, 0.0738, 0.0729, 0.0735, 0.0737, 0.0739, 0.0742, 0.0746, 0.0746, 0.0761, 0.0743, 0.0735, 0.0722, 0.0717, + 0.0728, 0.0749, 0.0721, 0.0712, 0.0705, 0.0737, 0.0733, 0.0758, 0.0780, 0.0785, 0.0775, 0.0771, 0.0755, 0.0744, 0.0743, 0.0742, 0.0755, 0.0779, 0.0849, 0.0940, 0.1042, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#green moss (nuotiosammal) +//120 65 134 31 209 124 104 96 97 95 76 79 83 93 83 95 95 104 117 127 140 161 214 252 290 310 328 343 347 373 365 351 347 343 311 301 285 283 263 256 255 251 257 235 227 224 233 208 194 186 165 160 151 149 157 161 185 243 309 425 543 +const double ColorTemp::ColorGreennuotisammal_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0120, 0.0065, 0.0134, 0.0031, 0.0209, 0.0124, 0.0104, 0.0096, 0.0097, 0.0095, 0.0076, 0.0079, 0.0083, 0.0093, 0.0083, 0.0095, 0.0095, 0.0104, 0.0117, 0.0127, 0.0140, 0.0161, + 0.0214, 0.0252, 0.0290, 0.0310, 0.0328, 0.0343, 0.0347, 0.0373, 0.0365, 0.0351, 0.0347, 0.0343, 0.0311, 0.0301, 0.0285, 0.0283, 0.0263, 0.0256, 0.0255, 0.0251, + 0.0257, 0.0235, 0.0227, 0.0224, 0.0233, 0.0208, 0.0194, 0.0186, 0.0165, 0.0160, 0.0151, 0.0149, 0.0157, 0.0161, 0.0185, 0.0243, 0.0309, 0.0425, 0.0543, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//#green leaf (leskenlehti) +//525 273 0 378 318 164 224 276 316 266 303 290 305 286 290 303 323 323 352 383 405 482 614 743 920 1015 1139 1192 1175 1216 1195 1145 1116 1009 947 867 802 754 741 709 675 625 574 579 561 565 557 511 471 419 399 372 365 395 375 382 458 555 716 1002 1407 +const double ColorTemp::ColorGreenleskenlehti_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0525, 0.0273, 0.0, 0.0378, 0.0318, 0.0164, 0.0224, 0.0276, 0.0316, 0.0266, 0.0303, 0.0290, 0.0305, 0.0286, 0.0290, 0.0303, 0.0323, 0.0323, 0.0352, 0.0383, 0.0405, 0.0482, + 0.0614, 0.0743, 0.0920, 0.1015, 0.1139, 0.1192, 0.1175, 0.1216, 0.1195, 0.1145, 0.1116, 0.1009, 0.0947, 0.0867, 0.0802, 0.0754, 0.0741, 0.0709, 0.0675, 0.0625, + 0.0574, 0.0579, 0.0561, 0.0565, 0.0557, 0.0511, 0.0471, 0.0419, 0.0399, 0.0372, 0.0365, 0.0395, 0.0375, 0.0382, 0.0458, 0.0555, 0.0716, 0.1002, 0.1407, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#green leaf (linnunkaali) +//602 0 267 306 339 335 300 247 292 289 295 298 292 318 312 289 299 307 310 320 350 375 446 499 574 634 698 725 736 754 736 702 668 633 590 551 514 499 467 460 445 424 415 409 399 412 393 380 370 362 366 343 342 350 333 350 364 418 494 670 914 +//RIS 77 +const double ColorTemp::ColorGreenlinnunkaali_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0602, 0.0, 0.0267, 0.0306, 0.0339, 0.0335, 0.0300, 0.0247, 0.0292, 0.0289, 0.0295, 0.0298, 0.0292, 0.0318, 0.0312, 0.0289, 0.0299, 0.0307, 0.0310, 0.0320, + 0.0350, 0.0375, 0.0446, 0.0499, 0.0574, 0.0634, 0.0698, 0.0725, 0.0736, 0.0754, 0.0736, 0.0702, 0.0668, 0.0633, 0.0590, 0.0551, 0.0514, 0.0499, 0.0467, 0.0460, + 0.0445, 0.0424, 0.0415, 0.0409, 0.0399, 0.0412, 0.0393, 0.0380, 0.0370, 0.0362, 0.0366, 0.0343, 0.0342, 0.0350, 0.0333, 0.0350, 0.0364, 0.0418, 0.0494, 0.0670, 0.0914, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//#green leaf (pelto-ohake) +//0 366 360 233 173 179 157 175 206 205 180 179 173 178 187 189 184 171 195 204 193 219 253 297 365 431 467 489 493 516 500 466 426 406 380 343 316 295 276 282 265 253 239 228 226 229 238 237 216 221 219 217 212 219 229 258 284 309 375 487 732 +const double ColorTemp::ColorGreenpelto_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0366, 0.0360, 0.0233, 0.0173, 0.0179, 0.0157, 0.0175, 0.0206, 0.0205, 0.0180, 0.0179, 0.0173, 0.0178, 0.0187, 0.0189, 0.0184, 0.0171, 0.0195, 0.0204, 0.0193, 0.0219, + 0.0253, 0.0297, 0.0365, 0.0431, 0.0467, 0.0489, 0.0493, 0.0516, 0.0500, 0.0466, 0.0426, 0.0406, 0.0380, 0.0343, 0.0316, 0.0295, 0.0276, 0.0282, 0.0265, 0.0253, 0.0239, + 0.0228, 0.0226, 0.0229, 0.0238, 0.0237, 0.0216, 0.0221, 0.0219, 0.0217, 0.0212, 0.0219, 0.0229, 0.0258, 0.0284, 0.0309, 0.0375, 0.0487, 0.0732, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#green rod (voikukka), +//2205 1755 1710 1365 1159 1207 1024 1118 1127 1141 1134 1125 1149 1140 1120 1128 1139 1156 1212 1273 1262 1359 1461 1519 1568 1599 1660 1668 1680 1718 1697 1690 1672 1675 1663 1644 1642 1652 1626 1623 1653 1621 1614 1590 1625 1609 1615 1576 1509 1483 1418 1391 1324 1294 1267 1220 1315 1417 1650 1861 2006 +const double ColorTemp::ColorGreenrodvoikukka[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2205, 0.1755, 0.1710, 0.1365, 0.1159, 0.1207, 0.1024, 0.1118, 0.1127, 0.1141, 0.1134, 0.1125, 0.1149, 0.1140, 0.1120, 0.1128, 0.1139, 0.1156, 0.1212, 0.1273, 0.1262, 0.1359, + 0.1461, 0.1519, 0.1568, 0.1599, 0.1660, 0.1668, 0.1680, 0.1718, 0.1697, 0.1690, 0.1672, 0.1675, 0.1663, 0.1644, 0.1642, 0.1652, 0.1626, 0.1623, 0.1653, 0.1621, 0.1614, 0.1590, + 0.1625, 0.1609, 0.1615, 0.1576, 0.1509, 0.1483, 0.1418, 0.1391, 0.1324, 0.1294, 0.1267, 0.1220, 0.1315, 0.1417, 0.1650, 0.1861, 0.2006, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#green leaf (lehmus) +//2362 1024 945 666 617 604 591 580 648 631 656 607 616 653 643 626 643 656 710 753 801 929 1105 1277 1437 1601 1742 1774 1798 1848 1832 1820 1787 1730 1663 1593 1541 1461 1446 1419 1335 1298 1247 1192 1197 1199 1156 1072 1007 942 899 832 824 793 755 801 860 1031 1305 1809 2260 +const double ColorTemp::ColorGreenlehmus[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2362, 0.1024, 0.0945, 0.0666, 0.0617, 0.0604, 0.0591, 0.0580, 0.0648, 0.0631, 0.0656, 0.0607, 0.0616, 0.0653, 0.0643, 0.0626, 0.0643, 0.0656, 0.0710, 0.0753, + 0.0801, 0.0929, 0.1105, 0.1277, 0.1437, 0.1601, 0.1742, 0.1774, 0.1798, 0.1848, 0.1832, 0.1820, 0.1787, 0.1730, 0.1663, 0.1593, 0.1541, 0.1461, 0.1446, 0.1419, 0.1335, 0.1298, + 0.1247, 0.1192, 0.1197, 0.1199, 0.1156, 0.1072, 0.1007, 0.0942, 0.0899, 0.0832, 0.0824, 0.0793, 0.0755, 0.0801, 0.0860, 0.1031, 0.1305, 0.1809, 0.2260, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#green leaf (koristeherukka) +//945 292 315 433 321 294 295 321 278 261 282 272 270 278 285 274 277 268 269 283 275 309 325 389 450 493 551 557 587 585 567 554 515 487 460 424 409 387 353 349 353 333 309 309 312 315 321 298 304 304 281 273 293 311 314 333 355 392 439 595 811 +const double ColorTemp::ColorGreenkoriste[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0945, 0.0292, 0.0315, 0.0433, 0.0321, 0.0294, 0.0295, 0.0321, 0.0278, 0.0261, 0.0282, 0.0272, 0.0270, 0.0278, 0.0285, 0.0274, 0.0277, 0.0268, 0.0269, 0.0283, + 0.0275, 0.0309, 0.0325, 0.0389, 0.0450, 0.0493, 0.0551, 0.0557, 0.0587, 0.0585, 0.0567, 0.0554, 0.0515, 0.0487, 0.0460, 0.0424, 0.0409, 0.0387, 0.0353, 0.0349, + 0.0353, 0.0333, 0.0309, 0.0309, 0.0312, 0.0315, 0.0321, 0.0298, 0.0304, 0.0304, 0.0281, 0.0273, 0.0293, 0.0311, 0.0314, 0.0333, 0.0355, 0.0392, 0.0439, 0.0595, 0.0811, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//#green leaf (poimulehti) +//1102 146 630 266 247 261 285 238 273 281 272 260 262 254 274 263 273 278 296 309 322 388 493 607 712 840 953 986 1006 1034 999 981 918 855 794 711 649 627 604 563 531 515 467 450 448 466 445 421 402 385 369 345 346 319 330 359 378 439 578 835 1177 +const double ColorTemp::ColorGreenpoimulehti[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1102, 0.0146, 0.0630, 0.0266, 0.0247, 0.0261, 0.0285, 0.0238, 0.0273, 0.0281, 0.0272, 0.0260, 0.0262, 0.0254, 0.0274, 0.0263, 0.0273, 0.0278, 0.0296, 0.0309, 0.0322, + 0.0388, 0.0493, 0.0607, 0.0712, 0.0840, 0.0953, 0.0986, 0.1006, 0.1034, 0.0999, 0.0981, 0.0918, 0.0855, 0.0794, 0.0711, 0.0649, 0.0627, 0.0604, 0.0563, 0.0531, 0.0515, + 0.0467, 0.0450, 0.0448, 0.0466, 0.0445, 0.0421, 0.0402, 0.0385, 0.0369, 0.0345, 0.0346, 0.0319, 0.0330, 0.0359, 0.0378, 0.0439, 0.0578, 0.0835, 0.1177, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//#green leaf (hopeapaju) +//787 512 1260 1032 765 881 994 908 983 985 941 985 971 967 964 937 928 959 973 992 1004 1017 1053 1102 1180 1227 1281 1309 1317 1328 1318 1271 1238 1222 1179 1152 1131 1092 1086 1078 1083 1020 1015 1000 1027 1037 1028 970 962 977 952 963 955 935 980 979 963 1028 1059 1228 1401 +const double ColorTemp::ColorGreenhopeapaju[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0787, 0.0512, 0.1260, 0.1032, 0.0765, 0.0881, 0.0994, 0.0908, 0.0983, 0.0985, 0.0941, 0.0985, 0.0971, 0.0967, 0.0964, 0.0937, 0.0928, 0.0959, 0.0973, 0.0992, 0.1004, + 0.1017, 0.1053, 0.1102, 0.1180, 0.1227, 0.1281, 0.1309, 0.1317, 0.1328, 0.1318, 0.1271, 0.1238, 0.1222, 0.1179, 0.1152, 0.1131, 0.1092, 0.1086, 0.1078, 0.1083, 0.1020, + 0.1015, 0.1000, 0.1027, 0.1037, 0.1028, 0.0970, 0.0962, 0.0977, 0.0952, 0.0963, 0.0955, 0.0935, 0.0980, 0.0979, 0.0963, 0.1028, 0.1059, 0.1228, 0.1401, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#red flower (uuden guinean liisa) +//2288 1861 2364 2229 2783 2842 2842 2923 2902 2990 2828 2871 2772 2723 2639 2558 2424 2315 2169 2094 2064 1964 1865 1739 1680 1624 1548 1457 1424 1408 1434 1451 1492 1528 1597 1755 1951 2147 2367 2648 2986 3236 3393 3596 3665 3786 3879 3915 3926 3994 3987 4017 4026 4112 4067 4125 4139 4121 4050 4040 4095 +const double ColorTemp::ColorReduuden[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2288, 0.1861, 0.2364, 0.2229, 0.2783, 0.2842, 0.2842, 0.2923, 0.2902, 0.2990, 0.2828, 0.2871, 0.2772, 0.2723, 0.2639, 0.2558, 0.2424, 0.2315, 0.2169, 0.2094, 0.2064, + 0.1964, 0.1865, 0.1739, 0.1680, 0.1624, 0.1548, 0.1457, 0.1424, 0.1408, 0.1434, 0.1451, 0.1492, 0.1528, 0.1597, 0.1755, 0.1951, 0.2147, 0.2367, 0.2648, 0.2986, 0.3236, + 0.3393, 0.3596, 0.3665, 0.3786, 0.3879, 0.3915, 0.3926, 0.3994, 0.3987, 0.4017, 0.4026, 0.4112, 0.4067, 0.4125, 0.4139, 0.4121, 0.4050, 0.4040, 0.4095, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//#red flower (pajuangervo) +//445 1024 605 833 937 959 1052 1028 1049 1029 1017 975 948 882 865 812 757 718 658 638 628 597 554 523 509 509 485 475 469 492 479 477 490 525 555 597 641 704 756 846 948 1055 1164 1221 1266 1339 1393 1491 1553 1604 1608 1650 1643 1652 1655 1658 1651 1739 1813 1818 1938 +const double ColorTemp::ColorRedpajuan[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0445, 0.1024, 0.0605, 0.0833, 0.0937, 0.0959, 0.1052, 0.1028, 0.1049, 0.1029, 0.1017, 0.0975, 0.0948, 0.0882, 0.0865, 0.0812, 0.0757, 0.0718, 0.0658, 0.0638, 0.0628, 0.0597, + 0.0554, 0.0523, 0.0509, 0.0509, 0.0485, 0.0475, 0.0469, 0.0492, 0.0479, 0.0477, 0.0490, 0.0525, 0.0555, 0.0597, 0.0641, 0.0704, 0.0756, 0.0846, 0.0948, 0.1055, 0.1164, 0.1221, + 0.1266, 0.1339, 0.1393, 0.1491, 0.1553, 0.1604, 0.1608, 0.1650, 0.1643, 0.1652, 0.1655, 0.1658, 0.1651, 0.1739, 0.1813, 0.1818, 0.1938, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//#red flower (jaloangervo) +//120 152 512 635 662 538 749 713 743 792 777 785 733 726 728 749 709 674 661 657 645 635 598 570 553 544 545 538 546 514 540 567 585 577 602 651 690 765 836 907 980 1089 1147 1188 1212 1253 1318 1371 1412 1473 1459 1478 1548 1582 1564 1590 1595 1714 1728 1814 1837 +const double ColorTemp::ColorRedjaloan[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0120, 0.0152, 0.0512, 0.0635, 0.0662, 0.0538, 0.0749, 0.0713, 0.0743, 0.0792, 0.0777, 0.0785, 0.0733, 0.0726, 0.0728, 0.0749, 0.0709, 0.0674, 0.0661, 0.0657, 0.0645, 0.0635, + 0.0598, 0.0570, 0.0553, 0.0544, 0.0545, 0.0538, 0.0546, 0.0514, 0.0540, 0.0567, 0.0585, 0.0577, 0.0602, 0.0651, 0.0690, 0.0765, 0.0836, 0.0907, 0.0980, 0.1089, 0.1147, 0.1188, + 0.1212, 0.1253, 0.1318, 0.1371, 0.1412, 0.1473, 0.1459, 0.1478, 0.1548, 0.1582, 0.1564, 0.1590, 0.1595, 0.1714, 0.1728, 0.1814, 0.1837, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//#blue flower (ukonhattu) +//801 682 1070 1319 1311 1420 1453 1394 1318 1292 1268 1179 1132 1054 1015 948 846 780 731 709 705 667 621 598 555 522 505 493 498 500 494 471 479 463 450 461 487 515 546 574 555 562 539 558 546 552 567 626 715 807 862 978 1086 1199 1313 1323 1350 1366 1358 1320 1365 +const double ColorTemp::ColorBlueukon[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0801, 0.0682, 0.1070, 0.1319, 0.1311, 0.1420, 0.1453, 0.1394, 0.1318, 0.1292, 0.1268, 0.1179, 0.1132, 0.1054, 0.1015, 0.0948, 0.0846, 0.0780, 0.0731, 0.0709, 0.0705, 0.0667, + 0.0621, 0.0598, 0.0555, 0.0522, 0.0505, 0.0493, 0.0498, 0.0500, 0.0494, 0.0471, 0.0479, 0.0463, 0.0450, 0.0461, 0.0487, 0.0515, 0.0546, 0.0574, 0.0555, 0.0562, 0.0539, 0.0558, + 0.0546, 0.0552, 0.0567, 0.0626, 0.0715, 0.0807, 0.0862, 0.0978, 0.1086, 0.1199, 0.1313, 0.1323, 0.1350, 0.1366, 0.1358, 0.1320, 0.1365, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//#blue flower (orvokki) +//292 528 645 1000 932 1439 1752 1947 2077 2158 2169 2153 2164 2132 2091 1993 1916 1876 1803 1702 1659 1554 1503 1425 1330 1229 1186 1134 1065 1031 1014 993 989 980 939 936 945 995 1055 1104 1180 1247 1284 1343 1349 1403 1458 1538 1634 1790 1880 2006 2218 2396 2556 2612 2735 2811 2765 2840 2877 +const double ColorTemp::ColorBlueorvokki[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0292, 0.0528, 0.0645, 0.1000, 0.0932, 0.1439, 0.1752, 0.1947, 0.2077, 0.2158, 0.2169, 0.2153, 0.2164, 0.2132, 0.2091, 0.1993, 0.1916, 0.1876, 0.1803, 0.1702, 0.1659, 0.1554, + 0.1503, 0.1425, 0.1330, 0.1229, 0.1186, 0.1134, 0.1065, 0.1031, 0.1014, 0.0993, 0.0989, 0.0980, 0.0939, 0.0936, 0.0945, 0.0995, 0.1055, 0.1104, 0.1180, 0.1247, 0.1284, 0.1343, + 0.1349, 0.1403, 0.1458, 0.1538, 0.1634, 0.1790, 0.1880, 0.2006, 0.2218, 0.2396, 0.2556, 0.2612, 0.2735, 0.2811, 0.2765, 0.2840, 0.2877, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//#blue flower (malvikki) +//1062 528 749 571 512 538 455 445 431 384 353 299 249 212 190 162 123 105 90 81 83 75 78 72 59 56 61 54 71 69 70 62 63 65 70 74 78 73 76 87 90 104 119 119 131 145 156 184 225 255 314 414 538 669 849 1068 1247 1467 1701 1885 2032 +const double ColorTemp::ColorBluemalvikki[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1062, 0.0528, 0.0749, 0.0571, 0.0512, 0.0538, 0.0455, 0.0445, 0.0431, 0.0384, 0.0353, 0.0299, 0.0249, 0.0212, 0.0190, 0.0162, 0.0123, 0.0105, 0.0090, 0.0081, 0.0083, 0.0075, + 0.0078, 0.0072, 0.0059, 0.0056, 0.0061, 0.0054, 0.0071, 0.0069, 0.0070, 0.0062, 0.0063, 0.0065, 0.0070, 0.0074, 0.0078, 0.0073, 0.0076, 0.0087, 0.0090, 0.0104, 0.0119, 0.0119, + 0.0131, 0.0145, 0.0156, 0.0184, 0.0225, 0.0255, 0.0314, 0.0414, 0.0538, 0.0669, 0.0849, 0.1068, 0.1247, 0.1467, 0.1701, 0.1885, 0.2032, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#black dry leaf (maitohorsma) +//256 0 172 356 213 270 203 203 195 208 202 201 210 210 203 204 209 203 209 201 205 201 194 210 206 197 203 198 207 201 204 202 198 200 198 197 186 203 202 198 200 208 206 231 235 223 244 254 278 289 297 309 338 335 338 368 412 524 686 926 1185 +const double ColorTemp::ColorBlackmaito[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0256, 0.0, 0.0172, 0.0356, 0.0213, 0.0270, 0.0203, 0.0203, 0.0195, 0.0208, 0.0202, 0.0201, 0.0210, 0.0210, 0.0203, 0.0204, 0.0209, 0.0203, 0.0209, 0.0201, 0.0205, 0.0201, + 0.0194, 0.0210, 0.0206, 0.0197, 0.0203, 0.0198, 0.0207, 0.0201, 0.0204, 0.0202, 0.0198, 0.0200, 0.0198, 0.0197, 0.0186, 0.0203, 0.0202, 0.0198, 0.0200, 0.0208, 0.0206, 0.0231, + 0.0235, 0.0223, 0.0244, 0.0254, 0.0278, 0.0289, 0.0297, 0.0309, 0.0338, 0.0335, 0.0338, 0.0368, 0.0412, 0.0524, 0.0686, 0.0926, 0.1185, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//#orange berry (pihlaja) +//945 731 585 433 247 408 266 314 293 305 289 288 280 297 262 298 277 274 291 293 285 303 300 310 324 336 364 377 426 465 499 561 602 667 741 890 1028 1164 1275 1465 1602 1640 1695 1744 1812 1837 1859 1805 1791 1822 1796 1751 1715 1655 1575 1600 1560 1618 1666 1740 1838 +const double ColorTemp::ColorOrangpihlaja[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0945, 0.0731, 0.0585, 0.0433, 0.0247, 0.0408, 0.0266, 0.0314, 0.0293, 0.0305, 0.0289, 0.0288, 0.0280, 0.0297, 0.0262, 0.0298, 0.0277, 0.0274, 0.0291, 0.0293, 0.0285, 0.0303, + 0.0300, 0.0310, 0.0324, 0.0336, 0.0364, 0.0377, 0.0426, 0.0465, 0.0499, 0.0561, 0.0602, 0.0667, 0.0741, 0.0890, 0.1028, 0.1164, 0.1275, 0.1465, 0.1602, 0.1640, 0.1695, 0.1744, + 0.1812, 0.1837, 0.1859, 0.1805, 0.1791, 0.1822, 0.1796, 0.1751, 0.1715, 0.1655, 0.1575, 0.1600, 0.1560, 0.1618, 0.1666, 0.1740, 0.1838, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#green flower (lehmus=linden) +//2677 1682 1170 1032 1085 816 728 755 833 832 813 845 857 884 855 882 914 997 1084 1179 1231 1437 1661 1873 2048 2209 2378 2408 2442 2509 2503 2452 2457 2418 2383 2348 2277 2213 2221 2169 2146 2048 1977 1960 2000 1993 1961 1899 1784 1748 1625 1517 1389 1260 1165 1143 1244 1522 1870 2324 2586 +//RIS 81 +const double ColorTemp::ColorGreenlinden[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2677, 0.1682, 0.1170, 0.1032, 0.1085, 0.0816, 0.0728, 0.0755, 0.0833, 0.0832, 0.0813, 0.0845, 0.0857, 0.0884, 0.0855, 0.0882, 0.0914, 0.0997, 0.1084, 0.1179, 0.1231, 0.1437, + 0.1661, 0.1873, 0.2048, 0.2209, 0.2378, 0.2408, 0.2442, 0.2509, 0.2503, 0.2452, 0.2457, 0.2418, 0.2383, 0.2348, 0.2277, 0.2213, 0.2221, 0.2169, 0.2146, 0.2048, 0.1977, 0.1960, + 0.2000, 0.1993, 0.1961, 0.1899, 0.1784, 0.1748, 0.1625, 0.1517, 0.1389, 0.1260, 0.1165, 0.1143, 0.1244, 0.1522, 0.1870, 0.2324, 0.2586, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#yellow petal (lehmus) +//1890 1097 900 832 814 799 758 853 803 808 833 862 916 943 960 969 1039 1162 1283 1370 1427 1529 1689 1781 1894 1950 2105 2118 2140 2185 2191 2199 2234 2266 2263 2297 2328 2312 2298 2332 2344 2312 2288 2347 2384 2390 2358 2280 2306 2315 2310 2253 2274 2271 2242 2292 2254 2208 2319 2314 2264 +const double ColorTemp::ColorYellowlehmus[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1890, 0.1097, 0.0900, 0.0832, 0.0814, 0.0799, 0.0758, 0.0853, 0.0803, 0.0808, 0.0833, 0.0862, 0.0916, 0.0943, 0.0960, 0.0969, 0.1039, 0.1162, 0.1283, 0.1370, 0.1427, + 0.1529, 0.1689, 0.1781, 0.1894, 0.1950, 0.2105, 0.2118, 0.2140, 0.2185, 0.2191, 0.2199, 0.2234, 0.2266, 0.2263, 0.2297, 0.2328, 0.2312, 0.2298, 0.2332, 0.2344, 0.2312, 0.2288, + 0.2347, 0.2384, 0.2390, 0.2358, 0.2280, 0.2306, 0.2315, 0.2310, 0.2253, 0.2274, 0.2271, 0.2242, 0.2292, 0.2254, 0.2208, 0.2319, 0.2314, 0.2264, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#yellow flower (suikeroalpi) +//2048 1666 1140 1210 699 680 615 566 567 561 609 585 614 572 599 575 636 730 982 1194 1360 1766 2222 2558 2849 3048 3201 3395 3395 3484 3576 3623 3606 3672 3651 3634 3647 3669 3715 3660 3720 3692 3704 3784 3683 3731 3681 3697 3635 3694 3617 3610 3632 3663 3616 3595 3599 3584 3588 3613 3527 +const double ColorTemp::ColorYellowsuikeroalpi[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2048, 0.1666, 0.1140, 0.1210, 0.0699, 0.0680, 0.0615, 0.0566, 0.0567, 0.0561, 0.0609, 0.0585, 0.0614, 0.0572, 0.0599, 0.0575, 0.0636, 0.0730, 0.0982, 0.1194, 0.1360, 0.1766, + 0.2222, 0.2558, 0.2849, 0.3048, 0.3201, 0.3395, 0.3395, 0.3484, 0.3576, 0.3623, 0.3606, 0.3672, 0.3651, 0.3634, 0.3647, 0.3669, 0.3715, 0.3660, 0.3720, 0.3692, 0.3704, 0.3784, + 0.3683, 0.3731, 0.3681, 0.3697, 0.3635, 0.3694, 0.3617, 0.3610, 0.3632, 0.3663, 0.3616, 0.3595, 0.3599, 0.3584, 0.3588, 0.3613, 0.3527, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#yellow flower (pensashanhikki) +//356 1365 1024 902 535 387 355 247 365 307 321 330 319 332 317 336 408 487 709 963 1235 1631 2111 2436 2718 2950 3151 3262 3313 3420 3448 3475 3491 3534 3520 3565 3622 3631 3626 3657 3640 3607 3641 3627 3601 3591 3588 3667 3618 3601 3630 3613 3592 3609 3569 3590 3568 3563 3588 3480 3471 +const double ColorTemp::ColorYellowpensashanhikki1[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0356, 0.1365, 0.1024, 0.0902, 0.0535, 0.0387, 0.0355, 0.0247, 0.0365, 0.0307, 0.0321, 0.0330, 0.0319, 0.0332, 0.0317, 0.0336, 0.0408, 0.0487, 0.0709, 0.0963, 0.1235, + 0.1631, 0.2111, 0.2436, 0.2718, 0.2950, 0.3151, 0.3262, 0.3313, 0.3420, 0.3448, 0.3475, 0.3491, 0.3534, 0.3520, 0.3565, 0.3622, 0.3631, 0.3626, 0.3657, 0.3640, 0.3607, + 0.3641, 0.3627, 0.3601, 0.3591, 0.3588, 0.3667, 0.3618, 0.3601, 0.3630, 0.3613, 0.3592, 0.3609, 0.3569, 0.3590, 0.3568, 0.3563, 0.3588, 0.3480, 0.3471, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#yellow sepal (pensashanhikki) +//1068 427 326 416 428 590 503 470 539 526 546 540 539 526 497 546 555 603 753 903 1010 1268 1563 1868 2068 2226 2429 2495 2560 2625 2636 2610 2655 2667 2635 2630 2612 2560 2597 2588 2543 2478 2499 2472 2438 2431 2379 2406 2361 2319 2264 2174 2128 2010 1942 1912 1930 2148 2334 2585 2764 +const double ColorTemp::ColorYellowpensashanhikki2[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1068, 0.0427, 0.0326, 0.0416, 0.0428, 0.0590, 0.0503, 0.0470, 0.0539, 0.0526, 0.0546, 0.0540, 0.0539, 0.0526, 0.0497, 0.0546, 0.0555, 0.0603, 0.0753, 0.0903, 0.1010, 0.1268, + 0.1563, 0.1868, 0.2068, 0.2226, 0.2429, 0.2495, 0.2560, 0.2625, 0.2636, 0.2610, 0.2655, 0.2667, 0.2635, 0.2630, 0.2612, 0.2560, 0.2597, 0.2588, 0.2543, 0.2478, 0.2499, 0.2472, + 0.2438, 0.2431, 0.2379, 0.2406, 0.2361, 0.2319, 0.2264, 0.2174, 0.2128, 0.2010, 0.1942, 0.1912, 0.1930, 0.2148, 0.2334, 0.2585, 0.2764, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#blue flower (hiidenvirna) +//315 512 675 832 765 865 807 867 911 904 852 826 780 753 711 661 595 528 513 476 431 391 361 331 305 276 240 229 237 223 212 208 215 205 203 195 209 212 222 266 296 322 356 352 388 391 411 425 473 532 550 630 669 748 823 879 904 917 930 950 942 +const double ColorTemp::ColorBluehiidenvirna[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0315, 0.0512, 0.0675, 0.0832, 0.0765, 0.0865, 0.0807, 0.0867, 0.0911, 0.0904, 0.0852, 0.0826, 0.0780, 0.0753, 0.0711, 0.0661, 0.0595, 0.0528, 0.0513, 0.0476, 0.0431, 0.0391, + 0.0361, 0.0331, 0.0305, 0.0276, 0.0240, 0.0229, 0.0237, 0.0223, 0.0212, 0.0208, 0.0215, 0.0205, 0.0203, 0.0195, 0.0209, 0.0212, 0.0222, 0.0266, 0.0296, 0.0322, 0.0356, 0.0352, + 0.0388, 0.0391, 0.0411, 0.0425, 0.0473, 0.0532, 0.0550, 0.0630, 0.0669, 0.0748, 0.0823, 0.0879, 0.0904, 0.0917, 0.0930, 0.0950, 0.0942, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#blue flower (kurkkuyrtti) +//2687 1553 2181 2246 2209 2263 2442 2347 2261 2353 2292 2230 2095 2008 1896 1782 1569 1443 1333 1223 1177 1074 992 902 813 755 701 626 577 548 525 498 469 445 456 448 428 441 448 447 455 467 496 534 527 586 668 798 966 1126 1289 1469 1679 1870 2013 2040 2060 2077 2104 2155 2119 +//RIS 87 +const double ColorTemp::ColorBluekurkkuyrtti[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2687, 0.1553, 0.2181, 0.2246, 0.2209, 0.2263, 0.2442, 0.2347, 0.2261, 0.2353, 0.2292, 0.2230, 0.2095, 0.2008, 0.1896, 0.1782, 0.1569, 0.1443, 0.1333, 0.1223, 0.1177, 0.1074, + 0.0992, 0.0902, 0.0813, 0.0755, 0.0701, 0.0626, 0.0577, 0.0548, 0.0525, 0.0498, 0.0469, 0.0445, 0.0456, 0.0448, 0.0428, 0.0441, 0.0448, 0.0447, 0.0455, 0.0467, 0.0496, 0.0534, + 0.0527, 0.0586, 0.0668, 0.0798, 0.0966, 0.1126, 0.1289, 0.1469, 0.1679, 0.1870, 0.2013, 0.2040, 0.2060, 0.2077, 0.2104, 0.2155, 0.2119, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#pink (siankaersaemoe) +//585 859 758 1094 780 1012 987 1067 1059 1034 1098 1110 1097 1040 1058 1048 1028 1014 1068 1024 1023 1025 1032 1029 1011 1007 986 973 946 906 949 923 943 949 956 998 1051 1107 1166 1242 1284 1355 1394 1438 1451 1543 1589 1588 1612 1616 1562 1534 1562 1541 1494 1492 1518 1650 1749 1907 1991 +const double ColorTemp::ColorPinksiankaersaemoe[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0585, 0.0859, 0.0758, 0.1094, 0.0780, 0.1012, 0.0987, 0.1067, 0.1059, 0.1034, 0.1098, 0.1110, 0.1097, 0.1040, 0.1058, 0.1048, 0.1028, 0.1014, 0.1068, 0.1024, 0.1023, 0.1025, + 0.1032, 0.1029, 0.1011, 0.1007, 0.0986, 0.0973, 0.0946, 0.0906, 0.0949, 0.0923, 0.0943, 0.0949, 0.0956, 0.0998, 0.1051, 0.1107, 0.1166, 0.1242, 0.1284, 0.1355, 0.1394, 0.1438, + 0.1451, 0.1543, 0.1589, 0.1588, 0.1612, 0.1616, 0.1562, 0.1534, 0.1562, 0.1541, 0.1494, 0.1492, 0.1518, 0.1650, 0.1749, 0.1907, 0.1991, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//#violet flower (harakankello) +//2520 1462 1890 1898 1751 1713 1555 1516 1471 1403 1282 1209 1144 1135 1069 976 895 823 782 762 713 685 661 635 603 559 551 550 541 567 562 574 580 589 586 620 670 690 718 801 786 769 773 739 800 806 837 845 971 1043 1102 1241 1359 1502 1611 1726 1793 1859 1909 1969 2014 +//RIS 89 +const double ColorTemp::ColorVioletharakankello[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2520, 0.1462, 0.1890, 0.1898, 0.1751, 0.1713, 0.1555, 0.1516, 0.1471, 0.1403, 0.1282, 0.1209, 0.1144, 0.1135, 0.1069, 0.0976, 0.0895, 0.0823, 0.0782, 0.0762, 0.0713, + 0.0685, 0.0661, 0.0635, 0.0603, 0.0559, 0.0551, 0.0550, 0.0541, 0.0567, 0.0562, 0.0574, 0.0580, 0.0589, 0.0586, 0.0620, 0.0670, 0.0690, 0.0718, 0.0801, 0.0786, 0.0769, + 0.0773, 0.0739, 0.0800, 0.0806, 0.0837, 0.0845, 0.0971, 0.1043, 0.1102, 0.1241, 0.1359, 0.1502, 0.1611, 0.1726, 0.1793, 0.1859, 0.1909, 0.1969, 0.2014, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#violet flower (alsikeapila) +//1260 585 765 1065 937 881 847 943 1075 1053 1020 994 1008 1026 1015 980 962 949 925 908 880 864 843 814 802 749 698 691 677 660 653 660 631 633 644 692 743 809 889 1005 1160 1325 1396 1450 1526 1583 1655 1674 1689 1707 1675 1674 1624 1576 1564 1591 1613 1717 1851 1962 2033 +const double ColorTemp::ColorVioletalsikeapila[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1260, 0.0585, 0.0765, 0.1065, 0.0937, 0.0881, 0.0847, 0.0943, 0.1075, 0.1053, 0.1020, 0.0994, 0.1008, 0.1026, 0.1015, 0.0980, 0.0962, 0.0949, 0.0925, 0.0908, 0.0880, 0.0864, + 0.0843, 0.0814, 0.0802, 0.0749, 0.0698, 0.0691, 0.0677, 0.0660, 0.0653, 0.0660, 0.0631, 0.0633, 0.0644, 0.0692, 0.0743, 0.0809, 0.0889, 0.1005, 0.1160, 0.1325, 0.1396, 0.1450, + 0.1526, 0.1583, 0.1655, 0.1674, 0.1689, 0.1707, 0.1675, 0.1674, 0.1624, 0.1576, 0.1564, 0.1591, 0.1613, 0.1717, 0.1851, 0.1962, 0.2033, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#violet flower (akilleija) +//843 1340 1393 1254 1290 1452 1508 1519 1454 1384 1301 1256 1178 1113 1056 985 884 827 743 720 691 664 605 578 540 507 499 475 485 494 492 479 487 493 471 495 559 595 645 689 720 732 716 723 734 750 804 849 948 1041 1169 1362 1525 1693 1761 1935 2071 2235 2376 2493 2604 +const double ColorTemp::ColorVioletakilleija[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0843, 0.1340, 0.1393, 0.1254, 0.1290, 0.1452, 0.1508, 0.1519, 0.1454, 0.1384, 0.1301, 0.1256, 0.1178, 0.1113, 0.1056, 0.0985, 0.0884, 0.0827, 0.0743, 0.0720, 0.0691, 0.0664, + 0.0605, 0.0578, 0.0540, 0.0507, 0.0499, 0.0475, 0.0485, 0.0494, 0.0492, 0.0479, 0.0487, 0.0493, 0.0471, 0.0495, 0.0559, 0.0595, 0.0645, 0.0689, 0.0720, 0.0732, 0.0716, 0.0723, + 0.0734, 0.0750, 0.0804, 0.0849, 0.0948, 0.1041, 0.1169, 0.1362, 0.1525, 0.1693, 0.1761, 0.1935, 0.2071, 0.2235, 0.2376, 0.2493, 0.2604, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#orange flower (kehaekukka) +//0 0 0 0 0 0 102 58 128 125 137 122 122 134 123 136 159 138 163 151 167 178 192 177 206 226 315 451 707 1045 1446 1707 1944 2131 2276 2524 2719 2841 2968 3052 3199 3264 3282 3429 3451 3454 3477 3556 3478 3565 3595 3569 3582 3582 3559 3610 3626 3668 3733 3692 3722 +const double ColorTemp::ColorOrangekehaekukka[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0102, 0.0058, 0.0128, 0.0125, 0.0137, 0.0122, 0.0122, 0.0134, 0.0123, 0.0136, 0.0159, 0.0138, 0.0163, 0.0151, 0.0167, 0.0178, 0.0192, + 0.0177, 0.0206, 0.0226, 0.0315, 0.0451, 0.0707, 0.1045, 0.1446, 0.1707, 0.1944, 0.2131, 0.2276, 0.2524, 0.2719, 0.2841, 0.2968, 0.3052, 0.3199, 0.3264, 0.3282, 0.3429, + 0.3451, 0.3454, 0.3477, 0.3556, 0.3478, 0.3565, 0.3595, 0.3569, 0.3582, 0.3582, 0.3559, 0.3610, 0.3626, 0.3668, 0.3733, 0.3692, 0.3722, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#red berry (pihlaja) +//0 0 0 0 25 84 128 87 165 130 167 147 155 146 148 165 158 159 164 160 158 158 157 157 173 173 179 195 210 234 264 302 349 386 461 572 735 886 1038 1216 1376 1521 1607 1691 1728 1769 1842 1843 1865 1910 1881 1920 1909 1909 1891 1879 1915 1879 1878 1843 1832 +const double ColorTemp::ColorRedpihlaja[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0025, 0.0084, 0.0128, 0.0087, 0.0165, 0.0130, 0.0167, 0.0147, 0.0155, 0.0146, 0.0148, 0.0165, 0.0158, 0.0159, 0.0164, 0.0160, 0.0158, 0.0158, + 0.0157, 0.0157, 0.0173, 0.0173, 0.0179, 0.0195, 0.0210, 0.0234, 0.0264, 0.0302, 0.0349, 0.0386, 0.0461, 0.0572, 0.0735, 0.0886, 0.1038, 0.1216, 0.1376, 0.1521, 0.1607, 0.1691, + 0.1728, 0.1769, 0.1842, 0.1843, 0.1865, 0.1910, 0.1881, 0.1920, 0.1909, 0.1909, 0.1891, 0.1879, 0.1915, 0.1879, 0.1878, 0.1843, 0.1832, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//#violet flower (petunia) +//292 66 227 313 325 332 310 319 300 268 229 193 164 137 127 104 67 50 49 37 34 34 44 32 33 31 38 41 33 34 45 44 37 42 44 49 49 67 80 89 110 130 137 145 153 171 194 223 275 321 391 464 580 720 907 1055 1230 1436 1548 1777 1933 +//RIS 94 +const double ColorTemp::ColorVioletpetunia[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0292, 0.0066, 0.0227, 0.0313, 0.0325, 0.0332, 0.0310, 0.0319, 0.0300, 0.0268, 0.0229, 0.0193, 0.0164, 0.0137, 0.0127, 0.0104, 0.0067, 0.0050, 0.0049, 0.0037, 0.0034, 0.0034, + 0.0044, 0.0032, 0.0033, 0.0031, 0.0038, 0.0041, 0.0033, 0.0034, 0.0045, 0.0044, 0.0037, 0.0042, 0.0044, 0.0049, 0.0049, 0.0067, 0.0080, 0.0089, 0.0110, 0.0130, 0.0137, 0.0145, + 0.0153, 0.0171, 0.0194, 0.0223, 0.0275, 0.0321, 0.0391, 0.0464, 0.0580, 0.0720, 0.0907, 0.1055, 0.1230, 0.1436, 0.1548, 0.1777, 0.1933, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#violet flower (orvokki) +//195 0 152 31 22 32 77 69 45 20 27 26 13 12 14 11 15 23 16 18 16 12 16 10 16 15 13 15 15 16 14 20 14 17 15 17 15 17 17 17 23 24 29 38 36 38 37 43 58 65 70 86 113 155 222 285 405 506 645 817 1035 +const double ColorTemp::ColorVioletorvokki[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0195, 0.0, 0.0152, 0.0031, 0.0022, 0.0032, 0.0077, 0.0069, 0.0045, 0.0020, 0.0027, 0.0026, 0.0013, 0.0012, 0.0014, 0.0011, 0.0015, 0.0023, 0.0016, 0.0018, 0.0016, 0.0012, 0.0016, + 0.0010, 0.0016, 0.0015, 0.0013, 0.0015, 0.0015, 0.0016, 0.0014, 0.0020, 0.0014, 0.0017, 0.0015, 0.0017, 0.0015, 0.0017, 0.0017, 0.0017, 0.0023, 0.0024, 0.0029, 0.0038, 0.0036, + 0.0038, 0.0037, 0.0043, 0.0058, 0.0065, 0.0070, 0.0086, 0.0113, 0.0155, 0.0222, 0.0285, 0.0405, 0.0506, 0.0645, 0.0817, 0.1035, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//#blue flower (sinisievikki) +//801 1109 1861 2325 2329 2380 2562 2565 2558 2611 2517 2567 2475 2397 2337 2294 2195 2001 1881 1892 1854 1746 1668 1580 1491 1362 1229 1178 1110 1094 1072 1019 994 960 928 879 836 859 863 951 1046 1102 1154 1193 1174 1166 1153 1199 1275 1316 1376 1550 1739 1918 2104 2228 2364 2377 2423 2394 2334 +const double ColorTemp::ColorBluesinisievikki[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0801, 0.1109, 0.1861, 0.2325, 0.2329, 0.2380, 0.2562, 0.2565, 0.2558, 0.2611, 0.2517, 0.2567, 0.2475, 0.2397, 0.2337, 0.2294, 0.2195, 0.2001, 0.1881, 0.1892, 0.1854, 0.1746, + 0.1668, 0.1580, 0.1491, 0.1362, 0.1229, 0.1178, 0.1110, 0.1094, 0.1072, 0.1019, 0.0994, 0.0960, 0.0928, 0.0879, 0.0836, 0.0859, 0.0863, 0.0951, 0.1046, 0.1102, 0.1154, 0.1193, + 0.1174, 0.1166, 0.1153, 0.1199, 0.1275, 0.1316, 0.1376, 0.1550, 0.1739, 0.1918, 0.2104, 0.2228, 0.2364, 0.2377, 0.2423, 0.2394, 0.2334, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#blue flower (iisoppi) +//623 85 605 833 776 756 755 781 774 775 697 724 697 654 617 575 536 494 460 469 442 436 400 393 380 358 369 352 342 368 357 360 342 342 341 335 355 353 365 376 382 392 412 412 407 414 420 449 487 504 517 571 651 734 806 885 968 1088 1210 1296 1411 +const double ColorTemp::ColorBlueiisoppi[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0623, 0.0085, 0.0605, 0.0833, 0.0776, 0.0756, 0.0755, 0.0781, 0.0774, 0.0775, 0.0697, 0.0724, 0.0697, 0.0654, 0.0617, 0.0575, 0.0536, 0.0494, 0.0460, 0.0469, 0.0442, 0.0436, + 0.0400, 0.0393, 0.0380, 0.0358, 0.0369, 0.0352, 0.0342, 0.0368, 0.0357, 0.0360, 0.0342, 0.0342, 0.0341, 0.0335, 0.0355, 0.0353, 0.0365, 0.0376, 0.0382, 0.0392, 0.0412, 0.0412, + 0.0407, 0.0414, 0.0420, 0.0449, 0.0487, 0.0504, 0.0517, 0.0571, 0.0651, 0.0734, 0.0806, 0.0885, 0.0968, 0.1088, 0.1210, 0.1296, 0.1411, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//#white petal (ojakaersaemoe) +//1732 951 1800 1365 1801 1697 1762 2103 2243 2218 2200 2206 2255 2254 2269 2261 2272 2251 2254 2260 2256 2266 2247 2269 2310 2273 2345 2312 2301 2323 2302 2314 2362 2355 2348 2362 2396 2374 2362 2381 2396 2440 2383 2347 2422 2419 2472 2423 2406 2425 2377 2381 2380 2398 2390 2404 2370 2375 2364 2411 2417 +const double ColorTemp::ColorWhiteojaka[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1732, 0.0951, 0.1800, 0.1365, 0.1801, 0.1697, 0.1762, 0.2103, 0.2243, 0.2218, 0.2200, 0.2206, 0.2255, 0.2254, 0.2269, 0.2261, 0.2272, 0.2251, 0.2254, 0.2260, 0.2256, 0.2266, + 0.2247, 0.2269, 0.2310, 0.2273, 0.2345, 0.2312, 0.2301, 0.2323, 0.2302, 0.2314, 0.2362, 0.2355, 0.2348, 0.2362, 0.2396, 0.2374, 0.2362, 0.2381, 0.2396, 0.2440, 0.2383, 0.2347, + 0.2422, 0.2419, 0.2472, 0.2423, 0.2406, 0.2425, 0.2377, 0.2381, 0.2380, 0.2398, 0.2390, 0.2404, 0.2370, 0.2375, 0.2364, 0.2411, 0.2417, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//#white flower (petunia) +//4095 4022 4410 4095 4095 4095 4193 4207 4388 4328 4223 4168 4221 4304 4245 4210 4212 4192 4181 4233 4207 4224 4197 4262 4243 4241 4274 4257 4204 4285 4265 4241 4267 4275 4245 4276 4260 4217 4217 4244 4240 4186 4160 4156 4227 4286 4237 4137 4202 4187 4100 4112 4103 4090 4125 4115 4098 4036 4047 4105 4050 +const double ColorTemp::ColorWhitepetunia[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.4095, 0.4022, 0.4410, 0.4095, 0.4095, 0.4095, 0.4193, 0.4207, 0.4388, 0.4328, 0.4223, 0.4168, 0.4221, 0.4304, 0.4245, 0.4210, 0.4212, 0.4192, 0.4181, 0.4233, 0.4207, 0.4224, + 0.4197, 0.4262, 0.4243, 0.4241, 0.4274, 0.4257, 0.4204, 0.4285, 0.4265, 0.4241, 0.4267, 0.4275, 0.4245, 0.4276, 0.4260, 0.4217, 0.4217, 0.4244, 0.4240, 0.4186, 0.4160, 0.4156, + 0.4227, 0.4286, 0.4237, 0.4137, 0.4202, 0.4187, 0.4100, 0.4112, 0.4103, 0.4090, 0.4125, 0.4115, 0.4098, 0.4036, 0.4047, 0.4105, 0.4050, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + + +//#blue flower (lobelia dortmanna) +//0 660 1277 1544 1612 1961 1909 1950 1901 1907 1809 1785 1685 1622 1522 1377 1178 1054 931 898 850 732 610 508 434 370 343 329 303 265 232 199 183 169 172 177 200 233 214 214 199 186 199 228 249 321 435 684 1006 1345 1703 2082 2432 2661 2843 2936 3079 3015 3003 3045 3038 +//RIS 98 +const double ColorTemp::ColorBluelobelia[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0660, 0.1277, 0.1544, 0.1612, 0.1961, 0.1909, 0.1950, 0.1901, 0.1907, 0.1809, 0.1785, 0.1685, 0.1622, 0.1522, 0.1377, 0.1178, 0.1054, 0.0931, 0.0898, 0.0850, 0.0732, + 0.0610, 0.0508, 0.0434, 0.0370, 0.0343, 0.0329, 0.0303, 0.0265, 0.0232, 0.0199, 0.0183, 0.0169, 0.0172, 0.0177, 0.0200, 0.0233, 0.0214, 0.0214, 0.0199, 0.0186, 0.0199, + 0.0228, 0.0249, 0.0321, 0.0435, 0.0684, 0.1006, 0.1345, 0.1703, 0.2082, 0.2432, 0.2661, 0.2843, 0.2936, 0.3079, 0.3015, 0.3003, 0.3045, 0.3038, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//#white petal (pelargonia) +//3493 2882 2284 2730 2869 2609 2781 2869 2861 2869 2795 2810 2740 2716 2650 2631 2539 2554 2450 2453 2447 2451 2343 2408 2404 2367 2343 2401 2474 2549 2668 2759 2843 2883 2989 3106 3209 3344 3383 3404 3453 3521 3495 3571 3521 3548 3582 3557 3581 3539 3563 3589 3597 3579 3502 3546 3507 3554 3490 3561 3518 +const double ColorTemp::ColorWhitepelargonia[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3493, 0.2882, 0.2284, 0.2730, 0.2869, 0.2609, 0.2781, 0.2869, 0.2861, 0.2869, 0.2795, 0.2810, 0.2740, 0.2716, 0.2650, 0.2631, 0.2539, 0.2554, 0.2450, 0.2453, 0.2447, + 0.2451, 0.2343, 0.2408, 0.2404, 0.2367, 0.2343, 0.2401, 0.2474, 0.2549, 0.2668, 0.2759, 0.2843, 0.2883, 0.2989, 0.3106, 0.3209, 0.3344, 0.3383, 0.3404, 0.3453, 0.3521, + 0.3495, 0.3571, 0.3521, 0.3548, 0.3582, 0.3557, 0.3581, 0.3539, 0.3563, 0.3589, 0.3597, 0.3579, 0.3502, 0.3546, 0.3507, 0.3554, 0.3490, 0.3561, 0.3518, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +/* +#white petal (paeivaenkakkara) +2168 1365 1969 2095 2231 2530 2944 3092 3107 3148 3188 3207 3195 3216 3225 3261 3211 3228 3260 3237 3258 3276 3265 3316 3327 3291 3315 3324 3355 3255 3264 3308 3324 3328 3282 3253 3220 3257 3289 3265 3245 3297 3284 3292 3228 3312 3290 3277 3278 3284 3182 3244 3273 3291 3212 3256 3154 3243 3306 3234 3155 +*/ +const double ColorTemp::ColorWhitepaeivaen[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2168, 0.1365, 0.1969, 0.2095, 0.2231, 0.2530, 0.2944, 0.3092, 0.3107, 0.3148, 0.3188, 0.3207, 0.3195, 0.3216, 0.3225, 0.3261, 0.3211, 0.3228, 0.3260, 0.3237, 0.3258, + 0.3276, 0.3265, 0.3316, 0.3327, 0.3291, 0.3315, 0.3324, 0.3355, 0.3255, 0.3264, 0.3308, 0.3324, 0.3328, 0.3282, 0.3253, 0.3220, 0.3257, 0.3289, 0.3265, 0.3245, 0.3297, + 0.3284, 0.3292, 0.3228, 0.3312, 0.3290, 0.3277, 0.3278, 0.3284, 0.3182, 0.3244, 0.3273, 0.3291, 0.3212, 0.3256, 0.3154, 0.3243, 0.3306, 0.3234, 0.3155, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + //spectral data Colorchecker24 : Green B3 const double ColorTemp::ColorchechGreB3_spect[97] = { @@ -446,6 +1162,21 @@ const double ColorTemp::ColorchechGraC4_67_spect[97] = { 0.369, 0.3689, 0.368, 0.3673, 0.3678, 0.3684, 0.37, 0.3711, 0.3712, 0.3714, 0.3714, 0.3714, 0.371, 0.3707, 0.37, 0.3694, 0.3697, 0.3703, 0.3697, 0.3692, 0.3688, 0.3685, 0.3675, 0.3669, 0.3657, 0.3647, 0.3635, 0.3625, 0.361, 0.3596, 0.3585, 0.3579, 0.357, 0.3560, 0.3555, 0.3548, 0.3535, 0.3526, 0.3513, 0.3500, 0.349, 0.3475, 0.3467, 0.3460, 0.3452, 0.3444, 0.3431, 0.3421, 0.3411, 0.3403, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; +const double ColorTemp::Fictif_61greyspect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, + 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, + 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::JDC468_K15_87greyspect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1984, 0.2223, 0.2448, 0.2934, 0.3415, 0.4425, 0.5707, 0.6609, 0.7619, 0.7956, 0.8275, 0.8280, 0.8292, 0.8223, 0.8156, 0.8112, 0.8076, 0.8040, 0.7982, 0.7970, 0.7954, 0.8013, 0.8083, 0.8141, 0.8184, 0.8167, + 0.8137, 0.8080, 0.8026, 0.8013, 0.7988, 0.7963, 0.7942, 0.7855, 0.7765, 0.7680, 0.7603, 0.7640, 0.7681, 0.7750, 0.7827, 0.7876, 0.7923, 0.7935, 0.7945, 0.7955, 0.7964, 0.7975, 0.7982, 0.8000, 0.8017, 0.8051, + 0.8090, 0.8145, 0.8191, 0.8234, 0.8269, 0.8300, 0.8327, 0.8342, 0.8359, 0.8375, 0.8390, 0.8405, 0.8421, 0.8436, 0.8452, 0.8480, 0.8504, 0.8564, 0.8611, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + +}; +//K15 275 275 0.1984 0.2448 0.3415 0.5707 0.7619 0.8275 0.8292 0.8156 0.8076 0.7982 0.7954 0.8083 0.8184 0.8137 0.8026 0.7988 0.7942 0.7765 0.7603 0.7681 0.7827 0.7923 0.7945 0.7964 0.7982 0.8017 0.8090 0.8191 0.8269 0.8327 0.8359 0.8390 0.8421 0.8452 0.8504 0.8611 //spectral data Colorchecker24 : Skin B1 //use also for palette WB @@ -478,7 +1209,7 @@ const double ColorTemp::ColorchechDCBluN881_m7_m14_spect[97] = { //spectral data ColorcheckerSG : Skin F7 //use also for palette WB const double ColorTemp::ColorchechSGSkiF763_14_26_spect[97] = { - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0508, 0.64, 0.0776, 0.903, 0.1099, 0.1128, 0.1256, 0.128, 0.1307, 0.133, 0.1357, 0.139, 0.1425, 0.148, 0.1523, 0.159, 0.1669, 0.177, 0.1871, 0.20, 0.2118, 0.2235, 0.2355, 0.2445, 0.2537, 0.259, 0.2655, 0.268, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0508, 0.064, 0.0776, 0.903, 0.1099, 0.1128, 0.1256, 0.128, 0.1307, 0.133, 0.1357, 0.139, 0.1425, 0.148, 0.1523, 0.159, 0.1669, 0.177, 0.1871, 0.20, 0.2118, 0.2235, 0.2355, 0.2445, 0.2537, 0.259, 0.2655, 0.268, 0.2700, 0.2708, 0.2716, 0.2743, 0.2770, 0.2803, 0.2827, 0.283, 0.2832, 0.283, 0.2828, 0.295, 0.3079, 0.344, 0.3803, 0.4105, 0.4409, 0.455, 0.4694, 0.477, 0.4851, 0.4896, 0.4962, 0.501, 0.5066, 0.511, 0.5160, 0.521, 0.5256, 0.529, 0.5318, 0.535, 0.5383, 0.541, 0.5451, 0.549, 0.5524, 0.556, 0.5597, 0.562, 0.5650, 0.568, 0.5709, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; @@ -531,15 +1262,156 @@ const double ColorTemp::JDC468_GraK14_44_spect[97] = { 0.1408, 0.14330, 0.1475, 0.15170, 0.1583, 0.16500, 0.172, 0.17940, 0.1836, 0.18780, 0.188, 0.18820, 0.186, 0.18430, 0.1801, 0.17620, 0.1741, 0.17210, 0.179, 0.18420, 0.1991, 0.21430, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; +const double ColorTemp::JDC468_BluM5_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1510, 0.1802, 0.2069, 0.2550, 0.3047, 0.4055, 0.5069, 0.590, 0.6747, 0.701, 0.7351, 0.7345, 0.7338, 0.7195, 0.7063, 0.693, 0.6732, 0.6490, 0.6261, 0.5993, 0.5723, 0.5560, + 0.5401, 0.526, 0.5106, 0.4805, 0.4504, 0.42, 0.3907, 0.385, 0.3799, 0.3750, 0.3695, 0.3340, 0.3005, 0.2692, 0.2382, 0.2387, 0.2389, 0.2501, 0.2610, 0.2635, 0.2662, 0.2601, 0.2541, + 0.2450, 0.2426, 0.2430, 0.2434, 0.2490, 0.2523, 0.2612, 0.2692, 0.2694, 0.2996, 0.3145, 0.3329, 0.3413, 0.3498, 0.3467, 0.3442, 0.3355, 0.3266, 0.3131, 0.2996, 0.2911, 0.2831, 0.2950, 0.3070, 0.3430, 0.3799, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//m5 317 //0.1510 0.2069 0.3047 0.5069 0.6747 0.7351 0.7338 0.7063 0.6732 0.6261 0.5723 0.5401 +// 0.5106 0.4504 0.3907 0.3799 0.3695 0.3005 0.2382 0.2389 0.2610 0.2662 0.2541 +// 0.2426 0.2434 0.2523 0.2692 0.2996 0.3329 0.3498 0.3442 0.3266 0.2996 0.2831 0.3070 0.3799 + +const double ColorTemp::JDC468_RedG21va_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1207, 0.141, 0.1585, 0.1810, 0.2073, 0.2529, 0.2959, 0.3210, 0.3476, 0.3350, 0.3232, 0.2845, 0.2564, 0.2140, 0.1823, 0.1523, 0.1266, 0.1001, 0.0792, 0.061, 0.0439, 0.0349, 0.0295, 0.0260, 0.0222, + 0.0180, 0.0135, 0.0111, 0.0087, 0.0090, 0.0094, 0.0101, 0.0109, 0.0093, 0.0086, 0.0090, 0.0091, 0.0061, 0.0321, 0.0086, 0.1368, 0.2312, 0.3256, 0.4112, 0.4958, 0.5444, 0.5884, 0.6002, 0.6264, 0.6323, 0.6473, + 0.6546, 0.6659, 0.6775, 0.6881, 0.6982, 0.7081, 0.7150, 0.7201, 0.7217, 0.7232, 0.7222, 0.7215, 0.7187, 0.7157, 0.7144, 0.7131, 0.7196, 0.7269, 0.7303, 0.7599, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//g21 177 0.1207 0.1585 0.2073 0.2959 0.3476 0.3232 0.2564 0.1823 0.1266 0.0792 0.0439 0.0295 0.0222 0.0135 0.0087 0.0094 0.0109 0.0086 0.0091 0.0321 +// 0.1368 0.3256 0.4958 0.5884 0.6264 0.6473 0.6659 0.6881 0.7081 0.7201 0.7232 0.7215 0.7157 0.7131 0.7269 0.7599 +const double ColorTemp::JDC468_RedI9_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0258, 0.023, 0.0220, 0.0205, 0.0189, 0.0183, 0.0174, 0.0168, 0.0162, 0.0152, 0.0148, 0.0145, 0.0139, 0.0136, 0.0133, 0.0130, 0.0127, 0.0130, 0.0133, 0.0151, 0.0168, 0.0218, 0.0268, 0.0317, 0.0367, 0.0330, + 0.0313, 0.0270, 0.0227, 0.0240, 0.0255, 0.0280, 0.0302, 0.0280, 0.0225, 0.0215, 0.0209, 0.0424, 0.0639, 0.1401, 0.2131, 0.3250, 0.4369, 0.5210, 0.6265, 0.6795, 0.7336, 0.7551, 0.7784, 0.7890, 0.7994, 0.8070, + 0.8146, 0.8210, 0.8277, 0.8321, 0.8362, 0.8398, 0.8439, 0.8470, 0.8504, 0.8530, 0.8572, 0.8612, 0.8653, 0.8689, 0.8715, 0.8730, 0.8747, 0.8766, 0.8788, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//I9 RED 217 0.0258 0.0220 0.0189 0.0174 0.0162 0.0148 0.0139 0.0133 0.0127 0.0133 0.0168 0.0268 0.0367 0.0313 0.0227 0.0255 0.0302 0.0225 0.0209 0.0639 0.2131 0.4369 0.6265 0.7336 0.7784 0.7994 0.8146 0.8277 0.8362 0.8439 0.8504 0.8572 0.8653 0.8715 0.8747 0.8788 + +const double ColorTemp::JDC468_YelN10_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0531, 0.0520, 0.0504, 0.0510, 0.0518, 0.0608, 0.0628, 0.0669, 0.0699, 0.0705, 0.0716, 0.0720, 0.0735, 0.0755, 0.0775, 0.0800, 0.0825, 0.0896, 0.0969, 0.1260, 0.1563, 0.2312, 0.3096, 0.4132, 0.5177, 0.5905, 0.6637, + 0.7251, 0.7350, 0.7458, 0.7480, 0.7507, 0.7460, 0.7414, 0.7356, 0.7301, 0.7320, 0.7347, 0.7390, 0.7438, 0.7472, 0.7500, 0.7508, 0.7515, 0.7528, 0.7538, 0.7550, 0.7563, 0.7581, 0.7607, 0.7642, 0.7686, 0.7710, + 0.7791, 0.7840, 0.7872, 0.7902, 0.7935, 0.7955, 0.7979, 0.7995, 0.8021, 0.8035, 0.8058, 0.8072, 0.8090, 0.8110, 0.8143, 0.8198, 0.8259, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//n10 348 0.0531 0.0504 0.0518 0.0628 0.0699 0.0716 0.0735 0.0775 0.0825 0.0969 0.1563 0.3096 0.5177 0.6637 0.7251 0.7458 0.7507 0.7414 0.7301 0.7347 0.7438 0.7500 0.7515 0.7538 0.7563 0.7607 0.7686 0.7791 0.7872 0.7935 0.7979 0.8021 0.8058 0.8090 0.8143 0.8259 +const double ColorTemp::JDC468_GreN7_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0112, 0.0102, 0.0094, 0.0096, 0.0099, 0.0100, 0.0100, 0.0100, 0.0100, 0.0099, 0.0099, 0.0099, 0.0099, 0.0099, 0.0099, 0.0100, 0.0100, 0.0103, 0.0107, 0.0129, 0.0151, 0.0312, 0.0462, 0.1015, 0.1571, 0.2270, 0.2977, + 0.3558, 0.3441, 0.3321, 0.3020, 0.2710, 0.2312, 0.1954, 0.1602, 0.1251, 0.1003, 0.0794, 0.0672, 0.0563, 0.0513, 0.0452, 0.0418, 0.0378, 0.0356, 0.0337, 0.0336, 0.0335, 0.0345, 0.0358, 0.0383, 0.0405, 0.0445, 0.0497, + 0.0612, 0.0647, 0.0670, 0.0660, 0.0644, 0.0620, 0.0574, 0.0525, 0.0483, 0.0460, 0.0436, 0.0484, 0.0532, 0.0690, 0.0870, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//n7 345 0.0112 0.0094 0.0099 0.0100 0.0100 0.0099 0.0099 0.0099 0.0100 0.0107 0.0151 0.0462 0.1571 0.2977 0.3558 0.3321 0.2710 0.1954 0.1251 0.0794 0.0563 0.0452 0.0378 0.0337 0.0335 0.0358 0.0405 0.0497 0.0612 0.0670 0.0644 0.0574 0.0483 0.0436 0.0532 0.0870 + +const double ColorTemp::JDC468_GreA10_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0958, 0.1010, 0.1090, 0.1172, 0.1352, 0.1954, 0.1957, 0.2178, 0.2402, 0.2477, 0.2553, 0.2594, 0.2622, 0.2667, 0.2707, 0.2760, 0.2805, 0.2913, 0.3023, 0.3376, 0.3715, 0.4345, 0.5030, 0.5702, 0.6376, 0.6724, 0.7072, + 0.7216, 0.7160, 0.7110, 0.6990, 0.6865, 0.6667, 0.6446, 0.6174, 0.5921, 0.5727, 0.5511, 0.5386, 0.5238, 0.5134, 0.5070, 0.4980, 0.4918, 0.4867, 0.4830, 0.4834, 0.4838, 0.4889, 0.4906, 0.4976, 0.5046, 0.5162, 0.5279, + 0.5519, 0.5589, 0.5649, 0.5645, 0.5639, 0.5576, 0.5552, 0.5480, 0.5407, 0.5377, 0.5326, 0.5387, 0.5498, 0.5732, 0.5966, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::JDC468_GreQ7_spect[97] = { //468 Q7 + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0149, 0.0139, 0.0133, 0.0128, 0.0123, 0.01185, 0.0114, 0.011, 0.0106, 0.01045, 0.0103, 0.0104, 0.0105, 0.01065, 0.0108, 0.0109, 0.0110, 0.0117, 0.0124, 0.0205, 0.0283, 0.071, 0.1122, 0.2051, + 0.3017, 0.385, 0.4690, 0.4880, 0.5069, 0.4811, 0.4561, 0.411, 0.3687, 0.3185, 0.2673, 0.2190, 0.1703, 0.1371, 0.1042, 0.086, 0.0695, 0.598, 0.0527, 0.0475, 0.04210, 0.039, 0.03600, 0.0357, 0.0355, 0.037, + 0.0381, 0.0405, 0.0438, 0.0499, 0.0555, 0.0635, 0.0708, 0.074, 0.0789, 0.077, 0.0751, 0.071, 0.0658, 0.059, 0.0530, 0.049, 0.0458, 0.052, 0.0570, 0.077, 0.0982, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//a10 Green 10 0.0958 0.1090 0.1352 0.1957 0.2402 0.2553 0.2622 0.2707 0.2805 0.3023 0.3715 0.5030 0.6376 0.7072 0.7216 0.7110 0.6865 0.6446 0.5921 0.5511 0.5238 0.5070 0.4918 0.4830 0.4838 0.4906 0.5046 0.5279 0.5519 0.5649 0.5639 0.5552 0.5407 0.5326 0.5498 0.5966 +const double ColorTemp::JDC468_GreK7_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0114, 0.0111, 0.0109, 0.0107, 0.0105, 0.0106, 0.0108, 0.0107, 0.0106, 0.0105, 0.0104, 0.0103, 0.0103, 0.0106, 0.0109, 0.0112, 0.0118, 0.0135, 0.0153, 0.0244, 0.0334, 0.0666, 0.0984, 0.1534, 0.2082, 0.2412, 0.2835, + 0.2959, 0.2843, 0.2735, 0.2516, 0.2305, 0.2012, 0.1728, 0.1435, 0.1156, 0.0964, 0.0772, 0.0671, 0.0570, 0.0518, 0.0468, 0.0436, 0.0397, 0.0380, 0.0354, 0.0354, 0.0355, 0.0367, 0.0380, 0.0402, 0.0426, 0.0481, 0.0523, + 0.0643, 0.0678, 0.0704, 0.0693, 0.0676, 0.0639, 0.0609, 0.0567, 0.0514, 0.0487, 0.0468, 0.0518, 0.0567, 0.0730, 0.0902, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//k7 Green 267 0.0114 0.0109 0.0105 0.0108 0.0106 0.0104 0.0103 0.0109 0.0118 0.0153 0.0334 0.0984 0.2082 0.2835 0.2959 0.2735 0.2305 0.1728 0.1156 0.0772 0.0570 0.0468 0.0397 0.0354 0.0355 0.0380 0.0426 0.0523 0.0643 0.0704 0.0676 0.0609 0.0514 0.0468 0.0567 0.0902 + +const double ColorTemp::JDC468_PurE24_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0677, 0.901, 0.1043, 0.1298, 0.1534, 0.1913, 0.2297, 0.2553, 0.2756, 0.2789, 0.2620, 0.2380, 0.2135, 0.1837, 0.1536, 0.1312, 0.1068, 0.0867, 0.0663, 0.0517, 0.0368, 0.0309, 0.0247, 0.0214, 0.0186, 0.0151, 0.0116, + 0.0077, 0.0079, 0.0079, 0.0083, 0.0086, 0.0077, 0.0071, 0.0071, 0.0072, 0.0107, 0.0147, 0.0298, 0.0440, 0.0661, 0.0880, 0.1010, 0.1152, 0.1193, 0.1236, 0.1260, 0.1287, 0.1326, 0.1366, 0.1428, 0.1489, 0.1596, 0.1697, + 0.1936, 0.1996, 0.2057, 0.2036, 0.2015, 0.1954, 0.1890, 0.1798, 0.1706, 0.1651, 0.1603, 0.1692, 0.1788, 0.2075, 0.2363, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//E24 Pur 128 0.0677 0.1043 0.1534 0.2297 0.2756 0.2620 0.2135 0.1536 0.1068 0.0663 0.0368 0.0247 0.0186 0.0116 0.0077 0.0079 0.0086 0.0071 0.0072 0.0147 0.0440 0.0880 0.1152 0.1236 0.1287 0.1366 0.1489 0.1697 0.1936 0.2057 0.2015 0.1890 0.1706 0.1603 0.1788 0.2363 + //spectral data 468 color : Blue H10 - Gamut > WidegamutRGB const double ColorTemp::JDC468_BluH10_spect[97] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.01590, 0.028, 0.03970, 0.0697, 0.09970, 0.1526, 0.20550, 0.253, 0.30110, 0.3412, 0.38180, 0.423, 0.46610, 0.4683, 0.51030, 0.4999, 0.49950, 0.4785, 0.45810, 0.429, 0.39950, 0.374, 0.35010, 0.3135, 0.29630, + 0.01590, 0.028, 0.03970, 0.0697, 0.09970, 0.1526, 0.20550, 0.253, 0.30110, 0.3412, 0.38180, 0.423, 0.46610, 0.4683, 0.51030, 0.5005, 0.49950, 0.4785, 0.45810, 0.429, 0.39950, 0.374, 0.35010, 0.3135, 0.29630, 0.2587, 0.22070, 0.182, 0.14450, 0.1125, 0.09060, 0.072, 0.04810, 0.033, 0.01740, 0.0113, 0.00520, 0.004, 0.00290, 0.0028, 0.00270, 0.0027, 0.00270, 0.0027, 0.00280, 0.0027, 0.00270, 0.0028, 0.00280, - 0.0029, 0.00300, 0.0029, 0.00290, 0.0029, 0.0029, 0.00290, 0.0029, 0.00290, 0.0029, 0.00290, 0.0029, 0.00290, 0.0029, 0.00290, 0.0029, 0.0031, 0.00320, 0.0035, 0.00380, 0.047, 0.00560, + 0.0029, 0.00300, 0.0029, 0.00290, 0.0029, 0.0029, 0.00290, 0.0029, 0.00290, 0.0029, 0.00290, 0.0029, 0.00290, 0.0029, 0.00290, 0.0029, 0.0031, 0.00320, 0.0035, 0.00380, 0.0047, 0.00560, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; +//0.0159, 0.028, 0.0397, 0.0697, 0.0997, 0.1526, 0.2055, 0.253, 0.3011, 0.3412, 0.3818, 0.423, 0.4661, 0.5103 0.4995 0.4581 0.3995 0.3501 0.2963 +//0.2207 0.1445 0.0906 0.0481 0.0174 0.0052 0.0029 0.0027 0.0027 0.0028 0.0027 0.0028 0.0030 0.0029 0.0029 0.0029 0.0029 0.0029 0.0029 +//0.0029 0.0032 0.0038 0.0056 + +const double ColorTemp::JDC468_BluD6_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1127, 0.143, 0.1773, 0.223, 0.2813, 0.3987, 0.4782, 0.5665, 0.6470, 0.6870, 0.7270, 0.7403, 0.7593, 0.7592, 0.7591, 0.7480, 0.7402, 0.7234, 0.7054, 0.6876, 0.6617, 0.6512, 0.6302, 0.6124, 0.5962, 0.5660, + 0.5352, 0.5009, 0.4655, 0.4356, 0.4191, 0.3923, 0.3619, 0.3145, 0.2653, 0.2245, 0.1744, 0.1499, 0.1255, 0.1124, 0.1014, 0.0972, 0.0855, 0.0786, 0.0715, 0.0659, 0.0626, 0.0625, 0.0624, 0.0645, 0.0670, 0.0714, + 0.0769, 0.0865, 0.0964, 0.1086, 0.1200, 0.123, 0.1327, 0.1309, 0.1281, 0.1214, 0.1146, 0.1023, 0.0950, 0.0901, 0.0839, 0.0918, 0.1009, 0.1260, 0.1597, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + + +}; +//d6 blue 84 0.1127 0.1773 0.2813 0.4782 0.6470 0.7270 0.7593 0.7591 0.7402 0.7054 0.6617 0.6302 0.5962 0.5352 0.4655 0.4191 0.3619 0.2653 0.1744 0.1255 0.1014 0.0855 0.0715 0.0626 0.0624 0.0670 0.0769 0.0964 0.1200 0.1327 0.1281 0.1146 0.0950 0.0839 0.1009 0.1597 +const double ColorTemp::JDC468_BluF4_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0180, 0.0270, 0.0324, 0.0453, 0.0611, 0.0845, 0.1066, 0.1234, 0.1446, 0.1567, 0.1718, 0.1867, 0.1954, 0.2024, 0.2083, 0.2090, 0.2096, 0.2060, 0.2036, 0.1990, 0.1947, 0.1920, 0.1901, 0.1856, 0.1794, 0.1667, 0.1516, 0.1321, + 0.1167, 0.1032, 0.0876, 0.0730, 0.0584, 0.0445, 0.0296, 0.0212, 0.0125, 0.0099, 0.0069, 0.0060, 0.0053, 0.0050, 0.0049, 0.0047, 0.0046, 0.0045, 0.0044, 0.0043, 0.0043, 0.0043, 0.0043, 0.0046, 0.0049, 0.0050, 0.0052, 0.0057, + 0.0063, 0.0066, 0.0069, 0.0067, 0.0066, 0.0063, 0.0059, 0.0056, 0.0053, 0.0054, 0.0055, 0.0062, 0.0069, 0.0099, 0.0122, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + +}; + +// f4 blue 134 0.0180 0.0324 0.0611 0.1066 0.1446 0.1718 0.1954 0.2083 0.2096 0.2036 0.1947 0.1901 0.1794 0.1516 0.1167 0.0876 0.0584 0.0296 0.0125 0.0069 0.0053 0.0049 0.0046 0.0044 0.0043 0.0043 0.0049 0.0052 0.0063 0.0069 0.0066 0.0059 0.0053 0.0055 0.0069 0.0122 +const double ColorTemp::JDC468_GreI8_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0230, 0.0232, 0.0234, 0.0254, 0.0263, 0.0298, 0.0329, 0.0367, 0.0377, 0.0388, 0.0399, 0.0410, 0.0421, 0.0440, 0.0460, 0.0481, 0.0496, 0.0523, 0.0559, 0.0645, 0.0727, 0.0878, 0.1020, 0.1156, 0.1288, 0.1334, 0.1394, 0.1398, + 0.1402, 0.1407, 0.1413, 0.1409, 0.1396, 0.1334, 0.1276, 0.1200, 0.1129, 0.1095, 0.1064, 0.1053, 0.1043, 0.1031, 0.1021, 0.1001, 0.0980, 0.0970, 0.0952, 0.0963, 0.0967, 0.0990, 0.1009, 0.1042, 0.1078, 0.1130, 0.1188, 0.1251, + 0.1307, 0.1335, 0.1374, 0.1376, 0.1378, 0.1362, 0.1345, 0.1312, 0.1278, 0.1257, 0.1240, 0.1290, 0.1345, 0.1476, 0.1615, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + +}; + +// i8 green215 215 0.0230 0.0234 0.0263 0.0329 0.0377 0.0399 0.0421 0.0460 0.0496 0.0559 0.0727 0.1020 0.1288 0.1394 0.1402 0.1413 0.1396 0.1276 0.1129 0.1064 0.1043 0.1021 0.0980 0.0952 0.0967 0.1009 0.1078 0.1188 0.1307 0.1374 0.1378 0.1345 0.1278 0.1240 0.1345 0.1615 + +const double ColorTemp::JDC468_OraO18_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0826, 0.0830, 0.0832, 0.0861, 0.0892, 0.0993, 0.1108, 0.1180, 0.1248, 0.1253, 0.1263, 0.1261, 0.1259, 0.1267, 0.1289, 0.1304, 0.1319, 0.1370, 0.1419, 0.1631, 0.1851, 0.2311, 0.2743, 0.3131, 0.3536, 0.3551, 0.3585, 0.3488, 0.3322, + 0.3470, 0.3575, 0.3680, 0.3498, 0.3316, 0.3224, 0.3129, 0.3578, 0.4013, 0.4734, 0.5454, 0.5978, 0.6502, 0.6745, 0.6982, 0.7080, 0.7182, 0.7273, 0.7269, 0.7308, 0.7342, 0.7393, 0.7436, 0.7498, 0.7550, 0.7597, 0.7640, 0.7680, 0.7713, + 0.7766, 0.7786, 0.7816, 0.7841, 0.7863, 0.7889, 0.7902, 0.7931, 0.7957, 0.7997, 0.8068, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + +}; +// o18 ora 382 382 0.0826 0.0832 0.0892 0.1108 0.1248 0.1263 0.1259 0.1289 0.1319 0.1419 0.1851 0.2743 0.3536 0.3585 0.3322 0.3470 0.3680 0.3316 0.3129 0.4013 0.5454 0.6502 0.6982 0.7182 0.7269 0.7342 0.7436 0.7550 0.7640 0.7713 0.7766 0.7816 0.7863 0.7902 0.7957 0.8068 +const double ColorTemp::JDC468_OraD17_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0462, 0.0442, 0.0422, 0.0401, 0.0383, 0.0390, 0.0396, 0.0396, 0.0395, 0.0388, 0.0380, 0.0378, 0.0376, 0.0381, 0.0384, 0.0391, 0.0399, 0.0421, 0.0451, 0.0561, 0.0676, 0.0934, 0.1189, 0.1432, 0.1671, 0.1650, 0.1632, 0.1512, 0.1402, 0.1456, + 0.1521, 0.1613, 0.1696, 0.1552, 0.1409, 0.1342, 0.1283, 0.1689, 0.2084, 0.2845, 0.3575, 0.4183, 0.4797, 0.5090, 0.5389, 0.5498, 0.5617, 0.5667, 0.5728, 0.5788, 0.5822, 0.5889, 0.5938, 0.6011, 0.6081, 0.6145, 0.6212, 0.6267, 0.6304, 0.6331, + 0.6352, 0.6361, 0.6373, 0.6372, 0.6370, 0.6376, 0.6384, 0.6413, 0.6483, 0.6523, 0.6668, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + +}; + +// d17 ora 95 95 0.0462 0.0422 0.0383 0.0396 0.0395 0.0380 0.0376 0.0384 0.0399 0.0451 0.0676 0.1189 0.1671 0.1632 0.1402 0.1521 0.1696 0.1409 0.1283 0.2084 0.3575 0.4797 0.5389 0.5617 0.5728 0.5822 0.5938 0.6081 0.6212 0.6304 0.6352 0.6373 0.6370 0.6384 0.6483 0.6668 //spectral data ColorLab : Skin 35 15 17 const double ColorTemp::ColabSkin35_15_17_spect[97] = { @@ -827,7 +1699,877 @@ const double ColorTemp::ColabSky42_0_m24_spect[97] = { 0.0979, 0.112, 0.1269, 0.134, 0.1430, 0.147, 0.1497, 0.151, 0.1529, 0.1545, 0.1561, 0.158, 0.1603, 0.1616, 0.1627, 0.1625, 0.1623, 0.1614, 0.1605, 0.159, 0.1575, 0.1567, 0.1557, 0.1563, 0.1569, 0.159, 0.1627, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; +//spectral data ColorLab : blue 77 -44 -50 +const double ColorTemp::Colorblue_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0316, 0.0480, 0.0658, 0.0925, 0.1199, 0.1812, 0.2424, 0.2770, 0.3145, 0.3430, 0.3702, 0.4022, 0.4346, 0.4560, 0.4778, 0.4843, 0.4902, 0.4940, 0.4960, 0.4920, 0.4889, 0.4820, + 0.4764, 0.4685, 0.4606, 0.4486, 0.4379, 0.4160, 0.3955, 0.3640, 0.3330, 0.2990, 0.2660, 0.2291, 0.1991, 0.1705, 0.1403, 0.1220, 0.1067, 0.0967, 0.0907, 0.0846, 0.0785, 0.0698, + 0.0601, 0.0525, 0.0455, 0.0423, 0.0386, 0.0370, 0.0358, 0.0354, 0.0351, 0.0368, 0.0382, 0.0413, 0.0449, 0.0474, 0.0492, 0.0484, 0.0477, 0.0460, 0.0437, 0.0402, 0.0371, 0.0349, + 0.0329, 0.0341, 0.0356, 0.0410, 0.0462, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + +}; +//0.1571 0.2150 0.3040 0.3684 0.3952 0.3965 0.3782 0.3418 0.2995 0.2543 0.2043 0.1686 0.1420 0.1070 0.0785 0.0725 0.0755 0.0695 0.0680 0.0914 0.1379 0.1833 0.2038 0.2065 0.2079 0.2110 0.2176 0.2319 0.2518 0.2632 0.2616 0.2522 0.2380 0.2290 0.2432 0.2901 + +const double ColorTemp::ColorViolA1_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1571, 0.185, 0.2150, 0.255, 0.3040, 0.332, 0.3684, 0.381, 0.3952, 0.3956, 0.3965, 0.387, 0.3782, 0.362, 0.3418, 0.322, 0.2995, 0.275, 0.2543, 0.229, 0.2043, 0.185, 0.1686, + 0.155, 0.1420, 0.131, 0.1070, 0.093, 0.0785, 0.075, 0.0725, 0.074, 0.0755, 0.072, 0.0695, 0.069, 0.0680, 0.083, 0.0914, 0.115, 0.1379, 0.162, 0.1833, 0.193, 0.2038, 0.205, + 0.2065, 0.207, 0.2079, 0.209, 0.2110, 0.214, 0.2176, 0.226, 0.2319, 0.242, 0.2518, 0.258, 0.2632, 0.263, 0.2616, 0.256, 0.2522, 0.246, 0.2380, 0.233, 0.2290, 0.235, 0.2432, 0.265, 0.2901, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//0.2270 0.2413 0.3287 0.4079 0.4469 0.4594 0.4535 0.4268 0.3886 0.3427 0.2866 0.2433 0.2087 0.1604 0.1181 0.1069 0.1098 0.0985 0.0916 0.1130 0.1496 0.1746 0.1783 0.1742 0.1738 0.1763 0.1831 0.1975 0.2169 0.2274 0.2247 0.2140 0.1990 0.1897 0.2039 0.2508 + +const double ColorTemp::ColorViolA4_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2270, 0231, 0.2413, 0.286, 0.3287, 0.367, 0.4079, 0.427, 0.4469, 0.452, 0.4594, 0.456, 0.4535, 0.432, 0.4268, 0.403, 0.3886, 0.368, 0.3427, 0.314, 0.2866, 0.265, 0.2433, 0.222, + 0.2087, 0.183, 0.1604, 0.130, 0.1181, 0.112, 0.1069, 0.108, 0.1098, 0.103, 0.0985, 0.094, 0.0916, 0.104, 0.1130, 0.131, 0.1496, 0.152, 0.1746, 0.176, 0.1783, 0.176, 0.1742, 0.174, + 0.1738, 0.175, 0.1763, 0.181, 0.1831, 0.192, 0.1975, 0.206, 0.2169, 0.222, 0.2274, 0.226, 0.2247, 0.219, 0.2140, 0.206, 0.1990, 0.195, 0.1897, 0.196, 0.2039, 0.221, 0.2508, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//0.1426 0.2660 0.3556 0.4259 0.4459 0.4317 0.3942 0.3425 0.2917 0.2413 0.1885 0.1524 0.1267 0.0948 0.0700 0.0661 0.0708 0.0671 0.0699 0.1092 0.2099 0.3582 0.4857 0.5583 0.5950 0.6146 0.6307 0.6495 0.6720 0.6825 0.6809 0.6718 0.6593 0.6517 0.6649 0.7066 +const double ColorTemp::ColorViolA6_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1426, 0.203, 0.2660, 0.315, 0.3556, 0.392, 0.4259, 0.435, 0.4459, 0.437, 0.4317, 0.417, 0.3942, 0.365, 0.3425, 0.317, 0.2917, 0.266, 0.2413, 0.218, 0.1885, 0.172, 0.1524, 0.141, + 0.1267, 0.112, 0.0948, 0.083, 0.0700, 0.068, 0.0661, 0.068, 0.0708, 0.069, 0.0671, 0.068, 0.0699, 0.900, 0.1092, 0.159, 0.2099, 0.284, 0.3582, 0.441, 0.4857, 0.525, 0.5583, 0.567, + 0.5950, 0.605, 0.6146, 0.623, 0.6307, 0.638, 0.6495, 0.661, 0.6720, 0.679, 0.6825, 0.681, 0.6809, 0.675, 0.6718, 0.667, 0.6593, 0.655, 0.6517, 0.658, 0.6649, 0.681, 0.7066, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//0.4939 0.3859 0.4198 0.4780 0.5328 0.5672 0.5880 0.5994 0.6029 0.5981 0.5808 0.5618 0.5369 0.4819 0.4190 0.3921 0.3815 0.3400 0.2991 0.2977 0.3090 0.3088 0.2930 0.2753 0.2660 0.2636 0.2678 0.2811 0.2995 0.3125 0.3153 0.3111 0.3006 0.2952 0.3116 0.3584 +const double ColorTemp::ColorBlueSkyK3_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.4939, 0.435, 0.3859, 0.403, 0.4198, 0.446, 0.4780, 0.505, 0.5328, 0.552, 0.5672, 0.578, 0.5880, 0.595, 0.5994, 0.602, 0.6029, 0.600, 0.5981, 0.588, 0.5808, 0.571, 0.5618, 0.551, + 0.5369, 0.503, 0.4819, 0.452, 0.4190, 0.404, 0.3921, 0.386, 0.3815, 0.364, 0.3400, 0.321, 0.2991, 0.298, 0.2977, 0.304, 0.3090, 0.309, 0.3088, 0.302, 0.2930, 0.284, 0.2753, 0.271, + 0.2660, 0.265, 0.2636, 0.266, 0.2678, 0.275, 0.2811, 0.290, 0.2995, 0.306, 0.3125, 0.314, 0.3153, 0.313, 0.3111, 0.307, 0.3006, 0.298, .2952, 0.306, 0.3116, 0.325, 0.3584, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//0.4058 0.4734 0.5372 0.6051 0.6698 0.6992 0.7118 0.7135 0.7071 0.6938 0.6702 0.6511 0.6282 0.5732 0.5103 0.4913 0.4926 0.4604 0.4341 0.4648 0.5111 0.5335 0.5283 0.5154 0.5098 0.5093 0.5151 0.5309 0.5520 0.5642 0.5657 0.5598 0.5489 0.5430 0.5601 0.6067 + +const double ColorTemp::ColorBlueSkyK9_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.4058, 0.441, 0.4734, 0.502, 0.5372, 0.585, 0.6051, 0.643, 0.6698, 0.685, 0.6992, 0.705, 0.7118, 0.712, 0.7135, 0.711, 0.7071, 0.702, 0.6938, 0.681, 0.6702, 0.663, 0.6511, 0.642, + 0.6282, 0.604, 0.5732, 0.542, 0.5103, 0.499, 0.4913, 0.492, 0.4926, 0.475, 0.4604, 0.452, 0.4341, 0.453, 0.4648, 0.496, 0.5111, 0.525, 0.5335, 0.531, 0.5283, 0.522, 0.5154, 0.512, + 0.5098, 0.509, 0.5093, 0.513, 0.5151, 0.523, 0.5309, 0.544, 0.5520, 0.562, 0.5642, 0.565, 0.5657, 0.562, 0.5598, 0.554, 0.5489, 0.546, 0.5430, 0.553, 0.5601, 0.576, 0.6067, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//42 C4 0.3280 0.2611 0.3781 0.4646 0.5292 0.5732 0.6112 0.6307 0.6310 0.6181 0.5847 0.5488 0.5066 0.4358 0.3585 0.3151 0.2855 0.2309 0.1786 0.1546 0.1443 0.1359 0.1245 0.1151 0.1120 0.1127 0.1169 0.1275 0.1421 0.1504 0.1488 0.1416 0.1303 0.1241 0.1355 0.1739 +const double ColorTemp::ColorBlueSkyC4_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3280, 0.2950, 0.2611, 0.304, 0.3781, 0.423, 0.4646, 0.498, 0.5292, 0.555, 0.5732, 0.591, 0.6112, 0.6221, 0.6307, 0.631, 0.6310, 0.625, 0.6181, 0.607, 0.5847, 0.563, 0.5488, 0.524, + 0.5066, 0.465, 0.4358, 0.398, 0.3585, 0.336, 0.3151, 0.302, 0.2855, 0.254, 0.2309, 0.203, 0.1786, 0.166, 0.1546, 0.149, 0.1443, 0.143, 0.1359, 0.131, 0.1245, 0.123, 0.115, 0.114, + 0.1120, 0.112, 0.1127, 0.114, 0.1169, 0.122, 0.1275, 0.133, 0.1421, 0.147, 0.1504, 0.149, 0.1488, 0.145, 0.1416, 0.136, 0.1303, 0.127, 0.1241, 0.132, 0.1355, 0.155, 0.1739, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//52 C14 0.5697 0.4660 0.5000 0.5560 0.6072 0.6402 0.6632 0.6850 0.7069 0.7292 0.7488 0.7678 0.7786 0.7721 0.7544 0.7394 0.7232 0.6889 0.6446 0.6171 0.5966 0.5743 0.5425 0.5093 0.4884 0.4784 0.4774 0.4822 0.4944 0.5076 0.5186 0.5268 0.5303 0.5332 0.5454 0.5760 +const double ColorTemp::ColorBlueSkyC14_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.5697, 0.511, 0.4660, 0.481, 0.5000, 0.528, 0.5560, 0.583, 0.6072, 0.622, 0.6402, 0.653, 0.6632, 0.674, 0.6850, 0.699, 0.7069, 0.717, 0.7292, 0.735, 0.7488, 0.757, 0.7678, 0.773, + 0.7786, 0.776, 0.7721, 0.765, 0.7544, 0.746, 0.7394, 0.731, 0.7232, 0.704, 0.6889, 0.674, 0.6446, 0.631, 0.6171, 0.606, 0.5966, 0.585, 0.5743, 0.5570, 0.5425, 0.529, 0.5093, 0.498, + 0.4884, 0.482, 0.4784, 0.478, 0.4774, 0.481, 0.4822, 0.487, 0.4944, 0.503, 0.5076, 0.512, 0.5186, 0.522, 0.5268, 0.529, 0.5303, 0.532, 0.5332, 0.539, 0.5454, 0.565, 0.5760, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//80 E4 0.1483 0.1756 0.2536 0.3084 0.3665 0.4189 0.4746 0.5127 0.5239 0.5193 0.4917 0.4569 0.4123 0.3422 0.2672 0.2179 0.1820 0.1356 0.0972 0.0784 0.0698 0.0646 0.0592 0.0556 0.0546 0.0551 0.0571 0.0611 0.0670 0.0701 0.0692 0.0661 0.0620 0.0606 0.0663 0.0834 +const double ColorTemp::ColorBlueSkyE4_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1483, 0.161, 0.1756, 0.213, 0.2536, 0.283, 0.3084, 0.331, 0.3665, 0.387, 0.4189, 0.445, 0.4746, 0.496, 0.5127, 0.519, 0.5239, 0.522, 0.5193, 0.508, 0.4917, 0.476, 0.4569, 0.431, + 0.4123, 0.375, 0.3422, 0.309, 0.2672, 0.242, 0.2179, 0.208, 0.1820, 0.162, 0.1356, 0.113, 0.0972, 0.091, 0.0784, 0.073, 0.0698, 0.066, 0.0646, 0.062, 0.0592, 0.057, 0.0556, 0.055, + 0.0546, 0.055, 0.0551, 0.056, 0.0571, 0.059, 0.0611, 0.064, 0.0670, 0.069, 0.0701, 0.070, 0.0692, 0.067, 0.0661, 0.065, 0.0620, 0.061, 0.0606, 0.063, 0.0663, 0.072, 0.0834, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//229 M1 0.3100 0.2922 0.3514 0.4042 0.4443 0.4769 0.5002 0.5133 0.5187 0.5179 0.5057 0.4928 0.4729 0.4235 0.3643 0.3371 0.3234 0.2827 0.2418 0.2338 0.2370 0.2329 0.2184 0.2028 0.1958 0.1937 0.1973 0.2084 0.2244 0.2351 0.2372 0.2331 0.2239 0.2178 0.2319 0.2731 +const double ColorTemp::ColorBlueSkyM1_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3100, 0.303, 0.2922, 0.322, 0.3514, 0.376, 0.4042, 0.424, 0.4443, 0.457, 0.4769, 0.497, 0.5002, 0.507, 0.5133, 0.516, 0.5187, 0.518, 0.5179, 0.511, 0.5057, 0.497, 0.4928, 0.483, + 0.4729, 0.454, 0.4235, 0.398, 0.3643, 0.346, 0.3371, 0.329, 0.3234, 0.301, 0.2827, 0.263, 0.2418, 0.235, 0.2338, 0.235, 0.2370, 0.236, 0.2329, 0.226, 0.2184, 0.213, 0.2028, 0.198, + 0.1958, 0.194, 0.1937, 0.196, 0.1973, 0.203, 0.2084, 0.212, 0.2244, 0.233, 0.2351, 0.236, 0.2372, 0.234, 0.2331, 0.229, 0.2239, 0.222, 0.2178, 0.224, 0.2319, 0.251, 0.2731, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//514 2B1 0.5277 0.4431 0.4972 0.5820 0.6387 0.6750 0.7001 0.7140 0.7202 0.7193 0.7053 0.6891 0.6657 0.6181 0.5614 0.5312 0.5101 0.4589 0.4045 0.3857 0.3826 0.3751 0.3574 0.3393 0.3314 0.3304 0.3368 0.3523 0.3742 0.3874 0.3883 0.3818 0.3693 0.3616 0.3800 0.4324 +const double ColorTemp::ColorBlueSky2B1_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.5277, 0.485, 0.4431, 0.476, 0.4972, 0.539, 0.5820, 0.607, 0.6387, 0.653, 0.6750, 0.691, 0.7001, 0.707, 0.7140, 0.718, 0.7202, 0.720, 0.7193, 0.713, 0.7053, 0.695, 0.6891, 0.674, + 0.6657, 0.632, 0.6181, 0.587, 0.5614, 0.543, 0.5312, 0.521, 0.5101, 0.483, 0.4589, 0.431, 0.4045, 0.398, 0.3857, 0.385, 0.3826, 0.376, 0.3751, 0.364, 0.3574, 0.346, 0.3393, 0.335, + 0.3314, 0.331, 0.3304, 0.333, 0.3368, 0.346, 0.3523, 0.363, 0.3742, 0.382, 0.3874, 0.385, 0.3883, 0.384, 0.3818, 0.375, 0.3693, 0.364, 0.3616, 0.374, 0.3800, 0.396, 0.4324, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//368 T7 0.1943 0.3199 0.4536 0.5443 0.6043 0.6499 0.6839 0.7125 0.7329 0.7482 0.7527 0.7514 0.7383 0.7028 0.6526 0.6034 0.5500 0.4708 0.3848 0.3268 0.2929 0.2712 0.2493 0.2316 0.2243 0.2234 0.2288 0.2436 0.2640 0.2762 0.2767 0.2693 0.2566 0.2489 0.2665 0.3165 +const double ColorTemp::ColorBlueSkyT7_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1943, 0.256, 0.3199, 0.376, 0.4536, 0.494, 0.5443, 0.572, 0.6043, 0.631, 0.6499, 0.664, 0.6839, 0.698, 0.7125, 0.726, 0.7329, 0.741, 0.7482, 0.751, 0.7527, 0.752, 0.7514, 0.745, + 0.7383, 0.721, 0.7028, 0.675, 0.6526, 0.631, 0.6034, 0.589, 0.5500, 0.512, 0.4708, 0.432, 0.3848, 0.342, 0.3268, 0.311, 0.2929, 0.282, 0.2712, 0.261, 0.2493, 0.236, 0.2316, 0.227, + 0.2243, 0.223, 0.2234, 0.229, 0.2288, 0.235, 0.2436, 0.255, 0.2640, 0.268, 0.2762, 0.277, 0.2767, 0.272, 0.2693, 0.263, 0.2566, 0.254, 0.2489, 0.255, 0.2665, 0.275, 0.3165, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + + +//399 U19 0.5829 0.4865 0.4927 0.5690 0.6221 0.6532 0.6728 0.6832 0.6889 0.6884 0.6771 0.6648 0.6465 0.6038 0.5524 0.5297 0.5194 0.4797 0.4387 0.4356 0.4455 0.4444 0.4282 0.4094 0.4009 0.3992 0.4046 0.4185 0.4385 0.4515 0.4545 0.4505 0.4411 0.4368 0.4539 0.5013 +const double ColorTemp::ColorBlueSkyU19_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.5829, 0.534, 0.4865, 0.489, 0.4927, 0.532, 0.5690, 0.593, 0.6221, 0.641, 0.6532, 0.662, 0.6728, 0.674, 0.6832, 0.687, 0.6889, 0.688, 0.6884, 0.683, 0.6771, 0.671, 0.6648, 0.665, + 0.6465, 0.622, 0.6038, 0.583, 0.5524, 0.542, 0.5297, 0.523, 0.5194, 0.492, 0.4797, 0.451, 0.4387, 0.436, 0.4356, 0.442, 0.4455, 0.445, 0.4444, 0.432, 0.4282, 0.413, 0.4094, 0.404, + 0.4009, 0.400, 0.3992, 0.402, 0.4046, 0.411, 0.4185, 0.426, 0.4385, 0.446, 0.4515, 0.452, 0.4545, 0.452, 0.4505, 0.446, 0.4411, 0.438, 0.4368, 0.443, 0.4539, 0.467, 0.5013, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//382 U2 0.3594 0.3425 0.3214 0.3654 0.4097 0.4360 0.4590 0.4793 0.5002 0.5234 0.5476 0.5745 0.5940 0.5901 0.5703 0.5545 0.5384 0.5029 0.4592 0.4334 0.4149 0.3947 0.3657 0.3363 0.3177 0.3087 0.3077 0.3123 0.3231 0.3351 0.3454 0.3520 0.3545 0.3562 0.3674 0.3976 +const double ColorTemp::ColorBlueSkyU2_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3594, 0.345, 0.3425, 0.333, 0.3214, 0.346, 0.3654, 0.387, 0.4097, 0.424, 0.4360, 0.446, 0.4590, 0.467, 0.4793, 0.494, 0.5002, 0.517, 0.5234, 0.538, 0.5476, 0.564, 0.5745, 0.583, + 0.5940, 0.593, 0.5901, 0.580, 0.5703, 0.563, 0.5545, 0.546, 0.5384, 0.521, 0.5029, 0.478, 0.4592, 0.444, 0.4334, 0.421, 0.4149, 0.408, 0.3947, 0.378, 0.3657, 0.352, 0.3363, 0.324, + 0.3177, 0.313, 0.3087, 0.308, 0.3077, 0.310, 0.3123, 0.317, 0.3231, 0.329, 0.3351, 0.339, 0.3454, 0.348, 0.3520, 0.353, 0.3545, 0.355, 0.3562, 0.359, 0.3674, 0.375, 0.3976, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + + +//378 T17 0.4213 0.3332 0.4205 0.5078 0.5650 0.6025 0.6223 0.6279 0.6195 0.5981 0.5578 0.5197 0.4785 0.4074 0.3325 0.3030 0.2918 0.2511 0.2125 0.2105 0.2198 0.2199 0.2083 0.1945 0.1895 0.1898 0.1954 0.2094 0.2288 0.2406 0.2399 0.2317 0.2189 0.2108 0.2261 0.2755 +const double ColorTemp::ColorBlueSkyT17_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.4213, 0.376, 0.3332, 0.387, 0.4205, 0.467, 0.5078, 0.532, 0.5650, 0.587, 0.6025, 0.611, 0.6223, 0.624, 0.6279, 0.623, 0.6195, 0.607, 0.5981, 0.576, 0.5578, 0.534, 0.5197, 0.499, + 0.4785, 0.435, 0.4074, 0.376, 0.3325, 0.317, 0.3030, 0.295, 0.2918, 0.272, 0.2511, 0.235, 0.2125, 0.212, 0.2105, 0.214, 0.2198, 0.219, 0.2199, 0.215, 0.2083, 0.202, 0.1945, 0.191, + 0.1895, 0.189, 0.1898, 0.193, 0.1954, 0.202, 0.2094, 0.215, 0.2288, 0.236, 0.2406, 0.240, 0.2399, 0.236, 0.2317, 0.225, 0.2189, 0.214, 0.2108, 0.218, 0.2261, 0.245, 0.2755, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//236 M8 -0.0593 0.0128 0.0031 0.0149 0.0197 0.0221 0.0223 0.0230 0.0232 0.0237 0.0243 0.0247 0.0249 0.0249 0.0248 0.0247 0.0244 0.0240 0.0240 0.0242 0.0244 0.0247 0.0252 0.0254 0.0262 0.0269 0.0271 0.0273 0.0278 0.0280 0.0276 0.0275 0.0282 0.0288 0.0295 0.0303 +const double ColorTemp::ColorBlackM8_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0593, 0.040, 0.0128, 0.023, 0.0031, 0.024, 0.0149, 0.017, 0.0197, 0.021, 0.0221, 0.022, 0.0223, 0.023, 0.0230, 0.023, 0.0232, 0.023, 0.0237, 0.024, 0.0243, 0.024, 0.0247, 0.024, + 0.0249, 0.025, 0.0249, 0.025, 0.0248, 0.025, 0.0247, 0.024, 0.0244, 0.024, 0.0240, 0.024, 0.0240, 0.024, 0.0242, 0.024, 0.0244, 0.024, 0.0247, 0.025, 0.0252, 0.025, 0.0254, 0.026, + 0.0262, 0.027, 0.0269, 0.027, 0.0271, 0.027, 0.0273, 0.027, 0.0278, 0.028, 0.0280, 0.028, 0.0276, 0.028, 0.0275, 0.028, 0.0282, 0.028, 0.0288, 0.029, 0.0295, 0.030, 0.0303, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//240 M12 -0.0377 0.0146 0.0167 0.0222 0.0257 0.0261 0.0270 0.0271 0.0274 0.0281 0.0287 0.0299 0.0306 0.0304 0.0297 0.0285 0.0277 0.0267 0.0257 0.0257 0.0258 0.0259 0.0263 0.0276 0.0279 0.0288 0.0297 0.0302 0.0304 0.0303 0.0302 0.0303 0.0310 0.0321 0.0337 0.0356 +const double ColorTemp::ColorBlackM12_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0377, 0.022, 0.0146, 0.015, 0.0167, 0.020, 0.0222, 0.023, 0.0257, 0.026, 0.0261, 0.027, 0.0270, 0.027, 0.0271, 0.027, 0.0274, 0.028, 0.0281, 0.028, 0.0287, 0.029, 0.0299, 0.030, + 0.0306, 0.030, 0.0304, 0.030, 0.0297, 0.029, 0.0285, 0.028, 0.0277, 0.027, 0.0267, 0.026, 0.0257, 0.026, 0.0257, 0.026, 0.0258, 0.026, 0.0259, 0.026, 0.0263, 0.027, 0.0276, 0.028, + 0.0279, 0.028, 0.0288, 0.029, 0.0297, 0.030, 0.0302, 0.030, 0.0304, 0.030, 0.0303, 0.030, 0.0302, 0.030, 0.0303, 0.031, 0.0310, 0.031, 0.0321, 0.033, 0.0337, 0.035, 0.0356, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//241 M13 0.2961 0.0487 0.0261 0.0330 0.0296 0.0305 0.0305 0.0314 0.0320 0.0322 0.0335 0.0348 0.0352 0.0347 0.0336 0.0325 0.0314 0.0299 0.0284 0.0284 0.0286 0.0288 0.0290 0.0299 0.0306 0.0314 0.0320 0.0328 0.0332 0.0331 0.0330 0.0328 0.0337 0.0350 0.0366 0.0385 +const double ColorTemp::ColorBlackM13_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2961, 0.100, 0.0487, 0.035, 0.0261, 0.030, 0.0330, 0.031, 0.0296, 0.030, 0.0305, 0.030, 0.0305, 0.031, 0.0314, 0.032, 0.0320, 0.032, 0.0322, 0.033, 0.0335, 0.034, 0.0348, 0.035, + 0.0352, 0.035, 0.0347, 0.034, 0.0336, 0.033, 0.0325, 0.032, 0.0314, 0.030, 0.0299, 0.029, 0.0284, 0.028, 0.0284, 0.029, 0.0286, 0.029, 0.0288, 0.029, 0.0290, 0.030, 0.0299, 0.030, + 0.0306, 0.031, 0.0314, 0.032, 0.0320, 0.032, 0.0328, 0.033, 0.0332, 0.033, 0.0331, 0.033, 0.0330, 0.033, 0.0328, 0.033, 0.0337, 0.034, 0.0350, 0.036, 0.0366, 0.037, 0.0385, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//525 2B12 0.3848 0.4127 0.4780 0.5375 0.5917 0.6194 0.6353 0.6485 0.6625 0.6784 0.7010 0.7367 0.7706 0.7847 0.7843 0.7826 0.7799 0.7689 0.7521 0.7463 0.7401 0.7314 0.7168 0.7008 0.6904 0.6860 0.6861 0.6896 0.6986 0.7064 0.7138 0.7185 0.7233 0.7281 0.7338 0.7498 +const double ColorTemp::ColorWhite2B12_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3848, 0.405, 0.4127, 0.435, 0.4780, 0.501, 0.5375, 0.572, 0.5917, 0.606, 0.6194, 0.627, 0.6353, 0.642, 0.6485, 0.653, 0.6625, 0.669, 0.6784, 0.692, 0.7010, 0.072, 0.7367, 0.0760, + 0.7706, 0.775, 0.7847, 0.784, 0.7843, 0.784, 0.7826, 0.781, 0.7799, 0.775, 0.7689, 0.762, 0.7521, 0.748, 0.7463, 0.743, 0.7401, 0.731, 0.7314, 0.723, 0.7168, 0.705, 0.7008, 0.701, + 0.6904, 0.689, 0.6860, 0.686, 0.6861, 0.687, 0.6896, 0.691, 0.6986, 0.701, 0.7064, 0.711, 0.7138, 0.715, 0.7185, 0.721, 0.7233, 0.725, 0.7281, 0.731, 0.7338, 0.741, 0.7498, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//527 2B14 0.6608 0.5900 0.6114 0.6747 0.7329 0.7599 0.7706 0.7776 0.7831 0.7890 0.7952 0.8074 0.8185 0.8214 0.8201 0.8218 0.8244 0.8229 0.8192 0.8281 0.8344 0.8388 0.8415 0.8445 0.8495 0.8521 0.8556 0.8604 0.8666 0.8687 0.8687 0.8672 0.8682 0.8703 0.8720 0.8803 +const double ColorTemp::ColorWhite2B14_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.6608, 0.631, 0.5900, 0.605, 0.6114, 0.634, 0.6747, 0.698, 0.7329, 0.745, 0.7599, 0.765, 0.7706, 0.775, 0.7776, 0.781, 0.7831, 0.786, 0.7890, 0.792, 0.7952, 0.797, 0.8074, 0.810, + 0.8185, 0.821, 0.8214, 0.821, 0.8201, 0.821, 0.8218, 0.822, 0.8244, 0.823, 0.8229, 0.822, 0.8192, 0.824, 0.8281, 0.831, 0.8344, 0.836, 0.8388, 0.840, 0.8415, 0.843, 0.8445, 0.847, + 0.8495, 0.851, 0.8521, 0.853, 0.8556, 0.858, 0.8604, 0.863, 0.8666, 0.867, 0.8687, 0.869, 0.8687, 0.867, 0.8672, 0.868, 0.8682, 0.870, 0.8703, 0.871, 0.8720, 0.874, 0.8803, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//97 97 0.0031 0.0047 0.0056 0.0064 0.0070 0.0070 0.0071 0.0066 0.0065 0.0065 0.0064 0.0063 0.0063 0.0058 0.0052 0.0052 0.0053 0.0047 0.0044 0.0052 0.0066 0.0077 0.0081 0.0082 0.0084 0.0089 0.0096 0.0106 0.0121 0.0127 0.0128 0.0124 0.0115 0.0117 0.0133 0.0169 +const double ColorTemp::JDC468_Blackred97_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0031, 0.0035, 0.0047, 0.0050, 0.0056, 0.0060, 0.0064, 0.0065, 0.0070, 0.007, 0.0070, 0.007, 0.0071, 0.007, 0.0066, 0.007, 0.0065, 0.006, 0.0065, 0.006, 0.0064, 0.006, 0.0063, + 0.006, 0.0063, 0.006, 0.0058, 0.005, 0.0052, 0.005, 0.0052, 0.005, 0.0053, 0.005, 0.0047, 0.005, 0.0044, 0.005, 0.0052, 0.006, 0.0066, 0.007, 0.0077, 0.008, 0.0081, 0.008, 0.008, + 0.008, 0.0084, 0.009, 0.0089, 0.009, 0.0096, 0.01, 0.0106, 0.011, 0.0121, 0.012, 0.0127, 0.012, 0.0128, 0.012, 0.0124, 0.012, 0.0115, 0.012, 0.0117, 0.013, 0.0133, 0.015, 0.0169, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//443 443 0.0067 0.0068 0.0067 0.0074 0.0083 0.0088 0.0092 0.0093 0.0098 0.0099 0.0101 0.0106 0.0109 0.0104 0.0094 0.0086 0.0075 0.0058 0.0044 0.0039 0.0037 0.0038 0.0036 0.0035 0.0036 0.0033 0.0033 0.0036 0.0038 0.0042 0.0041 0.0036 0.0033 0.0035 0.0042 0.0062 +const double ColorTemp::JDC468_Blackredbl443_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0067, 0.0067, 0.0068, 0.0068, 0.0067, 0.0070, 0.0074, 0.008, 0.0083, 0.0085, 0.0088, 0.009, 0.0092, 0.0092, 0.0093, 0.0096, 0.0098, 0.0098, 0.0099, 0.01, 0.0101, 0.0104, 0.0106, + 0.0106, 0.0109, 0.0105, 0.0104, 0.01, 0.0094, 0.09, 0.0086, 0.08, 0.0075, 0.06, 0.0058, 0.05, 0.0044, 0.04, 0.0039, 0.0038, 0.0037, 0.0037, 0.0038, 0.0037, 0.0036, 0.0036, + 0.0035, 0.0036, 0.0036, 0.0034, 0.0033, 0.0033, 0.0033, 0.0035, 0.0036, 0.0037, 0.0038, 0.004, 0.0042, 0.004, 0.0041, 0.004, 0.0036, 0.0034, 0.0033, 0.0034, 0.0035, 0.004, 0.0042, 0.005, 0.0062, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//27 27 0.0060 0.0064 0.0070 0.0076 0.0086 0.0086 0.0088 0.0089 0.0089 0.0083 0.0079 0.0078 0.0077 0.0067 0.0059 0.0057 0.0056 0.0046 0.0041 0.0045 0.0050 0.0056 0.0054 0.0053 0.0054 0.0055 0.0057 0.0065 0.0073 0.0079 0.0080 0.0075 0.0067 0.0068 0.0081 0.0114 +const double ColorTemp::JDC468_Blackbl27_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0060, 0.0062, 0.0064, 0.0066, 0.0070, 0.0073, 0.0076, 0.008, 0.0086, 0.0086, 0.0086, 0.0087, 0.0088, 0.0088, 0.0089, 0.0089, 0.0089, 0.0085, 0.0083, 0.008, 0.0079, 0.0078, 0.0078, + 0.0078, 0.0077, 0.007, 0.0067, 0.006, 0.0059, 0.0057, 0.0057, 0.0057, 0.0056, 0.005, 0.0046, 0.0045, 0.0041, 0.0043, 0.0045, 0.0047, 0.0050, 0.0053, 0.0056, 0.0055, 0.0054, 0.0055, + 0.0053, 0.0053, 0.0054, 0.0054, 0.0055, 0.0056, 0.0057, 0.006, 0.0065, 0.007, 0.0073, 0.0075, 0.0079, 0.008, 0.0080, 0.008, 0.0075, 0.007, 0.0067, 0.0067, 0.0068, 0.007, 0.0081, 0.01, 0.0114, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//28 28 0.0092 0.0118 0.0155 0.0218 0.0267 0.0296 0.0312 0.0306 0.0282 0.0244 0.0205 0.0186 0.0167 0.0126 0.0091 0.0080 0.0071 0.0050 0.0042 0.0042 0.0044 0.0045 0.0045 0.0042 0.0041 0.0039 0.0040 0.0043 0.0048 0.0050 0.0047 0.0042 0.0041 0.0042 0.0049 0.0074 +const double ColorTemp::JDC468_Blackbl28_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0092, 0.01, 0.0118, 0.012, 0.0155, 0.016, 0.0218, 0.025, 0.0267, 0.028, 0.0296, 0.03, 0.0312, 0.031, 0.0306, 0.03, 0.0282, 0.026, 0.0244, 0.022, 0.0205, 0.02, 0.0186, 0.017, 0.0167, + 0.015, 0.0126, 0.01, 0.0091, 0.0085, 0.0080, 0.0075, 0.0071, 0.006, 0.0050, 0.05, 0.0042, 0.0042, 0.0042, 0.0043, 0.0044, 0.0044, 0.0045, 0.0045, 0.0045, 0.0043, 0.0042, 0.0042, + 0.0041, 0.004, 0.0039, 0.004, 0.0040, 0.004, 0.0043, 0.0044, 0.0048, 0.005, 0.0050, 0.0048, 0.0047, 0.0045, 0.0042, 0.0041, 0.0041, 0.0041, 0.0042, 0.0045, 0.0049, 0.006, 0.0074, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//214 214 0.0072 0.0062 0.0061 0.0064 0.0069 0.0071 0.0075 0.0081 0.0082 0.0088 0.0103 0.0126 0.0145 0.0146 0.0140 0.0133 0.0118 0.0094 0.0070 0.0059 0.0051 0.0046 0.0045 0.0043 0.0045 0.0045 0.0048 0.0056 0.0065 0.0072 0.0067 0.0065 0.0057 0.0058 0.0068 0.0103 +const double ColorTemp::JDC468_Blackgr214_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0072, 0.007, 0.0062, 0.0062, 0.0061, 0.0063, 0.0064, 0.0067, 0.0069, 0.007, 0.0071, 0.0072, 0.0075, 0.008, 0.0081, 0.008, 0.0082, 0.0085, 0.0088, 0.009, 0.0103, 0.011, 0.0126, + 0.012, 0.0145, 0.0145, 0.0146, 0.014, 0.0140, 0.014, 0.0133, 0.012, 0.0118, 0.01, 0.0094, 0.008, 0.0070, 0.006, 0.0059, 0.0055, 0.0051, 0.005, 0.0046, 0.0045, 0.0045, 0.0044, + 0.0043, 0.0044, 0.0045, 0.0045, 0.0045, 0.0046, 0.0048, 0.005, 0.0056, 0.006, 0.0065, 0.007, 0.0072, 0.007, 0.0067, 0.0066, 0.0065, 0.006, 0.0057, 0.0056, 0.0058, 0.006, 0.0068, 0.008, 0.0103, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + + +//436 436 0.0095 0.0123 0.0173 0.0242 0.0293 0.0317 0.0310 0.0283 0.0246 0.0197 0.0152 0.0129 0.0112 0.0083 0.0063 0.0059 0.0056 0.0045 0.0043 0.0050 0.0059 0.0064 0.0062 0.0060 0.0060 0.0062 0.0066 0.0075 0.0086 0.0093 0.0089 0.0082 0.0073 0.0072 0.0088 0.0139 +const double ColorTemp::JDC468_Blackbl436_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0095, 0.01, 0.0123, 0.013, 0.0173, 0.02, 0.0242, 0.026, 0.0293, 0.03, 0.0317, 0.031, 0.0310, 0.03, 0.0283, 0.025, 0.0246, 0.02, 0.0197, 0.018, 0.0152, 0.014, 0.0129, 0.012, + 0.0112, 0.01, 0.0083, 0.007, 0.0063, 0.006, 0.0059, 0.0058, 0.0056, 0.005, 0.0045, 0.0045, 0.0043, 0.005, 0.0050, 0.0055, 0.0059, 0.006, 0.0064, 0.0063, 0.0062, 0.006, 0.0060, + 0.006, 0.0060, 0.006, 0.0062, 0.0064, 0.0066, 0.007, 0.0075, 0.008, 0.0086, 0.009, 0.0093, 0.009, 0.0089, 0.0086, 0.0082, 0.008, 0.0073, 0.0072, 0.0072, 0.008, 0.0088, 0.01, 0.0139, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + + +//455 455 0.1560 0.1943 0.2724 0.4469 0.5896 0.6393 0.6390 0.6239 0.6096 0.5895 0.5698 0.5662 0.5603 0.5304 0.4977 0.4975 0.4998 0.4601 0.4261 0.4520 0.4986 0.5237 0.5270 0.5260 0.5297 0.5375 0.5504 0.5711 0.5910 0.6023 0.6029 0.5977 0.5880 0.5830 0.5978 0.6345 +const double ColorTemp::JDC468_Whitebl455_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1560, 0.18, 0.1943, 0.25, 0.2724, 0.40, 0.4469, 0.50, 0.5896, 0.60, 0.6393, 0.639, 0.6390, 0.625, 0.6239, 0.61, 0.6096, 0.60, 0.5895, 0.57, 0.5698, 0.567, 0.5662, 0.56, + 0.5603, 0.55, 0.5304, 0.51, 0.4977, 0.498, 0.4975, 0.498, 0.4998, 0.47, 0.4601, 0.44, 0.4261, 0.43, 0.4520, 0.47, 0.4986, 0.51, 0.5237, 0.525, 0.5270, 0.526, 0.5260, 0.528, + 0.5297, 0.53, 0.5375, 0.54, 0.5504, 0.56, 0.5711, 0.58, 0.5910, 0.595, 0.6023, 0.602, 0.6029, 0.600, 0.5977, 0.59, 0.5880, 0.585, 0.5830, 0.59, 0.5978, 0.61, 0.6345, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//101 101 0.0076 0.0094 0.0116 0.0139 0.0158 0.0158 0.0152 0.0142 0.0130 0.0111 0.0094 0.0090 0.0085 0.0069 0.0058 0.0057 0.0058 0.0048 0.0044 0.0060 0.0094 0.0126 0.0141 0.0141 0.0148 0.0157 0.0172 0.0197 0.0227 0.0245 0.0242 0.0233 0.0215 0.0205 0.0240 0.0321 +const double ColorTemp::JDC468_Blackvio101_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0076, 0.008, 0.0094, 0.01, 0.0116, 0.012, 0.0139, 0.015, 0.0158, 0.0158, 0.0158, 0.0156, 0.0152, 0.015, 0.0142, 0.014, 0.0130, 0.012, 0.0111, 0.01, 0.0094, 0.009, 0.0090, 0.009, + 0.0085, 0.008, 0.0069, 0.006, 0.0058, 0.0057, 0.0057, 0.0058, 0.0058, 0.005, 0.0048, 0.0045, 0.0044, 0.005, 0.0060, 0.008, 0.0094, 0.011, 0.0126, 0.013, 0.0141, 0.014, 0.0141, 0.0145, 0.0148, 0.015, 0.0157, 0.016, 0.0172, 0.018, 0.0197, 0.021, 0.0227, 0.023, 0.0245, 0.0241, + 0.0242, 0.0235, 0.0233, 0.022, 0.0215, 0.021, 0.0205, 0.022, 0.0240, 0.026, 0.0321, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//92 92 0.1652 0.2036 0.2848 0.4708 0.6230 0.6758 0.6761 0.6619 0.6502 0.6343 0.6195 0.6194 0.6169 0.5939 0.5677 0.5678 0.5695 0.5373 0.5105 0.5356 0.5778 0.6020 0.6073 0.6090 0.6124 0.6187 0.6295 0.6456 0.6603 0.6693 0.6716 0.6704 0.6660 0.6640 0.6749 0.7003 +const double ColorTemp::JDC468_Whitebl92_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1652, 0.19, 0.2036, 0.24, 0.2848, 0.35, 0.4708, 0.55, 0.6230, 0.65, 0.6758, 0.6759, 0.6761, 0.665, 0.6619, 0.655, 0.6502, 0.64, 0.6343, 0.62, 0.6195, 0.6194, 0.6194, 0.618, + 0.6169, 0.605, 0.5939, 0.58, 0.5677, 0.5677, 0.5678, 0.568, 0.5695, 0.555, 0.5373, 0.52, 0.5105, 0.52, 0.5356, 0.55, 0.5778, 0.60, 0.6020, 0.605, 0.6073, 0.608, 0.6090, 0.61, + 0.6124, 0.615, 0.6187, 0.62, 0.6295, 0.64, 0.6456, 0.65, 0.6603, 0.665, 0.6693, 0.67, 0.6716, 0.671, 0.6704, 0.669, 0.6660, 0.665, 0.6640, 0.67, 0.6749, 0.69, 0.7003, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//94 94 0.0506 0.0569 0.0678 0.0906 0.1088 0.1160 0.1184 0.1195 0.1203 0.1215 0.1293 0.1474 0.1609 0.1538 0.1415 0.1466 0.1535 0.1364 0.1248 0.1494 0.1871 0.2098 0.2163 0.2179 0.2217 0.2282 0.2372 0.2500 0.2631 0.2713 0.2739 0.2725 0.2678 0.2660 0.2770 0.3025 +const double ColorTemp::JDC468_Greyredbl94_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0506, 0.053, 0.0569, 0.06, 0.0678, 0.08, 0.0906, 0.1, 0.1088, 0.11, 0.1160, 0.117, 0.1184, 0.119, 0.1195, 0.12, 0.1203, 0.1205, 0.1215, 0.125, 0.1293, 0.133, 0.1474, 0.15, + 0.1609, 0.155, 0.1538, 0.145, 0.1415, 0.143, 0.1466, 0.15, 0.1535, 0.14, 0.1364, 0.13, 0.1248, 0.14, 0.1494, 0.17, 0.1871, 0.200, 0.2098, 0.21, 0.2163, 0.217, 0.2179, 0.22, + 0.2217, 0.222, 0.2282, 0.23, 0.2372, 0.24, 0.2500, 0.256, 0.2631, 0.27, 0.2713, 0.272, 0.2739, 0.273, 0.2725, 0.27, 0.2678, 0.267, 0.2660, 0.272, 0.2770, 0.28, 0.3025, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + + + +//32 32 0.0933 0.1333 0.1967 0.3132 0.4096 0.4556 0.4763 0.4845 0.4870 0.4852 0.4868 0.4959 0.4971 0.4755 0.4407 0.4085 0.3643 0.2922 0.2161 0.1658 0.1370 0.1190 0.1040 0.0947 0.0949 0.1001 0.1106 0.1306 0.1536 0.1652 0.1609 0.1480 0.1291 0.1188 0.1370 0.1933 +const double ColorTemp::JDC468_Blue32_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0933, 0.11, 0.1333, 0.17, 0.1967, 0.265, 0.3132, 0.35, 0.4096, 0.43, 0.4556, 0.465, 0.4763, 0.48, 0.4845, 0.486, .4870, 0.486, 0.4852, 0.486, 0.4868, 0.49, 0.4959, 0.496, + 0.4971, 0.48, 0.4755, 0.46, 0.4407, 0.42, 0.4085, 0.38, 0.3643, 0.32, 0.2922, 0.25, 0.2161, 0.19, 0.1658, 0.15, 0.1370, 0.12, 0.1190, 0.11, 0.1040, 0.10, 0.0947, 0.0948, + 0.0949, 0.097, 0.1001, 0.105, 0.1106, 0.12, 0.1306, 0.14, 0.1536, 0.16, 0.1652, 0.162, 0.1609, 0.154, 0.1480, 0.135, 0.1291, 0.12, 0.1188, 0.125, 0.1370, 0.16, 0.1933, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + + +//236 236 0.0165 0.0259 0.0432 0.0684 0.0858 0.0895 0.0828 0.0683 0.0527 0.0365 0.0235 0.0177 0.0143 0.0096 0.0067 0.0063 0.0060 0.0052 0.0053 0.0061 0.0074 0.0083 0.0085 0.0080 0.0078 0.0076 0.0081 0.0095 0.0112 0.0121 0.0114 0.0100 0.0086 0.0083 0.0102 0.0180 +const double ColorTemp::JDC468_Blue236_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0165, 0.021, 0.0259, 0.035, 0.0432, 0.05, 0.0684, 0.075, 0.0858, 0.087, 0.0895, 0.085, 0.0828, 0.075, 0.0683, 0.058, 0.0527, 0.045, 0.0365, 0.031, 0.0235, 0.021, 0.0177, 0.016, + 0.0143, 0.012, 0.0096, 0.0085, 0.0067, 0.0065, 0.0063, 0.0062, 0.0060, 0.006, 0.0052, 0.0052, 0.0053, 0.006, 0.0061, 0.007, 0.0074, 0.008, 0.0083, 0.0084, 0.0085, 0.0083, + 0.0080, 0.008, 0.0078, 0.0077, 0.0076, 0.008, 0.0081, 0.009, 0.0095, 0.01, 0.0112, 0.012, 0.0121, 0.012, 0.0114, 0.011, 0.0100, 0.009, 0.0086, 0.0085, 0.0083, 0.009, 0.0102, 0.0015, 0.0180, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//300 300 0.0079 0.0085 0.0087 0.0092 0.0094 0.0093 0.0093 0.0095 0.0097 0.0110 0.0158 0.0544 0.1907 0.3753 0.4883 0.5181 0.5044 0.4631 0.4070 0.3594 0.3262 0.3054 0.2873 0.2772 0.2790 0.2875 0.3029 0.3292 0.3571 0.3719 0.3693 0.3573 0.3371 0.3253 0.3471 0.4087 +const double ColorTemp::JDC468_Gre300_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0079, 0.008, 0.0085, 0.0086, 0.0087, 0.009, 0.0092, 0.0093, 0.0094, 0.0094, 0.0093, 0.0093, 0.0093, 0.0094, 0.0095, 0.0096, 0.0097, 0.01, 0.0110, 0.012, 0.0158, 0.045, + 0.0544, 0.134, 0.1907, 0.25, 0.3753, 0.435, 0.4883, 0.505, 0.5181, 0.512, 0.5044, 0.485, 0.4631, 0.433, 0.4070, 0.387, 0.3594, 0.334, 0.3262, 0.31, 0.3054, 0.295, 0.2873, 0.292, + 0.2772, 0.278, 0.2790, 0.281, 0.2875, 0.291, 0.3029, 0.3121, 0.3292, 0.333, 0.3571, 0.365, 0.3719, 0.365, 0.3693, 0.362, 0.3573, 0.342, 0.3371, 0.325, 0.3253, 0.336, 0.3471, 0.367, 0.4087, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//340 340 0.0175 0.0320 0.0587 0.0989 0.1267 0.1322 0.1210 0.0978 0.0732 0.0487 0.0297 0.0212 0.0167 0.0106 0.0069 0.0064 0.0062 0.0051 0.0052 0.0061 0.0073 0.0081 0.0080 0.0076 0.0075 0.0072 0.0077 0.0088 0.0105 0.0112 0.0104 0.0092 0.0079 0.0075 0.0092 0.0167 +const double ColorTemp::JDC468_Blue340_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0175, 0.02, 0.0320, 0.04, 0.0587, 0.08, 0.0989, 0.11, 0.1267, 0.13, 0.1322, 0.125, 0.1210, 0.111, 0.0978, 0.08, 0.0732, 0.06, 0.0487, 0.04, 0.0297, 0.025, 0.0212, 0.02, + 0.0167, 0.012, 0.0106, 0.008, 0.0069, 0.0065, 0.0064, 0.0063, 0.0062, 0.0055, 0.0051, 0.0051, 0.0052, 0.006, 0.0061, 0.007, 0.0073, 0.008, 0.0081, 0.008, 0.0080, 0.0078, + 0.0076, 0.0076, 0.0075, 0.0074, 0.0072, 0.0075, 0.0077, 0.008, 0.0088, 0.0092, 0.0105, 0.011, 0.0112, 0.0108, 0.0104, 0.01, 0.0092, 0.008, 0.0079, 0.0075, 0.0075, 0.008, + 0.0092, 0.01, 0.0167, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//110 110 0.0954 0.1234 0.1702 0.2631 0.3363 0.3664 0.3799 0.3905 0.4002 0.4160 0.4582 0.5262 0.5798 0.5915 0.5742 0.5465 0.5035 0.4364 0.3581 0.2977 0.2589 0.2349 0.2152 0.2030 0.2032 0.2106 0.2249 0.2511 0.2799 0.2951 0.2915 0.2776 0.2552 0.2419 0.2638 0.3287 +const double ColorTemp::JDC468_Gree110_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0954, 0.11, 0.1234, 0.15, 0.1702, 0.22, 0.2631, 0.312, 0.3363, 0.352, 0.3664, 0.372, 0.3799, 0.385, 0.3905, 0.395, 0.4002, 0.41, 0.4160, 0.43, 0.4582, 0.511, 0.5262, 0.544, + 0.5798, 0.585, 0.5915, 0.585, 0.5742, 0.563, 0.5465, 0.523, 0.5035, 0.465, 0.4364, 0.389, 0.3581, 0.3334, 0.2977, 0.275, 0.2589, 0.245, 0.2349, 0.223, 0.2152, 0.211, 0.2030, 0.204, + 0.2032, 0.206, 0.2106, 0.221, 0.2249, 0.243, 0.2511, 0.271, 0.2799, 0.286, 0.2951, 0.294, 0.2915, 0.2876, 0.2776, 0.2657, 0.2552, 0.2456, 0.2419, 0.253, 0.2638, 0.275, 0.3287, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//457 457 0.0127 0.0126 0.0112 0.0110 0.0109 0.0106 0.0105 0.0104 0.0110 0.0136 0.0318 0.1246 0.3262 0.5051 0.5566 0.5181 0.4406 0.3429 0.2411 0.1647 0.1202 0.0968 0.0804 0.0709 0.0703 0.0747 0.0840 0.1023 0.1243 0.1355 0.1311 0.1179 0.0993 0.0884 0.1043 0.1590 +const double ColorTemp::JDC468_Gree457_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0127, 0.0126, 0.0126, 0.012, 0.0112, 0.011, 0.0110, 0.011, 0.0109, 0.0107, 0.0106, 0.0105, 0.0105, 0.0105, 0.0104, 0.0107, 0.0110, 0.0124, 0.0136, 0.0234, 0.0318, 0.09, + 0.1246, 0.22, 0.3262, 0.43, 0.5051, 0.52, 0.5566, 0.54, 0.5181, 0.476, 0.4406, 0.398, 0.3429, 0.296, 0.2411, 0.203, 0.1647, 0.142, 0.1202, 0.1, 0.0968, 0.09, 0.0804, 0.08, + 0.0709, 0.0708, 0.0703, 0.0723, 0.0747, 0.08, 0.0840, 0.09, 0.1023, 0.11, 0.1243, 0.13, 0.1355, 0.132, 0.1311, 0.12, 0.1179, 0.10, 0.0993, 0.09, 0.0884, 0.09, 0.1043, 0.12, 0.1590, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//241 241 0.0134 0.0106 0.0110 0.0108 0.0111 0.0114 0.0114 0.0115 0.0114 0.0122 0.0192 0.0731 0.2455 0.4689 0.6183 0.6852 0.7107 0.7112 0.7059 0.7177 0.7335 0.7445 0.7487 0.7523 0.7555 0.7606 0.7683 0.7779 0.7855 0.7915 0.7964 0.8011 0.8056 0.8097 0.8144 0.8239 +const double ColorTemp::JDC468_Yel241_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0134, 0.012, 0.0106, 0.011, 0.0110, 0.011, 0.0108, 0.011, 0.0111, 0.0112, 0.0114, 0.0114, 0.0114, 0.0114, 0.0115, 0.0114, 0.0114, 0.012, 0.0122, 0.017, 0.0192, 0.05, 0.0731, 0.12, + 0.2455, 0.355, 0.4689, 0.556, 0.6183, 0.645, 0.6852, 0.698, 0.7107, 0.711, 0.7112, 0.708, 0.7059, 0.712, 0.7177, 0.724, 0.7335, 0.742, 0.7445, 0.746, 0.7487, 0.751, 0.7523, 0.753, + 0.7555, 0.758, 0.760, 0.7626, 0.7683, 0.771, 0.7779, 0.782, 0.7855, 0.791, 0.7915, 0.794, 0.7964, 0.799, 0.8011, 0.804, 0.8056, 0.807, 0.8097, 0.811, 0.8144, 0.820, 0.8239, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//321 321 0.0247 0.0203 0.0182 0.0183 0.0182 0.0179 0.0182 0.0188 0.0199 0.0249 0.0529 0.1519 0.3116 0.4138 0.4410 0.4679 0.4906 0.4655 0.4517 0.5203 0.6238 0.6952 0.7270 0.7406 0.7469 0.7527 0.7607 0.7708 0.7786 0.7849 0.7897 0.7940 0.7984 0.8025 0.8069 0.8160 +const double ColorTemp::JDC468_Ora321_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0247, 0.022, 0.0203, 0.019, 0.0182, 0.0182, 0.0183, 0.0182, 0.0182, 0.018, 0.0179, 0.018, 0.0182, 0.0185, 0.0188, 0.019, 0.0199, 0.022, 0.0249, 0.035, 0.0529, 0.112, + 0.1519, 0.231, 0.3116, 0.365, 0.4138, 0.421, 0.4410, 0.451, 0.4679, 0.485, 0.4906, 0.473, 0.4655, 0.455, 0.4517, 0.487, 0.5203, 0.578, 0.6238, 0.667, 0.6952, 0.711, 0.7270, 0.735, + 0.7406, 0.743, 0.7469, .751, 0.7527, 0.756, 0.7607, 0.765, 0.7708, 0.774, 0.7786, 0.782, 0.7849, 0.786, 0.7897, 0.79, 0.7940, 0.794, 0.7984, 0.799, 0.8025, 0.805, 0.8069, 0.811, 0.8160, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//353 353 0.0260 0.0294 0.0331 0.0420 0.0490 0.0517 0.0541 0.0572 0.0608 0.0664 0.0813 0.1070 0.1291 0.1344 0.1317 0.1356 0.1390 0.1289 0.1195 0.1278 0.1420 0.1493 0.1500 0.1500 0.1527 0.1576 0.1651 0.1759 0.1870 0.1942 0.1963 0.1952 0.1910 0.1898 0.1995 0.2209 +const double ColorTemp::JDC468_Yellow353_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0260, 0.027, 0.0294, 0.031, 0.0331, 0.037, 0.0420, 0.045, 0.0490, 0.051, 0.0517, 0.053, 0.0541, 0.056, 0.0572, 0.059, 0.0608, 0.063, 0.0664, 0.072, 0.0813, 0.096, 0.1070, 0.112, + 0.1291, 0.132, 0.1344, 0.133, 0.1317, 0.134, 0.1356, 0.137, 0.1390, 0.134, 0.1289, 0.123, 0.1195, 0.122, 0.1278, 0.134, 0.1420, 0.145, 0.1493, 0.15, 0.1500, 0.15, 0.1500, 0.153, + 0.1527, 0.154, 0.1576, 0.162, 0.1651, 0.172, 0.1759, 0.182, 0.1870, 0.191, 0.1942, 0.195, 0.1963, 0.196, 0.1952, 0.193, 0.1910, 0.19, 0.1898, 0.195, 0.1995, 0.21, 0.2209, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//465 465 0.0388 0.0654 0.1020 0.1557 0.1880 0.1783 0.1434 0.1013 0.0684 0.0410 0.0219 0.0149 0.0117 0.0080 0.0062 0.0062 0.0062 0.0056 0.0063 0.0098 0.0230 0.0440 0.0577 0.0617 0.0645 0.0690 0.0766 0.0903 0.1064 0.1144 0.1113 0.1022 0.0898 0.0833 0.0962 0.1377 +const double ColorTemp::JDC468_Mag465_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0388, 0.05, 0.0654, 0.09, 0.1020, 0.12, 0.1557, 0.17, 0.1880, 0.182, 0.1783, 0.162, 0.1434, 0.12, 0.1013, 0.09, 0.0684, 0.05, 0.0410, 0.03, 0.0219, 0.02, 0.0149, 0.012, + 0.0117, 0.009, 0.0080, 0.007, 0.0062, 0.0062, 0.0062, 0.0062, 0.0062, 0.006, 0.0056, 0.006, 0.0063, 0.008, 0.0098, 0.018, 0.0230, 0.03, 0.0440, 0.05, 0.0577, 0.06, 0.0617, 0.062, + 0.0645, 0.065, 0.0690, 0.07, 0.0766, 0.08, 0.0903, 0.1, 0.1064, 0.111, 0.1144, 0.112, 0.1113, 0.104, 0.1022, 0.09, 0.0898, 0.088, 0.0833, 0.09, 0.0962, 0.111, 0.1377, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//333 333 0.1030 0.1508 0.2133 0.3191 0.3910 0.3895 0.3424 0.2770 0.2184 0.1593 0.1074 0.0825 0.0669 0.0430 0.0265 0.0278 0.0315 0.0212 0.0163 0.0355 0.0861 0.1365 0.1565 0.1589 0.1629 0.1713 0.1852 0.2099 0.2378 0.2517 0.2469 0.2322 0.2102 0.1973 0.2191 0.2855 +const double ColorTemp::JDC468_Mag333_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1030, 0.12, 0.1508, 0.18, 0.2133, 0.26, 0.3191, 0.364, 0.3910, 0.39, 0.3895, 0.375, 0.3424, 0.312, 0.2770, 0.251, 0.2184, 0.183, 0.1593, 0.122, 0.1074, 0.1, 0.0825, 0.07, + 0.0669, 0.05, 0.0430, 0.03, 0.0265, 0.027, 0.0278, 0.03, 0.0315, 0.025, 0.0212, 0.02, 0.0163, 0.03, 0.0355, 0.05, 0.0861, 0.112, 0.1365, 0.143, 0.1565, 0.157, 0.1589, 0.16, + 0.1629, 0.165, 0.1713, 0.175, 0.1852, 0.19, 0.2099, 0.221, 0.2378, 0.245, 0.2517, 0.25, 0.2469, 0.238, 0.2322, 0.224, 0.2102, 0.206, 0.1973, 0.209, 0.2191, 0.231, 0.2855, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + + +//203 203 0.0833 0.1329 0.2005 0.3099 0.3855 0.3916 0.3530 0.2926 0.2346 0.1741 0.1201 0.0934 0.0759 0.0495 0.0306 0.0308 0.0330 0.0214 0.0150 0.0256 0.0510 0.0723 0.0769 0.0748 0.0761 0.0813 0.0911 0.1087 0.1295 0.1399 0.1353 0.1232 0.1064 0.0971 0.1137 0.1677 +const double ColorTemp::JDC468_Mag203_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0833, 0.11, 0.1329, 0.16, 0.2005, 0.25, 0.3099, 0.342, 0.3855, 0.39, 0.3916, 0.374, 0.3530, 0.321, 0.2926, 0.267, 0.2346, 0.21, 0.1741, 0.153, 0.1201, 0.1, 0.0934, 0.08, + 0.0759, 0.06, 0.0495, 0.04, 0.0306, 0.0307, 0.0308, 0.032, 0.0330, 0.025, 0.0214, 0.018, 0.0150, 0.02, 0.0256, 0.04, 0.0510, 0.06, 0.0723, 0.074, 0.0769, 0.075, 0.0748, 0.076, + 0.0761, 0.08, 0.0813, 0.09, 0.0911, 0.1, 0.1087, 0.115, 0.1295, 0.134, 0.1399, 0.136, 0.1353, 0.131, 0.1232, 0.114, 0.1064, 0.1, 0.0971, 0.105, 0.1137, 0.123, 0.1677, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//blue cyan +const double ColorTemp::J570_BlueB6_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1611, 0.18, 0.1947, 0.23, 0.2639, 0.31, 0.3488, 0.37, 0.4022, 0.43, 0.4517, 0.49, 0.501, 0.52, 0.5317, 0.534, 0.5367, 0.53, 0.5246, 0.51, 0.4905, 0.47, 0.4510, 0.43, 0.4059, + 0.37, 0.3351, 0.31, 0.2612, 0.24, 0.2177, 0.205, 0.1883, 0.16, 0.1444, 0.123, 0.1065, 0.1, 0.0889, 0.085, 0.0811, 0.08, 0.0757, 0.071, 0.0695, 0.067, 0.0648, 0.064, 0.0634, + 0.063, 0.0637, 0.065, 0.0662, 0.068, 0.0714, 0.075, 0.0787, 0.08, 0.0828, 0.082, 0.0822, 0.08, 0.0781, 0.075, 0.0726, 0.071, 0.0698, 0.075, 0.0770, 0.08, 0.0973, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueB15_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2207, 0.2, 0.1897, 0.21, 0.2274, 0.25, 0.2805, 0.30, 0.3216, 0.34, 0.3596, 0.38, 0.4003, 0.42, 0.4438, 0.47, 0.4909, 0.52, 0.5469, 0.57, 0.6009, 0.62, 0.6414, 0.65, 0.6557, + 0.64, 0.6275, 0.59, 0.5675, 0.53, 0.5022, 0.48, 0.4348, 0.39, 0.3473, 0.31, 0.2613, 0.24, 0.2039, 0.18, 0.1696, 0.15, 0.1465, 0.13, 0.1243, 0.11, 0.1055, 0.10, 0.0952, 0.094, + 0.0911, 0.091, 0.0906, 0.092, 0.0940, 0.1, 0.1006, 0.104, 0.1075, 0.11, 0.1125, 0.113, 0.1146, 0.113, 0.1129, 0.112, 0.1120, 0.115, 0.1198, 0.13, 0.1431, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueC2_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2534, 0.25, 0.2454, 0.28, 0.3101, 0.33, 0.3567, 0.37, 0.3981, 0.41, 0.4258, 0.43, 0.4472, 0.45, 0.4574, 0.455, 0.4571, 0.45, 0.4468, 0.43, 0.4205, 0.41, 0.3947, 0.38, + 0.3647, 0.33, 0.3074, 0.27, 0.2471, 0.23, 0.2221, 0.22, 0.2128, 0.20, 0.1810, 0.17, 0.1510, 0.15, 0.1486, 0.15, 0.1546, 0.154, 0.1532, 0.15, 0.1426, 0.135, 0.1310, 0.125, + 0.1257, 0.125, 0.1246, 0.126, 0.1276, 0.13, 0.1360, 0.14, 0.1483, 0.15, 0.1566, 0.157, 0.1575, 0.155, 0.1535, 0.15, 0.1453, 0.143, 0.1403, 0.146, 0.1510, 0.16, 0.1855, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueC14_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.5697, 0.51, 0.4660, 0.49, 0.5000, 0.53, 0.5560, 0.58, 0.6072, 0.62, 0.6402, 0.65, 0.6632, 0.67, 0.6850, 0.69, 0.7069, 0.71, 0.7292, 0.74, 0.7488, 0.75, 0.7678, 0.77, 0.7786, + 0.775, 0.7721, 0.76, 0.7544, 0.75, 0.7394, 0.73, 0.7232, 0.70, 0.6889, 0.66, 0.6446, 0.63, 0.6171, 0.61, 0.5966, 0.58, 0.5743, 0.56, 0.5425, 0.53, 0.5093, 0.50, 0.4884, 0.48, + 0.4784, 0.475, 0.4774, 0.48, 0.4822, 0.49, 0.4944, 0.50, 0.5076, 0.51, 0.5186, 0.52, 0.5268, 0.53, 0.5303, 0.532, 0.5332, 0.54, 0.5454, 0.56, 0.5760, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueC16_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1909, 0.10, 0.0635, 0.06, 0.0554, 0.056, 0.0571, 0.057, 0.0580, 0.06, 0.0608, 0.063, 0.0662, 0.07, 0.0712, 0.072, 0.0742, 0.08, 0.0811, 0.09, 0.0985, 0.11, 0.1363, 0.15, + 0.1743, 0.173, 0.1720, 0.15, 0.1372, 0.12, 0.1005, 0.09, 0.0731, 0.06, 0.0509, 0.04, 0.0374, 0.036, 0.0322, 0.032, 0.0308, 0.031, 0.0309, 0.031, 0.0319, 0.033, + 0.0333, 0.034, 0.0349, 0.035, 0.0364, 0.037, 0.0377, 0.038, 0.0386, 0.0386, 0.0386, 0.0384, 0.0383, 0.038, 0.0377, 0.0377, 0.0378, 0.038, 0.0386, 0.04, 0.0417, 0.043, + 0.0461, 0.049, 0.0514, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueF1_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0060, 0.04, 0.0975, 0.11, 0.1297, 0.13, 0.1426, 0.15, 0.1538, 0.16, 0.1624, 0.165, 0.1684, 0.17, 0.1727, 0.175, 0.1761, 0.178, 0.1798, 0.18, 0.1863, 0.19, 0.1993, 0.20, + 0.2091, 0.205, 0.2041, 0.20, 0.1902, 0.19, 0.1836, 0.182, 0.1809, 0.17, 0.1675, 0.16, 0.1527, 0.151, 0.1511, 0.153, 0.1541, 0.154, 0.1545, 0.153, 0.1516, 0.15, + 0.1484, 0.149, 0.1489, 0.15, 0.1516, 0.153, 0.1563, 0.16, 0.1654, 0.17, 0.1766, 0.18, 0.1827, 0.182, 0.1817, 0.18, 0.1766, 0.17, 0.1693, 0.166, 0.1643, 0.17, 0.1726, 0.18, 0.1978, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueF2_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1613, 0.20, 0.2384, 0.30, 0.3288, 0.35, 0.4026, 0.43, 0.4630, 0.48, 0.4992, 0.51, 0.5294, 0.53, 0.5377, 0.53, 0.5261, 0.51, 0.4995, 0.48, 0.4513, 0.43, 0.4064, 0.38, + 0.3620, 0.31, 0.2935, 0.25, 0.2263, 0.21, 0.1977, 0.19, 0.1851, 0.17, 0.1519, 0.14, 0.1213, 0.12, 0.1149, 0.113, 0.1162, 0.114, 0.1133, 0.11, 0.1053, 0.10, 0.0976, 0.095, + 0.0947, 0.095, 0.0953, 0.097, 0.0985, 0.1, 0.1070, 0.11, 0.1188, 0.12, 0.1256, 0.124, 0.1246, 0.12, 0.1187, 0.11, 0.1099, 0.105, 0.1048, 0.11, 0.1145, 0.12, 0.145, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueF10_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3003, 0.20, 0.1512, 0.20, 0.2149, 0.25, 0.2709, 0.30, 0.3127, 0.32, 0.3534, 0.37, 0.4001, 0.42, 0.4456, 0.46, 0.4882, 0.51, 0.5343, 0.55, 0.5728, 0.58, 0.5968, 0.595, + 0.5932, 0.56, 0.5490, 0.51, 0.4756, 0.43, 0.3989, 0.37, 0.3256, 0.28, 0.2424, 0.21, 0.1691, 0.15, 0.1239, 0.10, 0.0998, 0.09, 0.0866, 0.08, 0.0752, 0.07, 0.0664, 0.065, + 0.0623, 0.062, 0.0616, 0.062, 0.0626, 0.064, 0.0662, 0.07, 0.0720, 0.075, 0.0767, 0.077, 0.0784, 0.078, 0.0770, 0.075, 0.0734, 0.073, 0.0716, 0.075, 0.0779, 0.08, 0.0968, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueF13_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3075, 0.22, 0.1514, 0.13, 0.1216, 0.125, 0.1264, 0.13, 0.1312, 0.14, 0.1448, 0.15, 0.1665, 0.17, 0.1850, 0.19, 0.1922, 0.195, 0.1970, 0.20, 0.2036, 0.21, + 0.2136, 0.213, 0.2122, 0.19, 0.1832, 0.16, 0.1412, 0.12, 0.1066, 0.09, 0.0810, 0.07, 0.0579, 0.05, 0.0422, 0.04, 0.0358, 0.035, 0.0336, 0.033, 0.0335, 0.0335, + 0.0339, 0.034, 0.0348, 0.035, 0.0358, 0.036, 0.0371, 0.038, 0.0384, 0.039, 0.0394, 0.04, 0.0405, 0.0404, 0.0405, 0.04, 0.0399, 0.039, 0.0387, 0.039, + 0.0396, 0.04, 0.0422, 0.045, 0.0467, 0.05, 0.0527, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueG9_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0937, 0.09, 0.0891, 0.07, 0.0621, 0.07, 0.0735, 0.08, 0.0842, 0.09, 0.0918, 0.1, 0.1009, 0.105, 0.1091, 0.11, 0.1158, 0.12, 0.1254, 0.13, 0.1452, 0.16, + 0.1805, 0.20, 0.2126, 0.213, 0.2128, 0.20, 0.1863, 0.17, 0.1550, 0.14, 0.1270, 0.1, 0.0973, 0.08, 0.0725, 0.06, 0.0585, 0.055, 0.0521, 0.05, 0.0486, 0.047, + 0.0458, 0.045, 0.0441, 0.044, 0.0439, 0.044, 0.0443, 0.045, 0.0455, 0.046, 0.0478, 0.049, 0.0500, 0.051, 0.0512, 0.051, 0.0511, 0.05, 0.0498, 0.049, + 0.0487, 0.049, 0.0495, 0.05, 0.0531, 0.055, 0.0620, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueG19_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1198, 0.12, 0.1376, 0.15, 0.1735, 0.18, 0.1903, 0.20, 0.2116, 0.22, 0.2322, 0.24, 0.2555, 0.27, 0.2802, 0.29, 0.3077, 0.32, 0.3420, 0.36, 0.3822, 0.41, + 0.4261, 0.43, 0.4565, 0.45, 0.4481, 0.43, 0.4109, 0.39, 0.3736, 0.35, 0.3368, 0.30, 0.2811, 0.25, 0.2228, 0.19, 0.1839, 0.17, 0.1592, 0.15, 0.1394, 0.12, + 0.1183, 0.1, 0.0998, 0.09, 0.0897, 0.085, 0.0851, 0.085, 0.0844, 0.085, 0.0863, 0.09, 0.0912, 0.095, 0.0977, 0.1, 0.1027, 0.105, 0.1064, 0.106, 0.1064, 0.106, + 0.1067, 0.11, 0.1135, 0.12, 0.1319, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueI5_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1096, 012, 0.1546, 0.16, 0.1855, 0.2, 0.2350, 0.25, 0.2720, 0.29, 0.3065, 0.32, 0.3404, 0.36, 0.3782, 0.4, 0.4229, 0.45, 0.4801, 0.51, 0.5416, 0.57, + 0.5962, 0.61, 0.6281, 0.62, 0.6144, 0.58, 0.5680, 0.55, 0.5211, 0.5, 0.4726, 0.43, 0.3991, 0.37, 0.3209, 0.29, 0.2674, 0.25, 0.2311, 0.22, 0.2000, 0.18, + 0.1656, 0.15, 0.1349, 0.12, 0.1161, 0.11, 0.1078, 0.105, 0.1046, 0.105, 0.1049, 0.107, 0.1097, 0.11, 0.1179, 0.12, 0.1264, 0.13, 0.1337, 0.135, 0.1378, 0.14, 0.1402, 0.145, 0.1474, 0.15, 0.1662, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueH15_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1047, 0.105, 0.1078, 0.12, 0.1550, 0.20, 0.2110, 0.23, 0.2487, 0.27, 0.2893, 0.31, 0.3386, 0.35, 0.3723, 0.375, 0.3773, 0.37, 0.3665, 0.35, 0.3373, 0.32, + 0.3037, 0.28, 0.2663, 0.24, 0.2106, 0.17, 0.1540, 0.13, 0.1200, 0.11, 0.0980, 0.08, 0.0721, 0.06, 0.0527, 0.05, 0.0448, 0.043, 0.0418, 0.041, 0.0403, 0.04, + 0.0390, 0.039, 0.0386, 0.039, 0.0392, 0.04, 0.0401, 0.041, 0.0413, 0.042, 0.0435, 0.044, 0.0456, 0.046, 0.0465, 0.046, 0.0457, 0.045, 0.0447, 0.044, 0.0435, 0.044, + 0.0442, 0.046, 0.0485, 0.05, 0.0576, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueI3_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1759, 0.21, 0.2647, 0.31, 0.3209, 0.36, 0.4249, 0.45, 0.4957, 0.52, 0.5536, 0.57, 0.6073, 0.62, 0.6431, 0.65, 0.6538, 0.653, 0.6506, 0.64, 0.6282, 0.61, + 0.5973, 0.57, 0.5559, 0.52, 0.4856, 0.43, 0.4033, 0.37, 0.3417, 0.32, 0.2901, 0.26, 0.2211, 0.19, 0.1585, 0.14, 0.1236, 0.11, 0.1062, 0.1, 0.0959, 0.09, + 0.0865, 0.085, 0.0801, 0.08, 0.0780, 0.079, 0.0788, 0.08, 0.0819, 0.09, 0.0903, 0.1, 0.1009, 0.105, 0.1073, 0.106, 0.1055, 0.1, 0.0998, 0.095, 0.0914, 0.09, 0.0863, 0.09, 0.0961, 0.11, 0.1250, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueI19_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3031, 0.28, 0.2588, 0.25, 0.2472, 0.26, 0.2738, 0.29, 0.3035, 0.31, 0.3271, 0.33, 0.3496, 0.36, 0.3724, 0.38, 0.3968, 0.41, 0.4252, 0.44, 0.4562, 0.47, + 0.4899, 0.5, 0.5147, 0.512, 0.5100, 0.49, 0.4841, 0.47, 0.4608, 0.45, 0.4373, 0.42, 0.3934, 0.37, 0.3420, 0.32, 0.3086, 0.30, 0.2850, 0.27, 0.2622, 0.25, + 0.2334, 0.22, 0.2054, 0.19, 0.1887, 0.185, 0.1806, 0.18, 0.1791, 0.18, 0.1825, 0.185, 0.1909, 0.2, 0.2018, 0.21, 0.2108, 0.213, 0.2164, 0.217, 0.2180, 0.219, + 0.2198, 0.22, 0.2295, 0.24, 0.2562, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueJ4_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0290, 0.02, 0.0598, 0.1, 0.1278, 0.15, 0.1764, 0.19, 0.2052, 0.21, 0.2331, 0.25, 0.2642, 0.28, 0.2906, 0.3, 0.3093, 0.31, 0.3263, 0.33, 0.3413, 0.35, + 0.3550, 0.354, 0.3532, 0.33, 0.3206, 0.3, 0.2685, 0.24, 0.2212, 0.2, 0.1802, 0.16, 0.1346, 0.1, 0.0965, 0.08, 0.0751, 0.07, 0.0646, 0.06, 0.0586, 0.055, + 0.0535, 0.052, 0.0504, 0.05, 0.0491, 0.0495, 0.0493, 0.05, 0.0504, 0.051, 0.0529, 0.053, 0.0565, 0.057, 0.0591, 0.059, 0.0593, 0.058, 0.0576, 0.056, 0.0556, 0.055, + 0.0553, 0.06, 0.0602, 0.065, 0.0727, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueJ6_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3039, 0.3, 0.2571, 0.27, 0.2960, 0.31, 0.3446, 0.37, 0.3937, 0.41, 0.4405, 0.47, 0.4884, 0.51, 0.5337, 0.56, 0.5771, 0.59, 0.6221, 0.64, 0.6589, 0.67, + 0.6808, 0.68, 0.6770, 0.65, 0.6375, 0.59, 0.5693, 0.53, 0.4933, 0.45, 0.4160, 0.39, 0.3223, 0.26, 0.2338, 0.21, 0.1761, 0.16, 0.1447, 0.13, 0.1258, 0.12, + 0.1090, 0.1, 0.0961, 0.09, 0.0899, 0.089, 0.0877, 0.088, 0.0892, 0.09, 0.0949, 0.1, 0.1045, 0.11, 0.1115, 0.112, 0.1131, 0.112, 0.1115, 0.11, 0.1065, 0.105, + 0.1033, 0.11, 0.1122, 0.12, 0.1400, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_BlueJ11_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1274, 0.1, 0.091, 0.08, 0.0656, 0.064, 0.0604, 0.06, 0.0570, 0.06, 0.0604, 0.061, 0.0644, 0.065, 0.0668, 0.07, 0.0700, 0.072, 0.0754, 0.08, 0.0874, 0.1, + 0.1111, 0.12, 0.1327, 0.132, 0.1313, 0.12, 0.1127, 0.1, 0.0931, 0.08, 0.0758, 0.06, 0.0580, 0.05, 0.0449, 0.04, 0.0385, 0.036, 0.0360, 0.035, 0.0351, 0.035, + 0.0351, 0.035, 0.0355, 0.036, 0.0371, 0.0375, 0.0379, 0.038, 0.0388, 0.04, 0.0406, 0.041, 0.0414, 0.0415, 0.0416, 0.041, 0.0409, 0.04, + 0.0398, 0.04, 0.0397, 0.04, 0.0424, 0.043, 0.0458, 0.05, 0.0522, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_BlueJ13_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2802, 0.28, 0.2820, 0.3, 0.3461, 0.4, 0.4357, 0.45, 0.5027, 0.53, 0.5528, 0.58, 0.6001, 0.62, 0.6402, 0.66, 0.6730, 0.69, 0.7019, 0.71, 0.7216, 0.725, + 0.7288, 0.72, 0.7172, 0.7, 0.6779, 0.65, 0.6160, 0.58, 0.5478, 0.52, 0.4751, 0.43, 0.3816, 0.35, 0.2882, 0.25, 0.2260, 0.2, 0.1905, 0.18, 0.1699, 0.16, + 0.1514, 0.14, 0.1361, 0.13, 0.1295, 0.129, 0.1281, 0.13, 0.1309, 0.135, 0.1408, 0.145, 0.1546, 0.16, 0.1644, 0.165, 0.1656, 0.162, + 0.1606, 0.155, 0.1516, 0.15, 0.1461, 0.15, 0.1585, 0.16, 0.1975, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_BlueK5_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1727, 0.18, 0.1814, 0.19, 0.1931, 0.21, 0.2379, 0.25, 0.2728, 0.29, 0.3054, 0.31, 0.3396, 0.36, 0.3780, 0.4, 0.4243, 0.45, 0.4829, 0.51, 0.5464, 0.57, + 0.6024, 0.62, 0.6348, 0.63, 0.6209, 0.59, 0.5741, 0.55, 0.5258, 0.49, 0.4755, 0.43, 0.4003, 0.37, 0.3204, 0.3, 0.2656, 0.25, 0.2282, 0.21, 0.1966, 0.17, + 0.1624, 0.15, 0.1322, 0.12, 0.1137, 0.11, 0.1052, 0.105, 0.1025, 0.102, 0.1028, 0.105, 0.1075, 0.11, 0.1155, 0.12, 0.1237, 0.13, 0.1310, 0.133, + 0.1352, 0.136, 0.1370, 0.14, 0.1444, 0.15, 0.1632, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_BlueN1_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1936, 0.194, 0.1942, 0.22, 0.2692, 0.29, 0.3102, 0.33, 0.3535, 0.37, 0.3885, 0.4, 0.4230, 0.44, 0.4594, 0.48, 0.5011, 0.52, 0.5510, 0.58, 0.6022, 0.62, 0.6479, 0.66, + 0.6748, 0.67, 0.6640, 0.65, 0.6268, 0.61, 0.5919, 0.58, 0.5549, 0.53, 0.4921, 0.46, 0.4209, 0.39, 0.3723, 0.35, 0.3364, 0.32, 0.3005, 0.28, 0.2569, 0.23, 0.2154, 0.19, + 0.1897, 0.18, 0.1768, 0.175, 0.1723, 0.173, 0.1722, 0.175, 0.1785, 0.18, 0.1892, 0.19, 0.2017, 0.21, 0.2134, 0.22, 0.2202, 0.222, 0.2247, 0.23, 0.2333, 0.24, 0.2566, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_BlueN4_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.3138, 0.25, 0.2038, 0.19, 0.1787, 0.18, 0.1840, 0.2, 0.2109, 0.23, 0.2400, 0.26, 0.2715, 0.29, 0.3075, 0.33, 0.3534, 0.39, 0.4149, 0.45, 0.4863, 0.52, + 0.5520, 0.57, 0.5904, 0.58, 0.5750, 0.55, 0.5198, 0.48, 0.4602, 0.43, 0.3997, 0.36, 0.3199, 0.27, 0.2411, 0.2, 0.1883, 0.17, 0.1553, 0.14, 0.1307, 0.12, + 0.1062, 0.1, 0.0859, 0.08, 0.0746, 0.07, 0.0697, 0.069, 0.0678, 0.068, 0.0683, 0.07, 0.0715, 0.075, 0.0765, 0.08, 0.0818, 0.085, 0.0862, 0.087, 0.0885, 0.089, + 0.0899, 0.09, 0.0951, 0.1, 0.1090, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_BlueO19_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1231, 0.13, 0.1348, 0.12, 0.1152, 0.12, 0.1368, 0.15, 0.1627, 0.17, 0.1860, 0.2, 0.2130, 0.23, 0.2462, 0.26, 0.2859, 0.31, 0.3425, 0.38, 0.4152, 0.45, 0.4902, 0.51, + 0.5386, 0.53, 0.5259, 0.49, 0.4652, 0.43, 0.3950, 0.35, 0.3266, 0.28, 0.2469, 0.21, 0.1750, 0.15, 0.1293, 0.12, 0.1033, 0.09, 0.0859, 0.08, 0.0703, 0.06, 0.0578, 0.055, + 0.0521, 0.05, 0.0494, 0.049, 0.0492, 0.049, 0.0498, 0.05, 0.0522, 0.053, 0.0558, 0.058, 0.0590, 0.06, 0.0615, 0.062, 0.0625, 0.063, 0.0634, 0.065, 0.0670, 0.07, 0.0776, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_BlueU8_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0776, 0.1, 0.1703, 0.23, 0.2942, 0.35, 0.4022, 0.45, 0.4795, 0.51, 0.5389, 0.56, 0.5968, 0.6, 0.6362, 0.64, 0.6512, 0.652, 0.6523, 0.64, 0.6340, 0.62, 0.6052, 0.58, + 0.5645, 0.53, 0.4952, 0.45, 0.4124, 0.38, 0.3457, 0.32, 0.2883, 0.25, 0.2164, 0.19, 0.1529, 0.14, 0.1168, 0.1, 0.0983, 0.09, 0.0883, 0.08, 0.0798, 0.075, 0.0735, 0.073, + 0.0720, 0.072, 0.0726, 0.074, 0.0757, 0.08, 0.0830, 0.09, 0.0930, 0.095, 0.0989, 0.097, 0.0971, 0.095, 0.0911, 0.085, 0.0832, 0.08, 0.0795, 0.082, 0.0877, 0.09, 0.1140, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//N8 +const double ColorTemp::J570_NeuN8_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0632, -0.04, -0.0244, 0.01, 0.0125, 0.02, 0.0294, 0.03, 0.0326, 0.033, 0.0352, 0.036, 0.0361, 0.037, 0.0374, 0.0374, 0.0373, 0.038, 0.0378, 0.039, 0.0397, 0.04, + 0.0421, 0.043, 0.0431, 0.042, 0.0417, 0.04, 0.0391, 0.038, 0.0378, 0.037, 0.0368, 0.035, 0.0347, 0.034, 0.0335, 0.034, 0.0341, 0.035, 0.0350, 0.035, 0.0355, 0.036, + 0.0357, 0.0357, 0.0358, 0.036, 0.0369, 0.037, 0.0372, 0.0376, 0.0378, 0.038, 0.0388, 0.039, 0.0397, 0.04, 0.0400, 0.0395, 0.0394, 0.039, 0.0386, 0.0385, 0.0384, 0.039, + 0.0395, 0.04, 0.0415, 0.043, 0.0448, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuN9_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0573, 0.054, 0.0516, 0.053, 0.0548, 0.05, 0.0401, 0.041, 0.0424, 0.043, 0.0449, 0.046, 0.0467, 0.047, 0.0473, 0.0473, 0.0474, 0.048, 0.0483, 0.05, 0.0508, 0.053, + 0.0558, 0.057, 0.0584, 0.058, 0.0550, 0.05, 0.0495, 0.048, 0.0468, 0.0465, 0.0460, 0.044, 0.0430, 0.042, 0.0411, 0.042, 0.0425, 0.044, 0.0457, 0.046, 0.0473, 0.0474, + 0.0475, 0.0475, 0.0474, 0.0475, 0.0476, 0.048, 0.0487, 0.049, 0.0499, 0.05, 0.0515, 0.052, 0.0533, 0.054, 0.0544, 0.054, 0.0539, 0.053, 0.0526, 0.052, 0.0512, 0.0515, + 0.0515, 0.053, 0.0538, 0.056, 0.0597, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuO8_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0014, 0.02, 0.0806, 0.07, 0.0673, 0.07, 0.0854, 0.09, 0.0901, 0.095, 0.0960, 0.098, 0.0992, 0.1, 0.1017, 0.102, 0.1030, 0.104, 0.1052, 0.107, 0.1098, 0.11, + 0.1176, 0.12, 0.1230, 0.12, 0.1176, 0.11, 0.1071, 0.105, 0.1032, 0.103, 0.1032, 0.1, 0.0963, 0.09, 0.0899, 0.09, 0.0939, 0.095, 0.1007, 0.102, 0.1037, 0.104, + 0.1029, 0.102, 0.1014, 0.102, 0.1020, 0.103, 0.1039, 0.105, 0.1072, 0.11, 0.1134, 0.12, 0.1207, 0.122, 0.1245, 0.123, 0.1236, 0.121, 0.1205, 0.12, 0.1158, 0.115, + 0.1132, 0.115, 0.1185, 0.12, 0.1345, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuO11_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2926, 0.2, 0.1863, 0.16, 0.1428, 0.14, 0.1322, 0.134, 0.1396, 0.14, 0.1450, 0.146, 0.1498, 0.15, 0.1527, 0.155, 0.1554, 0.157, 0.1583, 0.16, 0.1631, 0.17, + 0.1754, 0.18, 0.1841, 0.18, 0.1761, 0.17, 0.1600, 0.155, 0.1549, 0.155, 0.1555, 0.15, 0.1449, 0.14, 0.1352, 0.14, 0.1414, 0.15, 0.1519, 0.153, 0.1568, 0.156, + 0.1556, 0.154, 0.1534, 0.154, 0.1547, 0.156, 0.1573, 0.16, 0.1622, 0.17, 0.1713, 0.18, 0.1823, 0.185, 0.1886, 0.188, 0.1873, 0.183, 0.1829, 0.18, 0.1753, 0.174, + 0.1716, 0.175, 0.1800, 0.2, 0.2039, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuD5_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0840, 0.1, 0.1627, 0.18, 0.1934, 0.2, 0.2234, 0.23, 0.2430, 0.25, 0.2547, 0.26, 0.2618, 0.264, 0.2651, 0.265, 0.2655, 0.2655, 0.2659, 0.266, 0.2674, 0.27, + 0.2776, 0.28, 0.2841, 0.27, 0.2654, 0.25, 0.2351, 0.23, 0.2246, 0.225, 0.2247, 0.22, 0.2074, 0.20, 0.1913, 0.20, 0.2029, 0.21, 0.2231, 0.23, 0.2337, 0.233, + 0.2327, 0.23, 0.2291, 0.23, 0.2305, 0.232, 0.2344, 0.24, 0.2417, 0.25, 0.2553, 0.26, 0.2724, 0.28, 0.2816, 0.28, 0.2797, 0.276, 0.2720, 0.27, + 0.2603, 0.26, 0.2536, 0.26, 0.2660, 0.28, 0.3027, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_NeuE11_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1699, 0.18, 0.1971, 0.21, 0.2276, 0.23, 0.2483, 0.25, 0.2690, 0.28, 0.2820, 0.29, 0.2916, 0.295, 0.2992, 0.3, 0.3064, 0.31, 0.3151, 0.32, 0.3301, 0.34, 0.3593, 0.37, + 0.3873, 0.39, 0.3913, 0.38, 0.3793, 0.375, 0.3723, 0.37, 0.3678, 0.35, 0.3482, 0.33, 0.3249, 0.32, 0.3188, 0.319, 0.3188, 0.318, 0.3179, 0.315, 0.3128, 0.31, + 0.3086, 0.31, 0.3105, 0.312, 0.3148, 0.313, 0.3222, 0.33, 0.3364, 0.34, 0.3535, 0.36, 0.3629, 0.362, 0.3621, 0.36, 0.3549, 0.35, 0.3444, 0.34, 0.3394, 0.35, 0.3511, 0.36, 0.3862, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_NeuK16_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.5837, 0.45, 0.4117, 0.43, 0.4427, 0.47, 0.5098, 0.52, 0.5451, 0.55, 0.5698, 0.57, 0.5828, 0.59, 0.5939, 0.6, 0.6045, 0.607, 0.6140, 0.62, 0.6219, 0.63, 0.6330, 0.64, + 0.6419, 0.643, 0.6440, 0.642, 0.6417, 0.64, 0.6379, 0.631, 0.6309, 0.62, 0.6154, 0.6, 0.5911, 0.58, 0.5736, 0.57, 0.5612, 0.56, 0.5539, 0.55, 0.5462, 0.543, + 0.5406, 0.542, 0.5418, 0.543, 0.5452, 0.55, 0.5529, 0.56, 0.5654, 0.57, 0.5806, 0.584, 0.5888, 0.589, 0.5898, 0.586, 0.5858, 0.58, 0.5796, 0.577, 0.5770, 0.58, 0.5883, 0.59, 0.6190, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuM3_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2659, 0.255, 0.2526, 0.26, 0.2616, 0.27, 0.2854, 0.29, 0.3088, 0.31, 0.3231, 0.33, 0.3336, 0.34, 0.3421, 0.345, 0.347, 0.35, 0.3542, 0.36, 0.3647, 0.37, + 0.3854, 0.4, 0.4041, 0.402, 0.4012, 0.39, 0.3856, 0.38, 0.3769, 0.375, 0.3725, 0.36, 0.3525, 0.34, 0.3286, 0.325, 0.3247, 0.326, 0.3279, 0.328, 0.3285, 0.325, + 0.3240, 0.322, 0.3202, 0.321, 0.3220, 0.323, 0.3267, 0.33, 0.3342, 0.34, 0.3487, 0.35, 0.3667, 0.37, 0.3761, 0.375, 0.3746, 0.37, 0.3670, 0.36, 0.3559, 0.35, 0.3498, 0.35, 0.3630, 0.37, 0.3998, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuN18_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1284, 0.11, 0.1090, 0.13, 0.1573, 0.17, 0.1837, 0.19, 0.1971, 0.2, 0.2059, 0.21, 0.2143, 0.22, 0.2213, 0.225, 0.2271, 0.23, 0.2341, 0.24, 0.2487, 0.26, 0.2764, 0.29, + 0.3025, 0.303, 0.3052, 0.3, 0.2919, 0.29, 0.2843, 0.283, 0.2800, 0.27, 0.2612, 0.24, 0.2394, 0.235, 0.2339, 0.234, 0.2340, 0.233, 0.2326, 0.23, 0.2277, 0.225, + 0.2235, 0.224, 0.2246, 0.226, 0.2282, 0.23, 0.2349, 0.24, 0.2477, 0.25, 0.2632, 0.27, 0.2714, 0.271, 0.2702, 0.27, 0.2637, 0.26, 0.2538, 0.25, 0.2479, 0.25, 0.2589, 0.26, 0.2918, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuQ1_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0610, 0.06, 0.0592, 0.04, 0.0339, 0.04, 0.0338, 0.034, 0.0350, 0.036, 0.0363, 0.037, 0.0380, 0.038, 0.0383, 0.0383, 0.0385, 0.04, 0.0408, 0.042, 0.0451, 0.05, + 0.0524, 0.055, 0.0589, 0.058, 0.0585, 0.055, 0.0529, 0.05, 0.0456, 0.04, 0.0390, 0.035, 0.0330, 0.03, 0.0286, 0.028, 0.0275, 0.0276, 0.0275, 0.0278, 0.0279, 0.028, + 0.0289, 0.03, 0.0304, 0.031, 0.0320, 0.032, 0.0328, 0.033, 0.0341, 0.0345, 0.0346, 0.0346, 0.0347, 0.034, 0.0341, 0.034, 0.0336, 0.034, 0.0340, 0.035, + 0.0351, 0.036, 0.0373, 0.038, 0.0411, 0.042, 0.0446, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuS7_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1447, 0.06, 0.0448, 0.042, 0.0411, 0.03, 0.0282, 0.028, 0.0270, 0.029, 0.0298, 0.03, 0.0319, 0.032, 0.0331, 0.0333, 0.0335, 0.036, 0.0361, 0.038, 0.0403, 0.045, + 0.0493, 0.05, 0.0599, 0.06, 0.0636, 0.062, 0.0606, 0.06, 0.0547, 0.05, 0.0488, 0.045, 0.0421, 0.04, 0.0366, 0.035, 0.0335, 0.033, 0.0323, 0.032, 0.0320, 0.032, + 0.0321, 0.0322, 0.0324, 0.033, 0.0333, 0.034, 0.0345, 0.035, 0.0356, 0.036, 0.0364, 0.037, 0.0372, 0.037, 0.0367, 0.0365, 0.0363, 0.0364, + 0.0361, 0.0362, 0.0363, 0.037, 0.0376, 0.04, 0.0412, 0.042, 0.0450, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuV10_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1439, 0.07, 0.0583, 0.04, 0.0372, 0.037, 0.0362, 0.035, 0.0344, 0.034, 0.0340, 0.035, 0.0351, 0.036, 0.0361, 0.0361, 0.0361, 0.037, 0.0377, 0.039, 0.0404, 0.042, + 0.0450, 0.047, 0.0483, 0.048, 0.0475, 0.045, 0.0436, 0.04, 0.0387, 0.036, 0.0343, 0.03, 0.0299, 0.028, 0.0271, 0.027, 0.0262, 0.0262, 0.0262, 0.0267, 0.0269, 0.027, + 0.0283, 0.029, 0.0299, 0.03, 0.0308, 0.031, 0.0319, 0.032, 0.0331, 0.0333, 0.0337, 0.0337, 0.0337, 0.0333, 0.0332, 0.0332, 0.0331, 0.0331, 0.0331, 0.034, + 0.0341, 0.035, 0.0371, 0.038, 0.0399, 0.041, 0.0432, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuW18_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.4685, 0.45, 0.4262, 0.5, 0.5061, 0.55, 0.5898, 0.6, 0.6487, 0.66, 0.6781, 0.68, 0.6947, 0.7, 0.7070, 0.71, 0.7185, 0.72, 0.7294, 0.73, 0.7383, 0.74, 0.7499, 0.75, + 0.7582, 0.758, 0.7582, 0.755, 0.7531, 0.75, 0.7484, 0.745, 0.7422, 0.73, 0.7263, 0.72, 0.7033, 0.7, 0.6913, 0.69, 0.6820, 0.68, 0.6738, 0.67, 0.6628, 0.66, + 0.6512, 0.65, 0.6462, 0.645, 0.6448, 0.645, 0.6485, 0.65, 0.6569, 0.66, 0.6698, 0.67, 0.6781, 0.68, 0.6822, 0.682, 0.6820, 0.682, 0.6815, 0.682, 0.6820, 0.69, 0.6907, 0.7, 0.7152, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuZ14_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.2765, 0.2, 0.1352, 0.13, 0.1222, 0.121, 0.1206, 0.13, 0.1300, 0.134, 0.1357, 0.14, 0.1407, 0.142, 0.1455, 0.147, 0.1485, 0.15, 0.1539, 0.16, 0.1648, 0.17, + 0.1844, 0.2, 0.2015, 0.202, 0.2024, 0.2, 0.1922, 0.19, 0.1868, 0.185, 0.1841, 0.18, 0.1715, 0.16, 0.1566, 0.155, 0.1536, 0.154, 0.1545, 0.154, 0.1536, 0.151, + 0.1500, 0.148, 0.1471, 0.1472, 0.1478, 0.15, 0.1505, 0.153, 0.1552, 0.16, 0.1641, 0.17, 0.1751, 0.18, 0.1813, 0.181, 0.1801, 0.18, + 0.1757, 0.17, 0.1683, 0.165, 0.1642, 0.17, 0.1728, 0.18, 0.1970, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::J570_NeuC18_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0555, 0.055, 0.0545, 0.055, 0.0585, 0.058, 0.0577, 0.056, 0.0554, 0.056, 0.0564, 0.058, 0.0590, 0.06, 0.0611, 0.062, 0.0638, 0.065, 0.0685, 0.07, 0.0797, 0.09, + 0.1009, 0.11, 0.1222, 0.124, 0.1298, 0.127, 0.1257, 0.123, 0.1208, 0.12, 0.1164, 0.11, 0.1067, 0.1, 0.0954, 0.09, 0.0895, 0.088, 0.0862, 0.085, 0.0834, 0.082, + 0.0806, 0.08, 0.0782, 0.078, 0.0780, 0.078, 0.0789, 0.08, 0.0813, 0.084, 0.0858, 0.09, 0.0911, 0.092, 0.0944, 0.093, 0.0938, 0.092, 0.0914, 0.09, 0.0878, 0.086, + 0.0858, 0.09, 0.0903, 0.1, 0.1037, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuD17_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1980, 0.1, 0.0793, 0.06, 0.0578, 0.05, 0.0476, 0.046, 0.0454, 0.046, 0.0471, 0.048, 0.0499, 0.05, 0.0518, 0.052, 0.0533, 0.055, 0.0574, 0.06, 0.0676, 0.07, + 0.0897, 0.1, 0.1129, 0.113, 0.1140, 0.1, 0.0958, 0.08, 0.0743, 0.06, 0.0566, 0.05, 0.0422, 0.04, 0.0332, 0.03, 0.0297, 0.0295, 0.0292, 0.0293, 0.0294, 0.03, + 0.0306, 0.031, 0.0319, 0.032, 0.0339, 0.034, 0.0353, 0.036, 0.0363, 0.037, 0.0370, 0.037, 0.0372, 0.037, 0.0368, 0.0365, 0.0363, 0.036, + 0.0360, 0.037, 0.0376, 0.039, 0.0406, 0.042, 0.0448, 0.046, 0.0499, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuJ11_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1274, 0.1, 0.0916, 0.08, 0.0656, 0.061, 0.0604, 0.06, 0.0570, 0.06, 0.0604, 0.062, 0.0644, 0.065, 0.0668, 0.069, 0.0700, 0.072, 0.0754, 0.08, 0.0874, 0.1, + 0.1111, 0.12, 0.1327, 0.132, 0.1313, 0.12, 0.1127, 0.1, 0.0931, 0.08, 0.0758, 0.06, 0.0580, 0.05, 0.0449, 0.04, 0.0385, 0.037, 0.0360, 0.036, 0.0351, 0.035, + 0.0351, 0.0354, 0.0355, 0.036, 0.0371, 0.0375, 0.0379, 0.038, 0.0388, 0.04, 0.0406, 0.041, 0.0414, 0.0415, 0.0416, 0.041, 0.0409, 0.04, 0.0398, 0.0397, 0.0397, 0.04, + 0.0424, 0.043, 0.0458, 0.048, 0.0522, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::J570_NeuL4_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0348, 0.05, 0.0700, 0.09, 0.1043, 0.11, 0.1320, 0.14, 0.1505, 0.16, 0.1622, 0.17, 0.1721, 0.18, 0.1805, 0.185, 0.1877, 0.19, 0.1955, 0.2, 0.2068, 0.21, + 0.2226, 0.23, 0.2350, 0.235, 0.2352, 0.23, 0.2251, 0.22, 0.2128, 0.2, 0.1990, 0.18, 0.1761, 0.16, 0.1494, 0.13, 0.1296, 0.12, 0.1171, 0.11, 0.1089, 0.105, + 0.1010, 0.1, 0.0949, 0.093, 0.0926, 0.093, 0.0937, 0.095, 0.0961, 0.1, 0.1020, 0.11, 0.1104, 0.112, 0.1150, 0.115, 0.1155, 0.113, 0.1123, 0.11, + 0.1070, 0.105, 0.1040, 0.11, 0.1110, 0.12, 0.1323, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +const double ColorTemp::Colorlab_n72_n2_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0116, 0.01, 0.0171, 0.05, 0.0625, 0.08, 0.1486, 0.16, 0.1963, 0.2, 0.2409, 0.26, 0.2974, 0.31, 0.3468, 0.36, 0.3790, 0.39, 0.4075, 0.41, 0.4216, 0.43, + 0.4399, 0.47, 0.4878, 0.50, 0.5589, 0.57, 0.5882, 0.57, 0.5566, 0.52, 0.5030, 0.46, 0.4451, 0.42, 0.3928, 0.37, 0.3625, 0.35, 0.3396, 0.29, 0.2670, 0.15, + 0.1028, 0.05, -0.0397, -0.08, -0.1151, -0.12, -0.1464, -0.15, -0.1582, -0.16, -0.1609, -0.16, -0.1581, -0.155, -0.1556, -0.156, + -0.1582, -0.16, -0.1621, -0.165, -0.1683, -0.17, -0.1719, -0.17, -0.1696, -0.165, -0.1623, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_10_n70_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0964, 0.1, 0.1534, 0.2, 0.2437, 0.33, 0.4663, 0.5, 0.6005, 0.65, 0.6958, 0.75, 0.8010, 0.83, 0.8598, 0.858, 0.8579, 0.85, 0.8432, 0.83, 0.8102, 0.79, + 0.7607, 0.7, 0.6760, 0.6, 0.5530, 0.5, 0.4212, 0.3, 0.2974, 0.2, 0.1839, 0.1, 0.0743, 0.03, -0.0208, -0.05, -0.0747, -0.08, -0.0913, -0.05, -0.0458, 0.03, + 0.0806, 0.1, 0.1936, 0.2, 0.2556, 0.27, 0.2816, 0.29, 0.2925, 0.3, 0.3033, 0.31, 0.3175, 0.32, 0.3257, 0.325, 0.3246, 0.32, + 0.3187, 0.31, 0.3082, 0.305, 0.3014, 0.304, 0.3059, 0.31, 0.3253, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_n33_n70_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0615, 0.1, 0.1219, 0.2, 0.2179, 0.3, 0.4397, 0.5, 0.5722, 0.6, 0.6714, 0.7, 0.7834, 0.8, 0.8535, 0.86, 0.8647, 0.864, 0.8642, 0.864, 0.8429, 0.82, + 0.8035, 0.75, 0.7316, 0.7, 0.6238, 0.55, 0.4996, 0.45, 0.3717, 0.3, 0.2487, 0.2, 0.1299, 0.06, 0.0272, 0.01, -0.0315, -0.04, -0.0557, -0.051, + -0.0519, -0.03, -0.0234, 0.001, 0.0041, 0.01, 0.0201, 0.021, 0.0269, 0.028, 0.0298, 0.03, 0.0371, 0.04, 0.0497, 0.05, 0.0578, 0.056, + 0.0557, 0.05, 0.0490, 0.04, 0.0374, 0.03, 0.0299, 0.03, 0.0348, 0.04, 0.0537, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_n8_n74_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0603, 0.08, 0.1069, 0.15, 0.1810, 0.25, 0.3573, 0.4, 0.4634, 0.5, 0.5406, 0.6, 0.6266, 0.65, 0.6772, 0.679, 0.6800, 0.68, 0.6732, 0.66, 0.6511, 0.63, + 0.6136, 0.6, 0.5444, 0.5, 0.4415, 0.4, 0.3317, 0.3, 0.2286, 0.2, 0.1336, 0.1, 0.0425, 0.01, -0.0360, -0.05, -0.0807, -0.09, -0.0967, -0.08, + -0.0761, -0.05, -0.0119, 0.02, 0.0462, 0.05, 0.0784, 0.08, 0.0919, 0.095, 0.0974, 0.1, 0.1046, 0.11, 0.1152, 0.12, 0.1217, 0.121, + 0.1205, 0.12, 0.1155, 0.11, 0.1067, 0.104, 0.1010, 0.103, 0.1047, 0.11, 0.1199, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_19_n69_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1281, 0.16, 0.1941, 0.24, 0.2982, 0.4, 0.5607, 0.65, 0.7192, 0.8, 0.8299, 0.9, 0.9517, 1.0, 1.0174, 1.014, 1.0115, 1.0, 0.9899, 0.96, 0.9475, 0.91, + 0.8877, 0.82, 0.7902, 0.7, 0.6508, 0.57, 0.5008, 0.45, 0.3595, 0.3, 0.2302, 0.15, 0.1049, 0.02, -0.0045, -0.03, -0.0662, -0.07, -0.0832, -0.05, -0.0161, 0.05, + 0.1648, 0.2, 0.3257, 0.37, 0.4137, 0.43, 0.4506, 0.46, 0.4661, 0.47, 0.4801, 0.49, 0.4974, 0.5, 0.5072, 0.505, 0.5062, 0.5, 0.4995, 0.49, 0.4876, 0.48, + 0.4799, 0.48, 0.4849, 0.49, 0.5081, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_n80_10_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0247, -0.01, -0.0057, 0.01, 0.0242, 0.05, 0.0736, 0.08, 0.0996, 0.1, 0.1281, 0.14, 0.1660, 0.19, 0.2037, 0.21, 0.2337, 0.25, 0.2618, 0.27, 0.2793, 0.29, + 0.3024, 0.32, 0.3564, 0.4, 0.4360, 0.44, 0.4788, 0.47, 0.4655, 0.45, 0.4308, 0.42, 0.3920, 0.37, 0.3564, 0.34, 0.3357, 0.32, 0.3167, 0.28, 0.2434, 0.1, + 0.0745, 0.01, -0.0725, -0.09, -0.1506, -0.18, -0.1831, -0.19, -0.1955, -0.195, -0.1995, -0.199, -0.1989, -0.198, + -0.1976, -0.198, -0.1999, -0.2, -0.2027, -0.208, -0.2070, -0.208, -0.2094, -0.208, -0.2080, -0.207, -0.2038, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +const double ColorTemp::Colorlab_n80_26_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -0.0325, -0.03, -0.0203, -0.01, -0.0012, 0.01, 0.0228, 0.03, 0.0332, 0.04, 0.0506, 0.06, 0.0762, 0.09, 0.1069, 0.12, 0.1370, 0.15, 0.1666, 0.17, 0.1877, 0.2, + 0.2174, 0.25, 0.2849, 0.33, 0.3849, 0.4, 0.4477, 0.45, 0.4509, 0.44, 0.4305, 0.42, 0.4049, 0.39, 0.3806, 0.37, 0.3664, 0.35, 0.3495, 0.29, 0.2724, 0.1, + 0.0921, 0.01, -0.0651, -0.09, -0.1489, -0.15, -0.1837, -0.19, -0.1970, -0.2, -0.2020, -0.202, -0.2029, -0.203, -0.2026, -0.204, + -0.2047, -0.205, -0.2069, -0.208, -0.2099, -0.21, -0.2115, -0.21, -0.2106, -0.209, -0.2086, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +/* +//0,1767000 0,2207000 0,3142000 0,5269000 0,7018000 0,7605000 0,7580000 0,7366000 0,7182000 0,6929000 0,6661000 0,6542000 +//0,6420000 0,6085000 0,5752000 0,5728000 0,5723000 0,5318000 0,4982000 0,5226000 0,5670000 0,5929000 0,5977000 0,5975000 +//0,6002000 0,6065000 0,6177000 0,6352000 0,6526000 0,6623000 0,6633000 0,6593000 0,6517000 0,6479000 0,6607000 0,6908000 + +const double ColorTemp::JDC468_greyc14_66_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1767, 0.19, 0.2207, 0.25, 0.3142, 0.40, 0.5269, 0.63, 0.7018, 0.73, 0.7605, 0.76, 0.7580, 0.74, 0.7366, 0.725, 0.7182, 0.705, 0.6929, 0.68, 0.6661, 0.66, 0.6542, 0.65, + 0.642, 0.62, 0.6085, 0.585, 0.5752, 0.573, 0.5728, 0.573, 0.5723, 0.555, 0.5318, 0.51, 0.4982, 0.51, 0.5226, 0.54, 0.5670, 0.58, 0.5929, 0.594, 0.5977, 0.597, 0.5975, 0.6, + 0.6002, 0.602, 0.6065, 0.61, 0.6177, 0.62, 0.6352, 0.64, 0.6526, 0.66, 0.6623, 0.662, 0.6633, 0.66, 0.6593, 0.653, 0.6517, 0.65, 0.6479, 0.65, 0.6607, 0.69, 0.6908, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +//0,1325000 0,1637000 0,2222000 0,3492000 0,4523000 0,4897000 0,4918000 0,4840000 0,4761000 0,4638000 0,4538000 0,4582000 +// 0,4588000 0,4360000 0,4091000 0,4101000 0,4128000 0,3785000 0,3494000 0,3720000 0,4122000 0,4339000 0,4362000 0,4355000 +// 0,4395000 0,4475000 0,4606000 0,4807000 0,5006000 0,5125000 0,5145000 0,5112000 0,5029000 0,4992000 0,5150000 0,5526000 + +const double ColorTemp::JDC468_greym13_325_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.1325, 0.15, 0.1637, 0.2, 0.2222, 0.28, 0.3492, 0.40, 0.4523, 0.47, 0.4897, 0.49, 0.4918, 0.49, 0.4840, 0.48, 0.4761, 0.47, 0.4638, 0.46, 0.4538, 0.455, 0.4582, 0.458, + 0.4588, 0.45, 0.4360, 0.42, 0.4091, 0.41, 0.4101, 0.411, 0.4128, 0.405, 0.3785, 0.36, 0.3494, 0.36, 0.3720, 0.41, 0.4122, 0.425, 0.4339, 0.435, 0.4362, 0.597, 0.4355, 0.437, + 0.4395, 0.44, 0.4475, 0.45, 0.4606, 0.47, 0.4807, 0.49, 0.5006, 0.51, 0.5125, 0.513, 0.5145, 0.512, 0.5112, 0.51, 0.5029, 0.5, 0.4992, 0.51, 0.5150, 0.53, 0.5526, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; + +//0,0823000 0,1036000 0,1337000 0,1966000 0,2468000 0,2679000 0,2728000 0,2726000 0,2724000 0,2698000 0,2705000 0,2810000 +// 0,2879000 0,2756000 0,2586000 0,2601000 0,2617000 0,2357000 0,2124000 0,2241000 0,2471000 0,2581000 0,2569000 0,2548000 +// 0,2579000 0,2653000 0,2765000 0,2941000 0,3126000 0,3230000 0,3238000 0,3189000 0,3091000 0,3043000 0,3200000 0,3579000 + +const double ColorTemp::JDC468_greyf26_156_spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0823, 0.1, 0.1036, 0.11, 0.1337, 0.16, 0.1966, 0.22, 0.2468, 0.255, 0.2679, 0.27, 0.2728, 0.273, 0.2726, 0.273, 0.2724, 0.271, 0.2698, 0.27, 0.2705, 0.275, 0.2810, 0.285, + 0.2879, 0.28, 0.2756, 0.26, 0.2586, 0.26, 0.2601, 0.261, 0.2617, 0.25, 0.2357, 0.22, 0.2124, 0.22, 0.2241, 0.23, 0.2471, 0.25, 0.2581, 0.278, 0.2569, 0.255, 0.2548, 0.255, + 0.2579, 0.26, 0.2653, 0.27, 0.2765, 0.28, 0.2941, 0.30, 0.3126, 0.32, 0.3230, 0.323, 0.3238, 0.32, 0.3189, 0.31, 0.3091, 0.302, 0.3043, 0.31, 0.3200, 0.34, 0.3579, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +*/ +//A1 0.0912 0.1228 0.1712 0.2978 0.3713 0.4241 0.4861 0.5255 0.5355 0.5363 0.5237 0.5251 +// 0.5722 0.6554 0.6936 0.6675 0.6203 0.5651 0.5116 0.4825 0.4714 0.4866 0.5320 0.5729 +// 0.5968 0.6069 0.6131 0.6198 0.6285 0.6325 0.6316 0.6282 0.6227 0.6196 0.6215 0.6337 + +const double ColorTemp::Colorlab_n80_5_9_5_9spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0912, 0.1, 0.1228, 0.15, 0.1712, 0.2, 0.2978, 0.32, 0.3713, 0.41, 0.4241, 0.44, 0.4861, 0.51, 0.5255, 0.53, 0.5355, 0.534, 0.5363, 0.53, 0.5237, 0.524, 0.5251, 0.56, + 0.5722, 0.6, 0.6554, 0.67, 0.6936, 0.67, 0.6675, 0.65, 0.6203, 0.6, 0.5651, 0.54, 0.5116, 0.5, 0.4825, 0.48, 0.4714, 0.48, 0.4866, 0.5, 0.5320, 0.55, 0.5729, 0.58, + 0.5968, 0.6, 0.6069, 0.61, 0.6131, 0.615, 0.6198, 0.62, 0.6285, 0.63, 0.6325, 0.632, 0.6316, 0.63, 0.6282, 0.625, 0.6227, 0.62, 0.6196, 0.62, 0.6215, 0.63, 0.6337, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +/* +//A2 0.0385 0.0514 0.0711 0.1229 0.1528 0.1744 0.1999 0.2163 0.2209 0.2216 0.2167 0.2185 +//0.2414 0.2813 0.3012 0.2922 0.2734 0.2511 0.2292 0.2173 0.2127 0.2183 0.2354 0.2508 +//0.2599 0.2637 0.2662 0.2689 0.2725 0.2742 0.2738 0.2724 0.2701 0.2689 0.2697 0.2747 + +const double ColorTemp::Colorlab_n57_5_6_9spect[97] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0385, 0.04, 0.0514, 0.06, 0.0711, 0.1, 0.1229, 0.14, 0.1528, 0.16, 0.1744, 0.18, 0.1999, 0.2, 0.2163, 0.22, 0.2209, 0.221, 0.2216, 0.22, 0.2167, 0.216, 0.2185, 0.23, + 0.2414, 0.26, 0.2813, 0.3, 0.3012, 0.3, 0.2922, 0.28, 0.2734, 0.26, 0.2511, 0.24, 0.2292, 0.22, 0.2173, 0.215, 0.2127, 0.215, 0.2183, 0.22, 0.2354, 0.24, 0.2508, 0.255, + 0.2599, 0.26, 0.2637, 0.263, 0.2662, 0.267, 0.2689, 0.27, 0.2725, 0.273, 0.2742, 0.274, 0.2738, 0.273, 0.2724, 0.271, 0.2701, 0.27, 0.2689, 0.269, 0.2697, 0.27, 0.2747, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 +}; +*/ /* * Name: XYZtoCorColorTemp.c * @@ -1024,6 +2766,197 @@ void ColorTemp::cieCAT02(double Xw, double Yw, double Zw, double &CAM02BB00, dou } +void ColorTemp::cieCAT02float(float Xw, float Yw, float Zw, float &CAM02BB00, float &CAM02BB01, float &CAM02BB02, float &CAM02BB10, float &CAM02BB11, float &CAM02BB12, float &CAM02BB20, float &CAM02BB21, float &CAM02BB22, float adap) +{ + +// CIECAT02 - J.Desmis January 2012 review September 2012 + const float whiteD50p[3] = {0.9646019585, 1.0, 0.8244507152}; //calculate with these tools + + float cam_dest[3] = {0., 0., 0.}; + float cam_orig[3] = {0., 0., 0.}; + const float CAT02[3][3] = {{0.7328, 0.4296, -0.1624},//CAT02 2002 + { -0.7036, 1.6975, 0.0061}, + {0.0030, 0.0136, 0.9834} + }; + const float INVCAT02[3][3] = {{1.09612382083551, -0.278869000218287, 0.182745179382773}, //Inverse CAT02 + {0.454369041975359, 0.4735331543070412, 0.0720978037172291}, + { -0.009627608738442936, -0.00569803121611342, 1.01532563995454} + }; + + float inv_white_orig[3][3] = {{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.} + }; + float intermed[3][3] = {{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.} + }; + + float intermed_2[3][3] = {{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.} + }; + float CAM02[3][3] = {{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.} + }; + float D = adap; + + //white destination Wd : RT use always D50 + cam_dest[0] = CAT02[0][0] * whiteD50p[0] + CAT02[0][1] * whiteD50p[1] + CAT02[0][2] * whiteD50p[2]; //Cone response RoD + cam_dest[1] = CAT02[1][0] * whiteD50p[0] + CAT02[1][1] * whiteD50p[1] + CAT02[1][2] * whiteD50p[2]; //GaD + cam_dest[2] = CAT02[2][0] * whiteD50p[0] + CAT02[2][1] * whiteD50p[1] + CAT02[2][2] * whiteD50p[2]; //BeD + + //origin white Ws : A, D65, custom, etc. + cam_orig[0] = CAT02[0][0] * Xw + CAT02[0][1] * Yw + CAT02[0][2] * Zw; //Cone response RoS + cam_orig[1] = CAT02[1][0] * Xw + CAT02[1][1] * Yw + CAT02[1][2] * Zw; + cam_orig[2] = CAT02[2][0] * Xw + CAT02[2][1] * Yw + CAT02[2][2] * Zw; + + //inverse white + inv_white_orig[0][0] = 1. / cam_orig[0]; // 1/RoS + inv_white_orig[1][1] = 1. / cam_orig[1]; // 1/GaS + inv_white_orig[2][2] = 1. / cam_orig[2]; // 1/BeS + + //intermediates computation + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3 ; j++) { + intermed[i][j] = inv_white_orig[i][i] * CAT02[i][j]; + } + + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3 ; j++) { + intermed_2[i][j] = cam_dest[i] * intermed[i][j]; + } + + //and CAM02 + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) { + CAM02[i][j] += INVCAT02[i][k] * intermed_2[k][j]; + } + + //adaptation jdc : slightly different from CIECAM02 : Rc=(Yw(D/Rw)+(1-D))*R , but it's work ! true at 0 and 1 + CAM02[1][1] = (CAM02[1][1] - 1.0) * D + 1.0; + CAM02[0][0] = (CAM02[0][0] - 1.0) * D + 1.0; + CAM02[2][2] = (CAM02[2][2] - 1.0) * D + 1.0; +// CAM02[1][1] *= D; +// CAM02[0][0] *= D; +// CAM02[2][2] *= D; + CAM02[0][1] *= D; + CAM02[0][2] *= D; + CAM02[1][0] *= D; + CAM02[1][2] *= D; + CAM02[2][0] *= D; + CAM02[2][1] *= D; + //CAT02 matrix with D adaptation + CAM02BB00 = CAM02[0][0]; + CAM02BB01 = CAM02[0][1]; + CAM02BB02 = CAM02[0][2]; + CAM02BB10 = CAM02[1][0]; + CAM02BB11 = CAM02[1][1]; + CAM02BB12 = CAM02[1][2]; + CAM02BB20 = CAM02[2][0]; + CAM02BB21 = CAM02[2][1]; + CAM02BB22 = CAM02[2][2]; + +} + +void ColorTemp::icieCAT02float(float Xw, float Yw, float Zw, float &iCAM02BB00, float &iCAM02BB01, float &iCAM02BB02, float &iCAM02BB10, float &iCAM02BB11, float &iCAM02BB12, float &iCAM02BB20, float &iCAM02BB21, float &iCAM02BB22, float adap) +{ + +// CIECAT02 - J.Desmis January 2012 review September 2017 + const float whiteD50p[3] = {0.9646019585, 1.0, 0.8244507152}; //calculate with these tools + + float cam_dest[3] = {0., 0., 0.}; + float cam_orig[3] = {0., 0., 0.}; + const float CAT02[3][3] = {{0.7328, 0.4296, -0.1624},//CAT02 2002 + { -0.7036, 1.6975, 0.0061}, + {0.0030, 0.0136, 0.9834} + }; + const float INVCAT02[3][3] = {{1.09612382083551, -0.278869000218287, 0.182745179382773}, //Inverse CAT02 + {0.454369041975359, 0.4735331543070412, 0.0720978037172291}, + { -0.009627608738442936, -0.00569803121611342, 1.01532563995454} + }; + + float inv_white_orig[3][3] = {{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.} + }; + float intermed[3][3] = {{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.} + }; + + float intermed_2[3][3] = {{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.} + }; + float INVCAM02[3][3] = {{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.} + }; + float D = adap / 2.; + + //white destination Wd : RT use always D50 + cam_dest[0] = INVCAT02[0][0] * whiteD50p[0] + INVCAT02[0][1] * whiteD50p[1] + INVCAT02[0][2] * whiteD50p[2]; //Cone reponse RoD + cam_dest[1] = INVCAT02[1][0] * whiteD50p[0] + INVCAT02[1][1] * whiteD50p[1] + INVCAT02[1][2] * whiteD50p[2]; //GaD + cam_dest[2] = INVCAT02[2][0] * whiteD50p[0] + INVCAT02[2][1] * whiteD50p[1] + INVCAT02[2][2] * whiteD50p[2]; //BeD + + //origin white Ws : A, D65, custom, etc. + cam_orig[0] = INVCAT02[0][0] * Xw + INVCAT02[0][1] * Yw + INVCAT02[0][2] * Zw; //Cone reponse RoS + cam_orig[1] = INVCAT02[1][0] * Xw + INVCAT02[1][1] * Yw + INVCAT02[1][2] * Zw; + cam_orig[2] = INVCAT02[2][0] * Xw + INVCAT02[2][1] * Yw + INVCAT02[2][2] * Zw; +// cam_orig[0] = CAT02[0][0] * Xw + CAT02[0][1] * Yw + CAT02[0][2] * Zw; //Cone reponse RoS +// cam_orig[1] = CAT02[1][0] * Xw + CAT02[1][1] * Yw + CAT02[1][2] * Zw; + // cam_orig[2] = CAT02[2][0] * Xw + CAT02[2][1] * Yw + CAT02[2][2] * Zw; + + //inverse white + inv_white_orig[0][0] = 1. / cam_orig[0]; // 1/RoS + inv_white_orig[1][1] = 1. / cam_orig[1]; // 1/GaS + inv_white_orig[2][2] = 1. / cam_orig[2]; // 1/BeS + + //intermediates computation + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3 ; j++) { + // intermed[i][j] = inv_white_orig[i][i] * INVCAT02[i][j]; + intermed[i][j] = inv_white_orig[i][i] * CAT02[i][j]; + } + + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3 ; j++) { + intermed_2[i][j] = cam_dest[i] * intermed[i][j]; + } + + //and CAM02 + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) { + INVCAM02[i][j] += INVCAT02[i][k] * intermed_2[k][j]; + } + + //adaptation jdc : slightly different from CIECAM02 : Rc=(Yw(D/Rw)+(1-D))*R , but it's work ! true at 0 and 1 + INVCAM02[0][0] = (INVCAM02[0][0] - 1.0) * D + 1.0; + INVCAM02[2][2] = (INVCAM02[2][2] - 1.0) * D + 1.0; + INVCAM02[0][1] *= D; + INVCAM02[0][2] *= D; + INVCAM02[1][0] *= D; + INVCAM02[1][2] *= D; + INVCAM02[2][0] *= D; + INVCAM02[2][1] *= D; + //CAT02 matrix with D adaptation + iCAM02BB00 = INVCAM02[0][0]; + iCAM02BB01 = INVCAM02[0][1]; + iCAM02BB02 = INVCAM02[0][2]; + iCAM02BB10 = INVCAM02[1][0]; + iCAM02BB11 = INVCAM02[1][1]; + iCAM02BB12 = INVCAM02[1][2]; + iCAM02BB20 = INVCAM02[2][0]; + iCAM02BB21 = INVCAM02[2][1]; + iCAM02BB22 = INVCAM02[2][2]; + +} + + void ColorTemp::temp2mulxyz (double temp, const std::string &method, double &Xxyz, double &Zxyz) { double x, y, z; @@ -1071,10 +3004,10 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, double Xwb, Zwb; temp2mulxyz(temp, method, Xwb, Zwb); - float adj = 1.f; + double adj = 1.0; 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 +3322,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, } 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++) { @@ -1409,7 +3342,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, } 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++) { @@ -1425,8 +3358,8 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, quadCRI /= N_c; 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_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_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(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], static_cast(sqrt(quadCRI))); } } } @@ -1438,8 +3371,8 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, //calculate spectral data for blackbody at temp! double ColorTemp::blackbody_spect(double wavelength, double temperature) { - double wlm = wavelength * 1e-9; /* Wavelength in meters */ - return (3.7417715247e-16 / pow(wlm, 5)) / //3.7417..= c1 = 2*Pi*h*c2 where h=Planck constant, c=velocity of light + const double wlm = wavelength * 1e-9; /* Wavelength in meters */ + return (3.7417715247e-16 / rtengine::pow5(wlm)) / //3.7417..= c1 = 2*Pi*h*c2 where h=Planck constant, c=velocity of light (xexp(1.438786e-2 / (wlm * temperature)) - 1.0); //1.4387..= c2 = h*c/k where k=Boltzmann constant } @@ -1458,6 +3391,7 @@ this values are often called xBar yBar zBar and are characteristics of a color / values cie_colour_match[][3] = 2° Standard Observer x2, y2, z2 E.g. for 380nm: x2=0.001368 y2=0.000039 z2=0.006451 round in J.Walker to 0.0014 0.0000 0.0065 above I have increase precision used by J.Walker and pass to 350nm to 830nm +And also add 10° standard observer */ void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double &x, double &y, double &z) @@ -1516,6 +3450,7 @@ void ColorTemp::spectrum_to_xyz_preset(const double* spec_intens, double &x, dou values cie_colour_match[][3] = 2° Standard Observer x2, y2, z2 E.g. for 380nm: x2=0.001368 y2=0.000039 z2=0.006451 round in J.Walker to 0.0014 0.0000 0.0065 above I have increased the precision used by J.Walker and pass from 350nm to 830nm + And also add standard observer 10° */ for (i = 0, lambda = 350.; lambda < 830.1; i++, lambda += 5.) { double Me = get_spectral_color(lambda, spec_intens); @@ -1565,62 +3500,38 @@ void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const dou void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz) { int i; - double lambda, X = 0, Y = 0, Z = 0, Yo = 0; + double lambda, X = 0, Y = 0, Z = 0; for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { - - double Me; - double Mc; - - Me = get_spectral_color(lambda, spec_color); - Mc = daylight_spect(lambda, _m1, _m2); + const double Me = spec_color[i]; + const double Mc = daylight_spect(lambda, _m1, _m2); X += Mc * cie_colour_match_jd[i][0] * Me; Y += Mc * cie_colour_match_jd[i][1] * Me; Z += Mc * cie_colour_match_jd[i][2] * Me; } - for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { - - double Ms; - - Ms = daylight_spect(lambda, _m1, _m2); - Yo += cie_colour_match_jd[i][1] * Ms; - } - - xx = X / Yo; - yy = Y / Yo; - zz = Z / Yo; + xx = X / Y; + yy = 1.0; + zz = Z / Y; } //calculate XYZ from spectrum data (color) and illuminant : J.Desmis december 2011 void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double _temp, double &xx, double &yy, double &zz) { int i; - double lambda, X = 0, Y = 0, Z = 0, Yo = 0; + double lambda, X = 0, Y = 0, Z = 0; for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { - - double Me; - double Mc; - - Me = get_spectral_color(lambda, spec_color); - Mc = blackbody_spect(lambda, _temp); + const double Me = spec_color[i]; + const double Mc = blackbody_spect(lambda, _temp); X += Mc * cie_colour_match_jd[i][0] * Me; Y += Mc * cie_colour_match_jd[i][1] * Me; Z += Mc * cie_colour_match_jd[i][2] * Me; } - for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { - - double Ms; - - Ms = blackbody_spect(lambda, _temp); - Yo += cie_colour_match_jd[i][1] * Ms; - } - - xx = X / Yo; - yy = Y / Yo; - zz = Z / Yo; + xx = X / Y; + yy = 1.0; + zz = Z / Y; } double ColorTemp::daylight_spect(double wavelength, double m1, double m2) @@ -1648,6 +3559,289 @@ double ColorTemp::daylight_spect(double wavelength, double m1, double m2) return (s0[wlm] + m1 * s1[wlm] + m2 * s2[wlm]); } +//tempxy : return x and y of xyY for 200 or more refreence color, and for T temperature from 2000K to 12000K +// we can change step for temperature and increase number for T > 7500K if necessary +//these values Temp, x, y are references for all calculations and very precise. +//copyright J.Desmis august 2017 and june 2018 +void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float **Tz, float **Ta, float **Tb, float **TL, double *TX, double *TY, double *TZ, const procparams::WBParams & wbpar) +{ + const double* spec_colorforxcyc[] = {//color references + JDC468_BluH10_spect, JDC468_BluD6_spect, ColorchechCyaF3_spect, JDC468_BluM5_spect, // 0 3 + ColorGreenM25_spect, JDC468_GreK7_spect, ColabSky42_0_m24_spect, ColabSky60_0_m31_spect, ColorchechBluC150_m5_m22_spect,//8 + JDC468_GreQ7_spect, ColorchechDCBluN881_m7_m14_spect, ColorchechGreB3_spect, ColorchechPurD2_spect, //12 + ColorchechSGBlaN3_6_spect, ColorchechGraC4_67_spect, JDC468_K15_87greyspect,//15 + JDC468_GraK14_44_spect, ColorGreenalsi_spect, Fictif_61greyspect, ColorchechGreD1_spect,//19 + ColorchechWhiA496_spect, JDC468_GreA10_spect, JDC468_GreI8_spect,//22 + ColabSkin91_4_14_spect, JDC468_PurE24_spect, //24 + ColorchechSGSkiK285_11_17_spect, ColorchechGreE2_spect, ColorchechMagE3_spect, //27 + ColorchechSkiB166_18_18_spect, ColabSkin70_7_32_spect, ColorchechSGSkiF763_14_26_spect,//30 + ColorchechSkiA138_13_14_spect, ColabSkin57_22_18_spect, JDC468_YelN10_spect,//33 + ColabSkin35_15_17_spect, ColabSkin40_17_17_spect, ColorRedkurttu_spect, ColorYellowkeltano_spect, ColorchechYelD3_spect, JDC468_OraO18_spect,//39 + JDC468_GreN7_spect, JDC468_RedG21va_spect, JDC468_OraD17_spect,//42 + ColorchechredC3_spect, JDC468_RedI9_spect, ColorRedpetunia_spect, ColorchechOraA2_spect,//46 + ColabSkin87_8_8_spect, ColabSkin89_8_21_spect, ColabSkin75_8_4_spect, ColabSkin75_10_33_spect,//50 + ColabSkin65_33_11_spect, ColabSkin65_7_24_spect, ColabSkin57_19_6_spect, ColabSkin57_4_19_spect, ColabSkin57_10_28_spect, ColabSkin40_17_6_spect,//56 + ColabSkin26_18_18_spect, ColabSkin90_m1_20_spect, ColorRedlupiini_spect, ColorRedhevosminttu_spect, //60 + ColorRedneilikka_spect, ColorRedpelagornia_spect, ColorRedtalvio_spect, ColorBrownpoimulehti_spect, ColorOrangetuntematon_spect,//65 + ColorOrangetlehmus_spect, ColorOrangvaahtera_spect, ColorBrownlehmus_spect, ColorBrownuotiosammal_spect,//69 + ColorBlacksoil_spect, ColorGraynahjajaekaelae_spect, //71 + ColorGreennuotisammal_spect, ColorGreenleskenlehti_spect, ColorGreenlinnunkaali_spect, //74 + ColorGreenpelto_spect, ColorGreenrodvoikukka, ColorGreenlehmus, ColorGreenlinden, ColorYellowlehmus, ColorYellowsuikeroalpi, //80 + ColorYellowpensashanhikki1, ColorYellowpensashanhikki2, ColorBluehiidenvirna, ColorBluekurkkuyrtti, //84 + ColorPinksiankaersaemoe, ColorVioletharakankello, ColorVioletalsikeapila, ColorVioletakilleija, ColorOrangekehaekukka,//89 + ColorRedpihlaja, ColorVioletpetunia, ColorVioletorvokki, ColorBluesinisievikki, ColorBlueiisoppi, ColorBluelobelia, //95 + ColorWhiteojaka, ColorWhitepetunia, ColorWhitepelargonia, ColorWhitepaeivaen, JDC468_B14_75Redspect,//100 + ColorGreenkoriste, ColorGreenpoimulehti, ColorGreenhopeapaju, //103 + ColorReduuden, ColorRedpajuan, ColorRedjaloan, ColorBlueukon, ColorBlueorvokki, ColorBluemalvikki, //109 + ColorBlackmaito, ColorOrangpihlaja, ColorBlackpihlaja, //112 + ColorViolA1_spect, ColorViolA4_spect, ColorViolA6_spect, ColorBlueSkyK3_spect, ColorBlueSkyK9_spect, //117 + ColorBlueSkyC4_spect, ColorBlueSkyC14_spect, ColorBlueSkyE4_spect, //120 + ColorBlueSkyM1_spect, ColorBlueSky2B1_spect, ColorBlueSkyT7_spect, //123 + ColorBlueSkyU19_spect, ColorBlueSkyU2_spect, ColorBlueSkyT17_spect, //126 + ColorBlackM8_spect, ColorBlackM12_spect, ColorBlackM13_spect, ColorWhite2B12_spect, ColorWhite2B14_spect, //131 + JDC468_Blackred97_spect, JDC468_Blackredbl443_spect, JDC468_Blackbl27_spect, JDC468_Blackbl28_spect, //135 + JDC468_Blackgr214_spect, JDC468_Blackbl436_spect, JDC468_Whitebl455_spect, JDC468_Blackvio101_spect, JDC468_Whitebl92_spect, JDC468_Greyredbl94_spect, //141 + JDC468_Blue32_spect, JDC468_Blue236_spect, JDC468_Gre300_spect, //144 + JDC468_Blue340_spect, JDC468_Gree110_spect, JDC468_Gree457_spect, JDC468_Yel241_spect, JDC468_Ora321_spect, JDC468_Yellow353_spect, JDC468_Mag465_spect, //151 + JDC468_Mag333_spect, JDC468_Mag203_spect, J570_BlueB6_spect, J570_BlueB15_spect, J570_BlueC2_spect, J570_BlueC14_spect, J570_BlueC16_spect,//158 + J570_BlueF1_spect, J570_BlueF2_spect, J570_BlueF10_spect, J570_BlueF13_spect, J570_BlueG9_spect, J570_BlueG19_spect, J570_BlueI5_spect,//165 + J570_BlueI3_spect, J570_BlueI19_spect, J570_BlueJ4_spect, J570_BlueJ6_spect, J570_BlueJ11_spect, J570_BlueK5_spect, //171 + J570_BlueN1_spect, J570_BlueN4_spect, J570_BlueO19_spect, J570_BlueU8_spect, J570_NeuN8_spect,//176 + J570_NeuN9_spect, J570_NeuO8_spect, J570_NeuO11_spect, J570_NeuD5_spect,//180 + J570_NeuE11_spect, J570_NeuK16_spect, J570_NeuM3_spect, J570_NeuN18_spect, + J570_NeuQ1_spect, J570_NeuS7_spect, + J570_NeuV10_spect, J570_NeuW18_spect, J570_NeuZ14_spect, //189 + J570_NeuC18_spect, J570_NeuD17_spect, J570_NeuJ11_spect, J570_NeuL4_spect, Colorlab_n72_n2_spect, + Colorlab_10_n70_spect, Colorlab_n33_n70_spect, Colorlab_n8_n74_spect, Colorlab_19_n69_spect, Colorlab_n80_10_spect, Colorlab_n80_26_spect, + Colorlab_n80_5_9_5_9spect //, Colorlab_n57_5_6_9spect + + /*JDC468_greyc14_66_spect, JDC468_greym13_325_spect, JDC468_greyf26_156_spect*/ + }; + + + typedef struct WbTxyz { + double Tem; + double XX; + double ZZ; + } WbTxyz; + //probbaly can be "passed" with rawimagesource.cc but I don't know how to do. + constexpr WbTxyz Txyz[118] = {//temperature Xwb Zwb 118 values - same table as in Rawimagesource.cc x wb and y wb are calculated after + {2001., 1.273842, 0.145295}, + {2101., 1.244008, 0.167533}, + {2201., 1.217338, 0.190697}, + {2301., 1.193444, 0.214632}, + {2401., 1.171996, 0.239195}, + {2501., 1.152883, 0.264539}, + {2605., 1.134667, 0.290722}, + {2655., 1.126659, 0.303556}, + {2705., 1.119049, 0.316446}, + {2755., 1.111814, 0.329381}, + {2803., 1.105381, 0.342193}, + {2856., 1.098258, 0.355599}, + {2910., 1.091550, 0.369645}, + {2960., 1.085649, 0.382655}, + {3003., 1.080982, 0.394258}, + {3050., 1.075727, 0.406057}, + {3103., 1.070277, 0.419815}, + {3153., 1.065384, 0.432769}, + {3203., 1.060906, 0.446161}, + {3250., 1.056535, 0.457806}, + {3303., 1.052034, 0.471422}, + {3353., 1.047990, 0.484218}, + {3400., 1.044547, 0.496719}, + {3450., 1.040667, 0.508891}, + {3500., 1.037145, 0.521523}, + {3550., 1.033783, 0.534090}, + {3600., 1.030574, 0.546590}, + {3650., 1.027510, 0.559020}, + {3699., 1.024834, 0.571722}, + {3801., 1.019072, 0.596102}, + {3851., 1.016527, 0.608221}, + {3902., 1.014244, 0.621136}, + {3952., 1.011729, 0.632447}, + {4002., 0.996153, 0.609518}, + {4052., 0.993720, 0.620805}, + {4102., 0.993908, 0.631520}, + {4152., 0.989179, 0.643262}, + {4202., 0.989283, 0.653999}, + {4252., 0.985039, 0.665536}, + {4302., 0.985067, 0.676288}, + {4352., 0.981271, 0.687599}, + {4402., 0.981228, 0.698349}, + {4452., 0.977843, 0.709425}, + {4502., 0.977736, 0.720159}, + {4552., 0.974728, 0.730993}, + {4602., 0.974562, 0.741698}, + {4652., 0.971899, 0.752284}, + {4702., 0.971681, 0.762949}, + {4752., 0.969335, 0.773285}, + {4802., 0.969069, 0.783899}, + {4827., 0.967570, 0.788836}, + {4852., 0.967011, 0.793982}, + {4877., 0.966465, 0.799108}, + {4902., 0.965933, 0.804214}, + {4927., 0.965414, 0.809229}, + {4952., 0.964908, 0.814366}, + {4977., 0.964415, 0.819412}, + {5002., 0.963934, 0.824438}, + {5027., 0.963465, 0.829444}, + {5052., 0.963008, 0.834429}, + {5077., 0.962563, 0.839395}, + {5102., 0.962129, 0.844339}, + {5127., 0.961706, 0.849263}, + {5152., 0.961294, 0.854166}, + {5177., 0.960893, 0.859049}, + {5202., 0.960501, 0.863911}, + {5252., 0.959749, 0.873572}, + {5302., 0.959313, 0.883815}, + {5352., 0.958361, 0.892644}, + {5402., 0.957903, 0.902793}, + {5452., 0.957116, 0.911379}, + {5502., 0.956639, 0.921431}, + {5552., 0.956002, 0.929779}, + {5602., 0.955509, 0.939728}, + {5652., 0.955008, 0.947842}, + {5702., 0.954502, 0.957685}, + {5752., 0.954124, 0.965569}, + {5802., 0.953608, 0.975303}, + {5852., 0.953342, 0.982963}, + {5902., 0.952818, 0.992584}, + {5952., 0.952652, 1.000025}, + {6002., 0.952122, 1.009532}, + {6052., 0.952047, 1.016759}, + {6102., 0.951514, 1.026149}, + {6152., 0.951520, 1.033168}, + {6202., 0.950985, 1.042439}, + {6252., 0.951064, 1.049256}, + {6302., 0.950530, 1.058406}, + {6352., 0.950674, 1.065027}, + {6402., 0.950143, 1.074055}, + {6452., 0.950345, 1.080484}, + {6502., 0.950201, 1.088097}, + {6552., 0.950070, 1.095633}, + {6602., 0.949952, 1.103094}, + {6652., 0.949846, 1.110479}, + {6702., 0.949752, 1.119138}, + {6752., 0.949668, 1.125027}, + {6802., 0.949596, 1.132190}, + {6902., 0.949033, 1.147691}, + {7002., 0.949402, 1.160129}, + {7152., 0.949348, 1.180429}, + {7301., 0.948896, 1.201432}, + {7451., 0.949434, 1.219076}, + {7601., 0.949099, 1.239061}, + {7751., 0.949729, 1.255559}, + {7901., 0.949498, 1.274460}, + {8151., 0.950361, 1.300912}, + {8301., 0.950253, 1.318464}, + {8451., 0.950966, 1.332651}, + {8601., 0.950941, 1.349261}, + {8801., 0.951772, 1.367421}, + {9001., 0.951969, 1.387639}, + {9201., 0.952784, 1.404422}, + {9401., 0.953081, 1.423213}, + {9901., 0.954537, 1.464134}, + {10501., 0.956321, 1.508623}, + {11001., 0.957747, 1.541281}, + {12001., 0.960440, 1.601019} + }; + + int N_c = sizeof(spec_colorforxcyc) / sizeof(spec_colorforxcyc[0]); //number of color + int N_t = sizeof(Txyz) / sizeof(Txyz[0]); //number of temperature White point + typedef struct XYZref { + double Xref; + double Yref; + double Zref; + } XYZref; + XYZref Refxyz[N_c + 1]; + + for (int i = 0; i < N_c; i++) { + Refxyz[i].Xref = 0.f; + Refxyz[i].Yref = 0.f; + Refxyz[i].Zref = 0.f; + } + + if (settings->verbose) { + if (settings->itcwb_stdobserver10 == false) { + printf("Use standard observer 2°\n"); + } else { + printf("Use standard observer 10°\n"); + } + } + + if (settings->itcwb_stdobserver10 == false) { + for (int i = 0; i < 97; i++) { + cie_colour_match_jd[i][0] = cie_colour_match_jd2[i][0]; + cie_colour_match_jd[i][1] = cie_colour_match_jd2[i][1];; + cie_colour_match_jd[i][2] = cie_colour_match_jd2[i][2]; + } + } + + if (separated) { + const double tempw = Txyz[repref].Tem; + + if (tempw <= INITIALBLACKBODY) { + for (int i = 0; i < N_c; i++) { + spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, TX[i], TY[i], TZ[i]); + } + } else { + double m11, m22, x_DD, y_DD, interm2; + + if (tempw <= 7000) { + x_DD = -4.6070e9 / (tempw * tempw * tempw) + 2.9678e6 / (tempw * tempw) + 0.09911e3 / tempw + 0.244063; + } else { + x_DD = -2.0064e9 / (tempw * tempw * tempw) + 1.9018e6 / (tempw * tempw) + 0.24748e3 / tempw + 0.237040; + } + + y_DD = -3.0 * x_DD * x_DD + 2.87 * x_DD - 0.275; + //calculate D -daylight in function of s0, s1, s2 and temp ==> x_D y_D + //S(lamda)=So(lambda)+m1*s1(lambda)+m2*s2(lambda) + interm2 = (0.0241 + 0.2562 * x_DD - 0.734 * y_DD); + m11 = (-1.3515 - 1.7703 * x_DD + 5.9114 * y_DD) / interm2; + m22 = (0.03 - 31.4424 * x_DD + 30.0717 * y_DD) / interm2; + + for (int i = 0; i < N_c; i++) { + spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, TX[i], TY[i], TZ[i]); + } + } + } else { + for (int tt = 0; tt < N_t; tt++) { + const double tempw = Txyz[tt].Tem; + + if (tempw <= INITIALBLACKBODY) { + for (int i = 0; i < N_c; i++) { + spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref); + } + } else { + double x_DD; + + if (tempw <= 7000) { + x_DD = -4.6070e9 / (tempw * tempw * tempw) + 2.9678e6 / (tempw * tempw) + 0.09911e3 / tempw + 0.244063; + } else { + x_DD = -2.0064e9 / (tempw * tempw * tempw) + 1.9018e6 / (tempw * tempw) + 0.24748e3 / tempw + 0.237040; + } + + const double y_DD = -3.0 * x_DD * x_DD + 2.87 * x_DD - 0.275; + //calculate D -daylight in function of s0, s1, s2 and temp ==> x_D y_D + //S(lamda)=So(lambda)+m1*s1(lambda)+m2*s2(lambda) + const double interm2 = (0.0241 + 0.2562 * x_DD - 0.734 * y_DD); + const double m11 = (-1.3515 - 1.7703 * x_DD + 5.9114 * y_DD) / interm2; + const double m22 = (0.03 - 31.4424 * x_DD + 30.0717 * y_DD) / interm2; + + for (int i = 0; i < N_c; i++) { + spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref); + } + } + + for (int i = 0; i < N_c; i++) { + Tx[i][tt] = Refxyz[i].Xref; + Ty[i][tt] = Refxyz[i].Yref; + Tz[i][tt] = Refxyz[i].Zref; + } + } + } +} + } diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h index a38e01072..89c324490 100644 --- a/rtengine/colortemp.h +++ b/rtengine/colortemp.h @@ -21,6 +21,7 @@ #include #include #include +#include "procparams.h" namespace rtengine { @@ -53,6 +54,7 @@ public: explicit ColorTemp (double e) : temp(-1.), green(-1.), equal (e), method("Custom") {} ColorTemp (double t, double g, double e, const std::string &m); ColorTemp (double mulr, double mulg, double mulb, double e); + static void tempxy(bool separated, int repref, float **Tx, float **Ty, float **Tz, float **Ta, float **Tb, float **TL, double *TX, double *TY, double *TZ, const procparams::WBParams & wbpar); void update (const double rmul, const double gmul, const double bmul, const double equal, const double tempBias=0.0) { @@ -95,6 +97,8 @@ public: static void temp2mulxyz (double tem, const std::string &method, double &Xxyz, double &Zxyz); static void cieCAT02(double Xw, double Yw, double Zw, double &CAM02BB00, double &CAM02BB01, double &CAM02BB02, double &CAM02BB10, double &CAM02BB11, double &CAM02BB12, double &CAM02BB20, double &CAM02BB21, double &CAM02BB22, double adap ); + static void cieCAT02float(float Xw, float Yw, float Zw, float &CAM02BB00, float &CAM02BB01, float &CAM02BB02, float &CAM02BB10, float &CAM02BB11, float &CAM02BB12, float &CAM02BB20, float &CAM02BB21, float &CAM02BB22, float adap); + static void icieCAT02float(float Xw, float Yw, float Zw, float &iCAM02BB00, float &iCAM02BB01, float &iCAM02BB02, float &iCAM02BB10, float &iCAM02BB11, float &iCAM02BB12, float &iCAM02BB20, float &iCAM02BB21, float &iCAM02BB22, float adap); bool operator== (const ColorTemp& other) const { @@ -162,6 +166,125 @@ public: static const double ColorchechGreD1_spect[97]; static const double ColorchechSGBlaN3_6_spect[97];//ColorChecker SG N3 static const double JDC468_GraK14_44_spect[97];//468 K14 + static const double JDC468_BluM5_spect[97]; //468 M5 + static const double JDC468_BluD6_spect[97]; //468 D6 + static const double JDC468_BluF4_spect[97]; //468 F4 + static const double JDC468_RedG21va_spect[97]; //468 G21 modifié + static const double JDC468_RedI9_spect[97]; //468 I9 + static const double JDC468_GreI8_spect[97]; //468 I8 + static const double JDC468_GreQ7_spect[97]; //468 Q7 + static const double ColorGreenM25_spect[97]; + static const double ColorYellowkeltano_spect[97]; + static const double ColorGreenalsi_spect[97]; + static const double ColorRedpetunia_spect[97]; + static const double ColorRedkurttu_spect[97]; + static const double ColorRedlupiini_spect[97]; + static const double ColorRedhevosminttu_spect[97]; + static const double ColorRedneilikka_spect[97]; + static const double ColorRedpelagornia_spect[97]; + static const double ColorRedtalvio_spect[97]; + static const double ColorBrownpoimulehti_spect[97]; + static const double ColorOrangetuntematon_spect[97]; + static const double ColorOrangetlehmus_spect[97]; + static const double ColorOrangvaahtera_spect[97]; + static const double ColorBrownlehmus_spect[97]; + static const double ColorBrownuotiosammal_spect[97]; + static const double ColorBlacksoil_spect[97]; + static const double ColorGraynahjajaekaelae_spect[97]; + static const double ColorGreennuotisammal_spect[97]; + static const double ColorGreenleskenlehti_spect[97]; + static const double ColorGreenlinnunkaali_spect[97]; + static const double ColorGreenpelto_spect[97]; + static const double ColorGreenrodvoikukka[97]; + static const double ColorGreenlehmus[97]; + static const double ColorGreenlinden[97]; + static const double ColorYellowlehmus[97]; + static const double ColorYellowsuikeroalpi[97]; + static const double ColorYellowpensashanhikki1[97]; + static const double ColorYellowpensashanhikki2[97]; + static const double ColorBluehiidenvirna[97]; + static const double ColorBluekurkkuyrtti[97]; + static const double ColorPinksiankaersaemoe[97]; + static const double ColorVioletharakankello[97]; + static const double ColorVioletalsikeapila[97]; + static const double ColorVioletakilleija[97]; + static const double ColorOrangekehaekukka[97]; + static const double ColorRedpihlaja[97]; + static const double ColorVioletpetunia[97]; + static const double ColorVioletorvokki[97]; + static const double ColorBluesinisievikki[97]; + static const double ColorBlueiisoppi[97]; + static const double ColorBluelobelia[97]; + static const double ColorWhiteojaka[97]; + static const double ColorWhitepetunia[97]; + static const double ColorWhitepelargonia[97]; + static const double ColorWhitepaeivaen[97]; + static const double JDC468_B14_75Redspect[97]; + static const double Colorblue_spect[97]; + static const double ColorGreenkoriste[97]; + static const double ColorGreenpoimulehti[97]; + static const double ColorGreenhopeapaju[97]; + static const double ColorReduuden[97]; + static const double ColorRedpajuan[97]; + static const double ColorRedjaloan[97]; + static const double ColorBlueukon[97]; + static const double ColorBlueorvokki[97]; + static const double ColorBluemalvikki[97]; + static const double ColorBlackmaito[97]; + static const double ColorOrangpihlaja[97]; + static const double ColorBlackpihlaja[97]; + static const double ColorViolA1_spect[97]; + static const double ColorViolA4_spect[97]; + static const double ColorViolA6_spect[97]; + static const double ColorBlueSkyK3_spect[97]; + static const double ColorBlueSkyK9_spect[97]; + static const double ColorBlueSkyC4_spect[97]; + static const double ColorBlueSkyC14_spect[97]; + static const double ColorBlueSkyE4_spect[97]; + static const double ColorBlueSkyM1_spect[97]; + static const double ColorBlueSky2B1_spect[97]; + static const double ColorBlueSkyT7_spect[97]; + static const double ColorBlueSkyU19_spect[97]; + static const double ColorBlueSkyU2_spect[97]; + static const double ColorBlueSkyT17_spect[97]; + static const double ColorBlackM8_spect[97]; + static const double ColorBlackM12_spect[97]; + static const double ColorBlackM13_spect[97]; + static const double ColorWhite2B12_spect[97]; + static const double ColorWhite2B14_spect[97]; + static const double JDC468_Blackred97_spect[97]; + static const double JDC468_Blackredbl443_spect[97]; + static const double JDC468_Blackbl27_spect[97]; + static const double JDC468_Blackbl28_spect[97]; + static const double JDC468_Blackgr214_spect[97]; + static const double JDC468_Blackbl436_spect[97]; + static const double JDC468_Whitebl455_spect[97]; + static const double JDC468_Blackvio101_spect[97]; + static const double JDC468_Whitebl92_spect[97]; + static const double JDC468_Greyredbl94_spect[97]; + static const double JDC468_Blue32_spect[97]; + static const double JDC468_Blue236_spect[97]; + static const double JDC468_Gre300_spect[97]; + static const double JDC468_Blue340_spect[97]; + static const double JDC468_Gree110_spect[97]; + static const double JDC468_Gree457_spect[97]; + static const double JDC468_Yel241_spect[97]; + static const double JDC468_Ora321_spect[97]; + static const double JDC468_Yellow353_spect[97]; + static const double JDC468_Mag465_spect[97]; + static const double JDC468_Mag333_spect[97]; + static const double JDC468_Mag203_spect[97]; + + + static const double JDC468_OraO18_spect[97]; //468 O18 + static const double JDC468_OraD17_spect[97]; //468 D17 + static const double Fictif_61greyspect[97];//468 K15 + static const double JDC468_K15_87greyspect[97]; + static const double JDC468_YelN10_spect[97]; //468 N10 + static const double JDC468_GreN7_spect[97]; //468 N7 + static const double JDC468_GreA10_spect[97]; //468 A10 + static const double JDC468_GreK7_spect[97]; //468 K7 + static const double JDC468_PurE24_spect[97]; //468 E24 static const double JDC468_BluH10_spect[97];//468 H10 static const double ColabSkin35_15_17_spect[97];//Skin L 35 static const double ColabSkin57_22_18_spect[97];//Skin L 57 @@ -195,7 +318,63 @@ public: static const double ColabSkin70_7_32_spect[97];//Skin L 77 static const double ColabSky60_0_m31_spect[97];//Sky L=60 static const double ColabSky42_0_m24_spect[97];//Sky L=42 - + static const double J570_BlueB6_spect[97];//blue Cyan + static const double J570_BlueB15_spect[97];//blue Cyan + static const double J570_BlueC2_spect[97];//blue Cyan + static const double J570_BlueC14_spect[97];//blue Cyan + static const double J570_BlueC16_spect[97];//blue Cyan + static const double J570_BlueF1_spect[97];//blue Cyan + static const double J570_BlueF2_spect[97];//blue Cyan + static const double J570_BlueF10_spect[97];//blue Cyan + static const double J570_BlueF13_spect[97];//blue Cyan + static const double J570_BlueG9_spect[97];//blue Cyan + static const double J570_BlueG19_spect[97];//blue Cyan + static const double J570_BlueI5_spect[97];//blue Cyan + static const double J570_BlueH15_spect[97];//blue Cyan + static const double J570_BlueI3_spect[97];//blue Cyan + static const double J570_BlueI19_spect[97];//blue Cyan + static const double J570_BlueJ4_spect[97];//blue Cyan + static const double J570_BlueJ6_spect[97];//blue Cyan + static const double J570_BlueJ11_spect[97];//blue Cyan + static const double J570_BlueJ13_spect[97];//blue Cyan + static const double J570_BlueK5_spect[97];//blue Cyan + static const double J570_BlueN1_spect[97];//blue Cyan + static const double J570_BlueN4_spect[97];//blue Cyan + static const double J570_BlueO19_spect[97];//blue Cyan + static const double J570_BlueU8_spect[97];//blue Cyan + static const double J570_NeuN8_spect[97];//neutral + static const double J570_NeuN9_spect[97];//neutral + static const double J570_NeuO8_spect[97];//neutral + static const double J570_NeuO11_spect[97];//neutral + static const double J570_NeuD5_spect[97];//neutral + static const double J570_NeuE11_spect[97];//neutral + static const double J570_NeuK16_spect[97];//neutral + static const double J570_NeuM3_spect[97];//neutral + static const double J570_NeuN18_spect[97];//neutral + static const double J570_NeuQ1_spect[97];//neutral + static const double J570_NeuS7_spect[97];//neutral + static const double J570_NeuV10_spect[97];//neutral + static const double J570_NeuW18_spect[97];//neutral + static const double J570_NeuZ14_spect[97];//neutral + static const double J570_NeuC18_spect[97];//neutral + static const double J570_NeuD17_spect[97];//neutral + static const double J570_NeuJ11_spect[97];//neutral + static const double J570_NeuL4_spect[97];//neutral + static const double Colorlab_n72_n2_spect[97]; + static const double Colorlab_10_n70_spect[97]; + static const double Colorlab_n33_n70_spect[97]; + static const double Colorlab_n8_n74_spect[97]; + static const double Colorlab_19_n69_spect[97]; + static const double Colorlab_n80_10_spect[97]; + static const double Colorlab_n80_26_spect[97]; + static const double Colorlab_n80_5_9_5_9spect[97]; +// static const double Colorlab_n57_5_6_9spect[97]; + + /* + static const double JDC468_greyc14_66_spect[97]; + static const double JDC468_greym13_325_spect[97]; + static const double JDC468_greyf26_156_spect[97]; + */ static void spectrum_to_xyz_daylight (double _m1, double _m2, double &x, double &y, double &z); static void spectrum_to_xyz_blackbody (double _temp, double &x, double &y, double &z); static void spectrum_to_xyz_preset (const double* spec_intens, double &x, double &y, double &z); diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 35cc34089..d81cb5780 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -32,6 +32,7 @@ #include "opthelper.h" #include "ciecam02.h" #include "color.h" +#include "iccmatrices.h" #include "iccstore.h" using namespace std; @@ -3082,6 +3083,41 @@ void WavCurve::Set(const std::vector &curvePoints) } } +Wavblcurve::Wavblcurve() {} + +void Wavblcurve::Reset() +{ + lutblcurve.reset(); +} + +void Wavblcurve::Set(const Curve &pCurve) +{ + if (pCurve.isIdentity()) { + Reset(); // raise this value if the quality suffers from this number of samples + return; + } + + lutblcurve(501); // raise this value if the quality suffers from this number of samples + + for (int i = 0; i < 501; i++) { + lutblcurve[i] = pCurve.getVal(double(i) / 500.); + } +} + +void Wavblcurve::Set(const std::vector &curvePoints) +{ + if (!curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { + FlatCurve tcurve(curvePoints, false, CURVES_MIN_POLY_POINTS / 2); + tcurve.setIdentityValue(0.); + Set(tcurve); + } else { + Reset(); + } + +} + + + WavOpacityCurveRG::WavOpacityCurveRG() {} diff --git a/rtengine/curves.h b/rtengine/curves.h index 5d9e19940..b88c8457b 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -295,11 +295,11 @@ public: } 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(sRGBGammaCurve)) - 0.055f; } 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(sRGBGammaCurve)); } // gamma function with adjustable parameters static inline double gamma(double x, double gamma, double start, double slope, double mul, double add) @@ -330,8 +330,8 @@ public: #endif static inline float hlcurve(const float exp_scale, const float comp, const float hlrange, float level) { - if (comp > 0.0) { - float val = level + (hlrange - 65536.0); + if (comp > 0.f) { + float val = level + (hlrange - 65536.f); if (val == 0.0f) { // to avoid division by zero val = 0.000001f; @@ -340,7 +340,7 @@ public: float Y = val * exp_scale / hlrange; Y *= comp; - if (Y <= -1.0) { // to avoid log(<=0) + if(Y <= -1.f) { // to avoid log(<=0) Y = -.999999f; } @@ -1429,6 +1429,30 @@ public: } }; +class Wavblcurve +{ +private: + LUTf lutblcurve; // 0xffff range + void Set(const Curve &pCurve); +public: + virtual ~Wavblcurve() {}; + Wavblcurve(); + + void Reset(); + // void Set(const std::vector &curvePoints, bool &opautili); + void Set(const std::vector &curvePoints); + float operator[](float index) const + { + return lutblcurve[index]; + } + + operator bool (void) const + { + return lutblcurve; + } +}; + + class WavOpacityCurveRG { private: diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 11fe306b8..89256bba4 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -1064,9 +1064,11 @@ void DCPProfile::apply( for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { + double temp = 0.0; 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 j = 0; j < 3; ++j) { + double temp = 0.0; 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 j = 0; j < 3; ++j) { + double temp = 0.0; 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,27 +1179,35 @@ void DCPProfile::setStep2ApplyState(const Glib::ustring& working_space, bool use mWork = ICCStore::getInstance()->workingSpaceMatrix (working_space); memset(as_out.data->pro_photo, 0, sizeof(as_out.data->pro_photo)); - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + double temp = 0.0; 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); memset(as_out.data->work, 0, sizeof(as_out.data->work)); - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + double temp = 0.0; 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; + } + } } } 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) float exp_scale = as_in.data->bl_scale; diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 537bf1334..29796ea67 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -62,12 +62,8 @@ $Date: 2018/06/01 20:36:25 $ */ -#define DCRAW_VERSION "9.28" +//#define DCRAW_VERSION "9.28" -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#define _USE_MATH_DEFINES #include #include #include @@ -94,8 +90,12 @@ #ifdef WIN32 #include #include +#ifndef strcasecmp #define strcasecmp stricmp +#endif +#ifndef strncasecmp #define strncasecmp strnicmp +#endif typedef __int64 INT64; typedef unsigned __int64 UINT64; #else @@ -6898,7 +6898,7 @@ it under the terms of the one of two licenses as you choose: break; case 50778: case 50779: - if( get2() == 21 ) + if( get2() != 17 ) // 17 is Standard light A cm_D65 = (tag-50778); break; case 50829: /* ActiveArea */ @@ -9077,9 +9077,6 @@ void CLASS adobe_coeff (const char *make, const char *model) if (RT_blacklevel_from_constant == ThreeValBool::X || is_pentax_dng) { RT_blacklevel_from_constant = ThreeValBool::T; } - if (RT_matrix_from_constant == ThreeValBool::X) { - RT_matrix_from_constant = ThreeValBool::T; - } // -- RT -------------------------------------------------------------------- for (i=0; i < sizeof table / sizeof *table; i++) @@ -9096,6 +9093,11 @@ void CLASS adobe_coeff (const char *make, const char *model) if (load_raw == &CLASS sony_arw2_load_raw) { // RT: arw2 scale fix black <<= 2; tiff_bps += 2; + } else if (load_raw == &CLASS panasonic_load_raw) { + tiff_bps = RT_pana_info.bpp; + } + if (RT_matrix_from_constant == ThreeValBool::X) { + RT_matrix_from_constant = ThreeValBool::T; } { /* Check for RawTherapee table overrides and extensions */ int black_level, white_level; @@ -10046,6 +10048,9 @@ canon_a5: } else if (!strncmp(model, "X-A3", 4) || !strncmp(model, "X-A5", 4)) { width = raw_width = 6016; height = raw_height = 4014; + } else if (!strcmp(model, "X-Pro3") || !strcmp(model, "X-T3") || !strcmp(model, "X-T30")) { + width = raw_width = 6384; + height = raw_height = 4182; } top_margin = (raw_height - height) >> 2 << 1; left_margin = (raw_width - width ) >> 2 << 1; @@ -10541,7 +10546,7 @@ dng_skip: * files. See #4129 */) { memcpy (rgb_cam, cmatrix, sizeof cmatrix); // raw_color = 0; - RT_matrix_from_constant = ThreeValBool::F; + RT_matrix_from_constant = ThreeValBool::X; } if(!strncmp(make, "Panasonic", 9) && !strncmp(model, "DMC-LX100",9)) adobe_coeff (make, model); diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 3de2f5e67..5cd29a1f9 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -30,7 +30,9 @@ #include "procparams.h" #include "refreshmap.h" #include "rt_math.h" +#include "color.h" #include "../rtgui/editcallbacks.h" +#include "guidedfilter.h" #pragma GCC diagnostic warning "-Wall" #pragma GCC diagnostic warning "-Wextra" @@ -816,6 +818,7 @@ void Crop::update(int todo) parent->ipf.workingtrc(workingCrop, workingCrop, cw, ch, 5, params.icm.workingProfile, params.icm.workingTRCGamma, params.icm.workingTRCSlope, parent->getCustomTransformOut(), false, true, true); } } + double rrm, ggm, bbm; DCPProfileApplyState as; DCPProfile *dcpProf = parent->imgsrc->getDCP(params.icm, as); @@ -825,6 +828,7 @@ void Crop::update(int todo) params.toneCurve.saturation, parent->rCurve, parent->gCurve, parent->bCurve, parent->colourToningSatLimit, parent->colourToningSatLimitOpacity, parent->ctColorCurve, parent->ctOpacityCurve, parent->opautili, parent->clToningcurve, parent->cl2Toningcurve, parent->customToneCurve1, parent->customToneCurve2, parent->beforeToneCurveBW, parent->afterToneCurveBW, rrm, ggm, bbm, parent->bwAutoR, parent->bwAutoG, parent->bwAutoB, dcpProf, as, histToneCurve); + if (workingCrop != baseCrop) { delete workingCrop; } @@ -1345,6 +1349,7 @@ void Crop::update(int todo) } WavCurve wavCLVCurve; + Wavblcurve wavblcurve; WavOpacityCurveRG waOpacityCurveRG; WavOpacityCurveBY waOpacityCurveBY; WavOpacityCurveW waOpacityCurveW; @@ -1352,12 +1357,176 @@ void Crop::update(int todo) LUTf wavclCurve; - params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + LabImage *unshar = nullptr; + Glib::ustring provis; + LabImage *provradius = nullptr; + bool procont = WaveParams.expcontrast; + bool prochro = WaveParams.expchroma; + bool proedge = WaveParams.expedge; + bool profin = WaveParams.expfinal; + bool proton = WaveParams.exptoning; + bool pronois = WaveParams.expnoise; - parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); - } + if(WaveParams.showmask) { + // WaveParams.showmask = false; + // WaveParams.expclari = true; + } + + + if (WaveParams.softrad > 0.f) { + provradius = new LabImage(labnCrop->W, labnCrop->H); + provradius->CopyFrom(labnCrop); + } + + + + if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { + + unshar = new LabImage(labnCrop->W, labnCrop->H); + provis = params.wavelet.CLmethod; + params.wavelet.CLmethod = "all"; + parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); + unshar->CopyFrom(labnCrop); + + params.wavelet.CLmethod = provis; + + WaveParams.expcontrast = false; + WaveParams.expchroma = false; + WaveParams.expedge = false; + WaveParams.expfinal = false; + WaveParams.exptoning = false; + WaveParams.expnoise = false; + } parent->ipf.softLight(labnCrop, params.softlight); + + parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); + + + if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { + WaveParams.expcontrast = procont; + WaveParams.expchroma = prochro; + WaveParams.expedge = proedge; + WaveParams.expfinal = profin; + WaveParams.exptoning = proton; + WaveParams.expnoise = pronois; + if (WaveParams.softrad > 0.f) { + array2D ble(labnCrop->W, labnCrop->H); + array2D guid(labnCrop->W, labnCrop->H); + Imagefloat *tmpImage = nullptr; + tmpImage = new Imagefloat(labnCrop->W, labnCrop->H); + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < labnCrop->H ; ir++) + for (int jr = 0; jr < labnCrop->W; jr++) { + float X, Y, Z; + float L = provradius->L[ir][jr]; + float a = provradius->a[ir][jr]; + float b = provradius->b[ir][jr]; + Color::Lab2XYZ(L, a, b, X, Y, Z); + + guid[ir][jr] = Y / 32768.f; + float La = labnCrop->L[ir][jr]; + float aa = labnCrop->a[ir][jr]; + float ba = labnCrop->b[ir][jr]; + Color::Lab2XYZ(La, aa, ba, X, Y, Z); + tmpImage->r(ir, jr) = X; + tmpImage->g(ir, jr) = Y; + tmpImage->b(ir, jr) = Z; + ble[ir][jr] = Y / 32768.f; + } + double epsilmax = 0.0001; + double epsilmin = 0.00001; + double aepsil = (epsilmax - epsilmin) / 90.f; + double bepsil = epsilmax - 100.f * aepsil; + double epsil = aepsil * WaveParams.softrad + bepsil; + + float blur = 10.f / skip * (0.0001f + 0.8f * WaveParams.softrad); + rtengine::guidedFilter(guid, ble, ble, blur, epsil, false); + + + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < labnCrop->H; ir++) + for (int jr = 0; jr < labnCrop->W; jr++) { + float X = tmpImage->r(ir, jr); + float Y = 32768.f * ble[ir][jr]; + float Z = tmpImage->b(ir, jr); + float L, a, b; + Color::XYZ2Lab(X, Y, Z, L, a, b); + labnCrop->L[ir][jr] = L; + } + delete tmpImage; + } + + } + + + if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { + + float mL = (float)(WaveParams.mergeL / 100.f); + float mC = (float)(WaveParams.mergeC / 100.f); + float mL0; + float mC0; + float background = 0.f; + int show = 0; + + if ((WaveParams.CLmethod == "one" || WaveParams.CLmethod == "inf") && WaveParams.Backmethod == "black") { + mL0 = mC0 = 0.f; + mL = -1.5f * mL; + mC = -mC; + background = 12000.f; + show = 0; + } else if (WaveParams.CLmethod == "sup" && WaveParams.Backmethod == "resid") { + mL0 = mL; + mC0 = mC; + background = 0.f; + show = 0; + } else { + mL0 = mL = mC0 = mC = 0.f; + background = 0.f; + show = 0; + } + + float indic = 1.f; + if(WaveParams.showmask){ + mL0 = mC0 = -1.f; + indic = -1.f; + mL = fabs(mL); + mC = fabs(mC); + show = 1; + } + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int x = 0; x < labnCrop->H; x++) + for (int y = 0; y < labnCrop->W; y++) { + labnCrop->L[x][y] = LIM((1.f + mL0) * (unshar->L[x][y]) + show * background - mL * indic * labnCrop->L[x][y], 0.f, 32768.f); + labnCrop->a[x][y] = (1.f + mC0) * (unshar->a[x][y]) - mC * indic * labnCrop->a[x][y]; + labnCrop->b[x][y] = (1.f + mC0) * (unshar->b[x][y]) - mC * indic * labnCrop->b[x][y]; + } + + delete unshar; + unshar = NULL; + if (WaveParams.softrad > 0.f) { + delete provradius; + provradius = NULL; + } + + + } + + + } if (params.colorappearance.enabled) { float fnum = parent->imgsrc->getMetaData()->getFNumber(); // F number diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc index 538858a9a..a31415968 100644 --- a/rtengine/demosaic_algos.cc +++ b/rtengine/demosaic_algos.cc @@ -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) { 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]); } } diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc index 1fb1d2e1b..6961a4b54 100644 --- a/rtengine/dfmanager.cc +++ b/rtengine/dfmanager.cc @@ -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 ; } } diff --git a/rtengine/diagonalcurves.cc b/rtengine/diagonalcurves.cc index e81f2fe92..622683ea2 100644 --- a/rtengine/diagonalcurves.cc +++ b/rtengine/diagonalcurves.cc @@ -63,23 +63,23 @@ DiagonalCurve::DiagonalCurve (const std::vector& 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 // not reaching the limits { 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) { - 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) { - x[0] = 0.99f; + x[0] = 0.99; } if (!identity) { @@ -95,7 +95,7 @@ DiagonalCurve::DiagonalCurve (const std::vector& p, int poly_pn) } } } 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; x = new double[9]; diff --git a/rtengine/dirpyr_equalizer.cc b/rtengine/dirpyr_equalizer.cc index 9d48bea47..ccd834bb4 100644 --- a/rtengine/dirpyr_equalizer.cc +++ b/rtengine/dirpyr_equalizer.cc @@ -231,11 +231,11 @@ void fillLut(LUTf &irangefn, int level, double dirpyrThreshold, float mult, floa } const float offs = skinprot == 0.f ? 0.f : -1.f; - constexpr float noise = 2000.f; - const float noisehi = 1.33f * noise * dirpyrThreshold / expf(level * log(3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf(level * log(3.0)); + constexpr double noise = 2000.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++) { - if (abs(i - 0x10000) > noisehi || multbis < 1.0) { + if (abs(i - 0x10000) > noisehi || multbis < 1.f) { irangefn[i] = multbis + offs; } else { if (abs(i - 0x10000) < noiselo) { @@ -307,7 +307,7 @@ void idirpyr_eq_channel(const float * const * data_coarse, const float * const * buffer[i][j] += irangefn[hipass + 0x10000] * hipass; } } - } else if (skinprot > 0.f) { + } else if (skinprot > 0.0) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif @@ -359,7 +359,7 @@ void idirpyr_eq_channelcam(const float * const * data_coarse, const float * cons buffer[i][j] += irangefn[hipass + 0x10000] * hipass; } } - } else if (skinprot > 0.f) { + } else if (skinprot > 0.0) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif diff --git a/rtengine/dual_demosaic_RT.cc b/rtengine/dual_demosaic_RT.cc index 93508808c..253468a76 100644 --- a/rtengine/dual_demosaic_RT.cc +++ b/rtengine/dual_demosaic_RT.cc @@ -45,7 +45,7 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams { BENCHFUN - if (contrast == 0.f && !autoContrast) { + if (contrast == 0.0 && !autoContrast) { // contrast == 0.0 means only first demosaicer will be used if(isBayer) { 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 JaggedArray blend(winw, winh); - float contrastf = contrast / 100.f; + float contrastf = contrast / 100.0; buildBlendMask(L, blend, winw, winh, contrastf, autoContrast); contrast = contrastf * 100.f; diff --git a/rtengine/eahd_demosaic.cc b/rtengine/eahd_demosaic.cc index ad4bda3cd..009be0714 100644 --- a/rtengine/eahd_demosaic.cc +++ b/rtengine/eahd_demosaic.cc @@ -360,8 +360,8 @@ void RawImageSource::eahd_demosaic () int wh = 0; - for (int dmi = 0; dmi < 9; dmi++) { - wh += (dLmaph[dmi] <= eL) * (dCamaph[dmi] <= eCa) * (dCbmaph[dmi] <= eCb); + for (int d = 0; d < 9; ++d) { + wh += (dLmaph[d] <= eL) * (dCamaph[d] <= eCa) * (dCbmaph[d] <= eCb); } homh[imx][j - 1] += wh; @@ -376,8 +376,8 @@ void RawImageSource::eahd_demosaic () int wv = 0; - for (int dmi = 0; dmi < 9; dmi++) { - wv += (dLmapv[dmi] <= eL) * (dCamapv[dmi] <= eCa) * (dCbmapv[dmi] <= eCb); + for (int d = 0; d < 9; ++d) { + wv += (dLmapv[d] <= eL) * (dCamapv[d] <= eCa) * (dCbmapv[d] <= eCb); } homv[imx][j - 1] += wv; diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index ce60277e1..c55bc5108 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -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 ; } } diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 1f27983ed..6d4fe1ad6 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -35,6 +35,9 @@ namespace { +using rtengine::ST_BAYER; +using rtengine::ST_FUJI_XTRANS; +using rtengine::settings; bool channelsAvg( const rtengine::RawImage* ri, @@ -43,17 +46,16 @@ bool channelsAvg( const float* cblacksom, rtengine::Coord spotPos, int spotSize, - const rtengine::procparams::FilmNegativeParams& params, std::array& avgs ) { avgs = {}; // Channel averages - if (ri->getSensorType() != rtengine::ST_BAYER && ri->getSensorType() != rtengine::ST_FUJI_XTRANS) { + if (ri->getSensorType() != ST_BAYER && ri->getSensorType() != ST_FUJI_XTRANS) { return false; } - if (rtengine::settings->verbose) { + if (settings->verbose) { printf("Spot coord: x=%d y=%d\n", spotPos.x, spotPos.y); } @@ -69,9 +71,10 @@ bool channelsAvg( } std::array pxCount = {}; // Per-channel sample counts + for (int c = x1; c < x2; ++c) { for (int r = y1; r < y2; ++r) { - const int ch = ri->getSensorType() == rtengine::ST_BAYER ? ri->FC(r,c) : ri->XTRANSFC(r,c); + const int ch = ri->getSensorType() == ST_BAYER ? ri->FC(r, c) : ri->XTRANSFC(r, c); ++pxCount[ch]; @@ -88,6 +91,112 @@ bool channelsAvg( return true; } +void calcMedians( + const rtengine::RawImage* ri, + float** data, + int x1, int y1, int x2, int y2, + std::array& meds +) +{ + + MyTime t1, t2, t3; + t1.set(); + + // Channel vectors to calculate medians + std::array, 3> cvs; + + // Sample one every 5 pixels, and push the value in the appropriate channel vector. + // Choose an odd step, not a multiple of the CFA size, to get a chance to visit each channel. + if (ri->getSensorType() == ST_BAYER) { + for (int row = y1; row < y2; row += 5) { + const int c0 = ri->FC(row, x1 + 0); + const int c1 = ri->FC(row, x1 + 5); + int col = x1; + + for (; col < x2 - 5; col += 10) { + cvs[c0].push_back(data[row][col]); + cvs[c1].push_back(data[row][col + 5]); + } + + if (col < x2) { + cvs[c0].push_back(data[row][col]); + } + } + } else if (ri->getSensorType() == ST_FUJI_XTRANS) { + for (int row = y1; row < y2; row += 5) { + const std::array cs = { + ri->XTRANSFC(row, x1 + 0), + ri->XTRANSFC(row, x1 + 5), + ri->XTRANSFC(row, x1 + 10), + ri->XTRANSFC(row, x1 + 15), + ri->XTRANSFC(row, x1 + 20), + ri->XTRANSFC(row, x1 + 25) + }; + int col = x1; + + for (; col < x2 - 25; col += 30) { + for (int c = 0; c < 6; ++c) { + cvs[cs[c]].push_back(data[row][col + c * 5]); + } + } + + for (int c = 0; col < x2; col += 5, ++c) { + cvs[cs[c]].push_back(data[row][col]); + } + } + } + + t2.set(); + + if (settings->verbose) { + printf("Median vector fill loop time us: %d\n", t2.etime(t1)); + } + + t2.set(); + + for (int c = 0; c < 3; ++c) { + // Find median values for each channel + if (!cvs[c].empty()) { + rtengine::findMinMaxPercentile(cvs[c].data(), cvs[c].size(), 0.5f, meds[c], 0.5f, meds[c], true); + } + } + + t3.set(); + + if (settings->verbose) { + printf("Sample count: R=%zu, G=%zu, B=%zu\n", cvs[0].size(), cvs[1].size(), cvs[2].size()); + printf("Median calc time us: %d\n", t3.etime(t2)); + } + +} + +std::array calcWBMults( + const rtengine::ColorTemp& wb, + const rtengine::ImageMatrices& imatrices, + const rtengine::RawImage *ri, + const float ref_pre_mul[4]) +{ + std::array wb_mul; + double r, g, b; + wb.getMultipliers(r, g, b); + wb_mul[0] = imatrices.cam_rgb[0][0] * r + imatrices.cam_rgb[0][1] * g + imatrices.cam_rgb[0][2] * b; + wb_mul[1] = imatrices.cam_rgb[1][0] * r + imatrices.cam_rgb[1][1] * g + imatrices.cam_rgb[1][2] * b; + wb_mul[2] = imatrices.cam_rgb[2][0] * r + imatrices.cam_rgb[2][1] * g + imatrices.cam_rgb[2][2] * b; + + for (int c = 0; c < 3; ++c) { + wb_mul[c] = ri->get_pre_mul(c) / wb_mul[c] / ref_pre_mul[c]; + } + + // Normalize max channel gain to 1.0 + float mg = rtengine::max(wb_mul[0], wb_mul[1], wb_mul[2]); + + for (int c = 0; c < 3; ++c) { + wb_mul[c] /= mg; + } + + return wb_mul; +} + } bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D spotB, int tran, const procparams::FilmNegativeParams ¤tParams, std::array& newExps) @@ -104,26 +213,34 @@ bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D s std::array clearVals; std::array denseVals; + // Get channel averages in the two spots, sampling from the original ri->data buffer. + // NOTE: rawData values might be affected by CA corection, FlatField, etc, so: + // rawData[y][x] == (ri->data[y][x] - cblacksom[c]) * scale_mul[c] + // is not always true. To calculate exponents on the exact values, we should keep + // a copy of the rawData buffer after preprocessing. Worth the memory waste? + // Sample first spot transformPosition(spotA.x, spotA.y, tran, spot.x, spot.y); - if (!channelsAvg(ri, W, H, cblacksom, spot, spotSize, currentParams, clearVals)) { + + if (!channelsAvg(ri, W, H, cblacksom, spot, spotSize, clearVals)) { return false; } // Sample second spot transformPosition(spotB.x, spotB.y, tran, spot.x, spot.y); - if (!channelsAvg(ri, W, H, cblacksom, spot, spotSize, currentParams, denseVals)) { + + if (!channelsAvg(ri, W, H, cblacksom, spot, spotSize, denseVals)) { return false; } // Detect which one is the dense spot, based on green channel if (clearVals[1] < denseVals[1]) { - std::swap(clearVals, denseVals); + std::swap(clearVals, denseVals); } if (settings->verbose) { - printf("Clear film values: R=%g G=%g B=%g\n", clearVals[0], clearVals[1], clearVals[2]); - printf("Dense film values: R=%g G=%g B=%g\n", denseVals[0], denseVals[1], denseVals[2]); + printf("Clear film values: R=%g G=%g B=%g\n", static_cast(clearVals[0]), static_cast(clearVals[1]), static_cast(clearVals[2])); + printf("Dense film values: R=%g G=%g B=%g\n", static_cast(denseVals[0]), static_cast(denseVals[1]), static_cast(denseVals[2])); } const float denseGreenRatio = clearVals[1] / denseVals[1]; @@ -141,18 +258,43 @@ bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D s if (ch == 1) { newExps[ch] = 1.f; // Green is the reference channel } 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) { - 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(newExps[0]), static_cast(newExps[1]), static_cast(newExps[2])); } return true; } -void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams ¶ms) +bool rtengine::RawImageSource::getRawSpotValues(Coord2D spotCoord, int spotSize, int tran, const procparams::FilmNegativeParams ¶ms, std::array& rawValues) +{ + Coord spot; + transformPosition(spotCoord.x, spotCoord.y, tran, spot.x, spot.y); + + if (settings->verbose) { + printf("Transformed coords: %d,%d\n", spot.x, spot.y); + } + + if (spotSize < 4) { + return false; + } + + // Calculate averages of raw unscaled channels + if (!channelsAvg(ri, W, H, cblacksom, spot, spotSize, rawValues)) { + return false; + } + + if (settings->verbose) { + printf("Raw spot values: R=%g, G=%g, B=%g\n", rawValues[0], rawValues[1], rawValues[2]); + } + + return true; +} + +void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams ¶ms, std::array& filmBaseValues) { // BENCHFUNMICRO @@ -168,92 +310,114 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ static_cast(-params.blueRatio * params.greenExp) }; - MyTime t1, t2, t3,t4, t5; - - t1.set(); - - // Channel vectors to calculate medians - std::array, 3> cvs; - - // Sample one every 5 pixels, and push the value in the appropriate channel vector. - // Choose an odd step, not a multiple of the CFA size, to get a chance to visit each channel. - if (ri->getSensorType() == ST_BAYER) { - for (int row = 0; row < H; row += 5) { - const int c0 = ri->FC(row, 0); - const int c1 = ri->FC(row, 5); - int col = 0; - for (; col < W - 5; col += 10) { - cvs[c0].push_back(rawData[row][col]); - cvs[c1].push_back(rawData[row][col + 5]); - } - if (col < W) { - cvs[c0].push_back(rawData[row][col]); - } - } - } - else if (ri->getSensorType() == ST_FUJI_XTRANS) { - for (int row = 0; row < H; row += 5) { - const std::array cs = { - ri->XTRANSFC(row, 0), - ri->XTRANSFC(row, 5), - ri->XTRANSFC(row, 10), - ri->XTRANSFC(row, 15), - ri->XTRANSFC(row, 20), - ri->XTRANSFC(row, 25) - }; - int col = 0; - for (; col < W - 25; col += 30) { - for (int c = 0; c < 6; ++c) { - cvs[cs[c]].push_back(rawData[row][col + c * 5]); - } - } - for (int c = 0; col < W; col += 5, ++c) { - cvs[cs[c]].push_back(rawData[row][col]); - } - } - } - constexpr float MAX_OUT_VALUE = 65000.f; - t2.set(); + // Get multipliers for a known, fixed WB setting, that will be the starting point + // for balancing the converted image. + const std::array wb_mul = calcWBMults( + ColorTemp(3500., 1., 1., "Custom"), imatrices, ri, ref_pre_mul); - if (settings->verbose) { - printf("Median vector fill loop time us: %d\n", t2.etime(t1)); + + if (rtengine::settings->verbose) { + printf("Fixed WB mults: %g %g %g\n", wb_mul[0], wb_mul[1], wb_mul[2]); } - t2.set(); + // Compensation factor to restore the non-autoWB initialGain (see RawImageSource::load) + const float autoGainComp = camInitialGain / initialGain; - std::array medians; // Channel median values - std::array mults = { - 1.f, - 1.f, - 1.f - }; // Channel normalization multipliers + std::array mults; // Channel normalization multipliers + + // If film base values are set in params, use those + if (filmBaseValues[0] <= 0.f) { + // ...otherwise, the film negative tool might have just been enabled on this image, + // whithout any previous setting. So, estimate film base values from channel medians + + std::array medians; + + // Special value for backwards compatibility with profiles saved by RT 5.7 + const bool oldChannelScaling = filmBaseValues[0] == -1.f; + + // If using the old channel scaling method, get medians from the whole current image, + // reading values from the already-scaled rawData buffer. + if (oldChannelScaling) { + calcMedians(ri, rawData, 0, 0, W, H, medians); + } else { + // Cut 20% border from medians calculation. It will probably contain outlier values + // from the film holder, which will bias the median result. + const int bW = W * 20 / 100; + const int bH = H * 20 / 100; + calcMedians(ri, rawData, bW, bH, W - bW, H - bH, medians); + } + + // Un-scale rawData medians + for (int c = 0; c < 3; ++c) { + medians[c] /= scale_mul[c]; + } + + if (settings->verbose) { + printf("Channel medians: R=%g, G=%g, B=%g\n", medians[0], medians[1], medians[2]); + } + + for (int c = 0; c < 3; ++c) { + + // Estimate film base values, so that in the output data, each channel + // median will correspond to 1/24th of MAX. + filmBaseValues[c] = pow_F(24.f / 512.f, 1.f / exps[c]) * medians[c]; + + if (oldChannelScaling) { + // If using the old channel scaling method, apply WB multipliers here to undo their + // effect later, since fixed wb compensation was not used in previous version. + // Also, undo the effect of the autoGainComp factor (see below). + filmBaseValues[c] /= pow_F((wb_mul[c] / autoGainComp), 1.f / exps[c]);// / autoGainComp; + } - for (int c = 0; c < 3; ++c) { - // Find median values for each channel - if (!cvs[c].empty()) { - findMinMaxPercentile(cvs[c].data(), cvs[c].size(), 0.5f, medians[c], 0.5f, medians[c], true); - medians[c] = pow_F(rtengine::max(medians[c], 1.f), exps[c]); - // Determine the channel multiplier so that N times the median becomes 65k. This clips away - // the values in the dark border surrounding the negative (due to the film holder, for example), - // the reciprocal of which have blown up to stellar values. - mults[c] = MAX_OUT_VALUE / (medians[c] * 24.f); } } - t3.set(); + + // Calculate multipliers based on previously obtained film base input values. + + // Apply current scaling coefficients to raw, unscaled base values. + std::array fb = { + filmBaseValues[0] * scale_mul[0], + filmBaseValues[1] * scale_mul[1], + filmBaseValues[2] * scale_mul[2] + }; if (settings->verbose) { - 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("Computed multipliers: %g %g %g\n", mults[0], mults[1], mults[2] ); - printf("Median calc time us: %d\n", t3.etime(t2)); + printf("Input film base values: %g %g %g\n", fb[0], fb[1], fb[2]); } + for (int c = 0; c < 3; ++c) { + // Apply channel exponents, to obtain the corresponding base values in the output data + fb[c] = pow_F(rtengine::max(fb[c], 1.f), exps[c]); + + // Determine the channel multiplier so that the film base value is 1/512th of max. + mults[c] = (MAX_OUT_VALUE / 512.f) / fb[c]; + + // Un-apply the fixed WB multipliers, to reverse their effect later in the WB tool. + // This way, the output image will be adapted to this fixed WB setting + mults[c] /= wb_mul[c]; + + // Also compensate for the initialGain difference between the default scaling (forceAutoWB=true) + // and the non-autoWB scaling (see camInitialGain). + // This effectively restores camera scaling multipliers, and gives us stable multipliers + // (not depending on image content). + mults[c] *= autoGainComp; + + } + + if (settings->verbose) { + printf("Output film base values: %g %g %g\n", static_cast(fb[0]), static_cast(fb[1]), static_cast(fb[2])); + printf("Computed multipliers: %g %g %g\n", static_cast(mults[0]), static_cast(mults[1]), static_cast(mults[2])); + } + + constexpr float CLIP_VAL = 65535.f; - t3.set(); + MyTime t1, t2, t3; + + t1.set(); if (ri->getSensorType() == ST_BAYER) { #ifdef __SSE2__ @@ -264,6 +428,7 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) #endif + for (int row = 0; row < H; ++row) { int col = 0; // Avoid trouble with zeroes, minimum pixel value is 1. @@ -274,14 +439,18 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ #ifdef __SSE2__ const vfloat expsv = _mm_setr_ps(exps0, exps1, exps0, exps1); const vfloat multsv = _mm_setr_ps(mult0, mult1, mult0, mult1); + for (; col < W - 3; col += 4) { STVFU(rawData[row][col], vminf(multsv * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv), clipv)); } + #endif // __SSE2__ + for (; col < W - 1; col += 2) { rawData[row][col] = rtengine::min(mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0), CLIP_VAL); rawData[row][col + 1] = rtengine::min(mult1 * pow_F(rtengine::max(rawData[row][col + 1], 1.f), exps1), CLIP_VAL); } + if (col < W) { rawData[row][col] = rtengine::min(mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0), CLIP_VAL); } @@ -295,6 +464,7 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) #endif + for (int row = 0; row < H; row ++) { int col = 0; // Avoid trouble with zeroes, minimum pixel value is 1. @@ -321,30 +491,34 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ const vfloat multsv0 = _mm_setr_ps(multsc[0], multsc[1], multsc[2], multsc[3]); const vfloat multsv1 = _mm_setr_ps(multsc[4], multsc[5], multsc[0], multsc[1]); const vfloat multsv2 = _mm_setr_ps(multsc[2], multsc[3], multsc[4], multsc[5]); + for (; col < W - 11; col += 12) { STVFU(rawData[row][col], vminf(multsv0 * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv0), clipv)); STVFU(rawData[row][col + 4], vminf(multsv1 * pow_F(vmaxf(LVFU(rawData[row][col + 4]), onev), expsv1), clipv)); STVFU(rawData[row][col + 8], vminf(multsv2 * pow_F(vmaxf(LVFU(rawData[row][col + 8]), onev), expsv2), clipv)); } + #endif // __SSE2__ + for (; col < W - 5; col += 6) { for (int c = 0; c < 6; ++c) { rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]), CLIP_VAL); } } + for (int c = 0; col < W; col++, c++) { rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]), CLIP_VAL); } } } - t4.set(); + t2.set(); if (settings->verbose) { - printf("Pow loop time us: %d\n", t4.etime(t3)); + printf("Pow loop time us: %d\n", t2.etime(t1)); } - t4.set(); + t2.set(); PixelsMap bitmapBads(W, H); @@ -354,6 +528,7 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ #ifdef _OPENMP #pragma omp parallel for reduction(+:totBP) schedule(dynamic,16) #endif + for (int i = 0; i < H; ++i) { for (int j = 0; j < W; ++j) { if (rawData[i][j] >= MAX_OUT_VALUE) { @@ -367,11 +542,11 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ interpolateBadPixelsBayer(bitmapBads, rawData); } - } - else if (ri->getSensorType() == ST_FUJI_XTRANS) { + } else if (ri->getSensorType() == ST_FUJI_XTRANS) { #ifdef _OPENMP #pragma omp parallel for reduction(+:totBP) schedule(dynamic,16) #endif + for (int i = 0; i < H; ++i) { for (int j = 0; j < W; ++j) { if (rawData[i][j] >= MAX_OUT_VALUE) { @@ -386,10 +561,10 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ } } - t5.set(); + t3.set(); if (settings->verbose) { printf("Bad pixels count: %d\n", totBP); - printf("Bad pixels interpolation time us: %d\n", t5.etime(t4)); + printf("Bad pixels interpolation time us: %d\n", t3.etime(t2)); } } diff --git a/rtengine/filmnegativethumb.cc b/rtengine/filmnegativethumb.cc index b31432a55..57f2601f9 100644 --- a/rtengine/filmnegativethumb.cc +++ b/rtengine/filmnegativethumb.cc @@ -18,6 +18,7 @@ */ #include +#include "colortemp.h" #include "LUT.h" #include "rtengine.h" #include "rtthumbnail.h" @@ -29,70 +30,179 @@ #define BENCHMARK #include "StopWatch.h" +namespace +{ + +using rtengine::Imagefloat; +using rtengine::findMinMaxPercentile; + + +void calcMedians( + const Imagefloat* baseImg, + const int x1, const int y1, + const int x2, const int y2, + float &rmed, float &gmed, float &bmed +) +{ + // Channel vectors to calculate medians + std::vector rv, gv, bv; + + const int sz = std::max(0, (y2 - y1) * (x2 - x1)); + rv.reserve(sz); + gv.reserve(sz); + bv.reserve(sz); + + for (int i = y1; i < y2; i++) { + for (int j = x1; j < x2; j++) { + rv.push_back(baseImg->r(i, j)); + gv.push_back(baseImg->g(i, j)); + bv.push_back(baseImg->b(i, j)); + } + } + + // Calculate channel medians from whole image + findMinMaxPercentile(rv.data(), rv.size(), 0.5f, rmed, 0.5f, rmed, true); + findMinMaxPercentile(gv.data(), gv.size(), 0.5f, gmed, 0.5f, gmed, true); + findMinMaxPercentile(bv.data(), bv.size(), 0.5f, bmed, 0.5f, bmed, true); +} + +} + void rtengine::Thumbnail::processFilmNegative( const procparams::ProcParams ¶ms, const Imagefloat* baseImg, - const int rwidth, const int rheight, - float &rmi, float &gmi, float &bmi -) { + const int rwidth, const int rheight +) +{ // Channel exponents const float rexp = -params.filmNegative.redRatio * params.filmNegative.greenExp; const float gexp = -params.filmNegative.greenExp; const float bexp = -params.filmNegative.blueRatio * params.filmNegative.greenExp; - // Need to calculate channel averages, to fake the same conditions - // found in rawimagesource, where get_ColorsCoeff is called with - // forceAutoWB=true. - float rsum = 0.f, gsum = 0.f, bsum = 0.f; - - // Channel vectors to calculate medians - std::vector rv, gv, bv; - - for (int i = 0; i < rheight; i++) { - for (int j = 0; j < rwidth; j++) { - const float r = baseImg->r(i, j); - const float g = baseImg->g(i, j); - const float b = baseImg->b(i, j); - - rsum += r; - gsum += g; - bsum += b; - - rv.push_back(r); - gv.push_back(g); - bv.push_back(b); - } - } - - const float ravg = rsum / (rheight*rwidth); - const float gavg = gsum / (rheight*rwidth); - const float bavg = bsum / (rheight*rwidth); - - // Shifting current WB multipliers, based on channel averages. - rmi /= (gavg/ravg); - // gmi /= (gAvg/gAvg); green chosen as reference channel - bmi /= (gavg/bavg); - - float rmed, gmed, bmed; - findMinMaxPercentile(rv.data(), rv.size(), 0.5f, rmed, 0.5f, rmed, true); - findMinMaxPercentile(gv.data(), gv.size(), 0.5f, gmed, 0.5f, gmed, true); - findMinMaxPercentile(bv.data(), bv.size(), 0.5f, bmed, 0.5f, bmed, true); - - rmed = powf(rmed, rexp); - gmed = powf(gmed, gexp); - bmed = powf(bmed, bexp); + // Calculate output multipliers + float rmult, gmult, bmult; const float MAX_OUT_VALUE = 65000.f; - const float rmult = (MAX_OUT_VALUE / (rmed * 24)) ; - const float gmult = (MAX_OUT_VALUE / (gmed * 24)) ; - const float bmult = (MAX_OUT_VALUE / (bmed * 24)) ; + + // For backwards compatibility with profiles saved by RT 5.7 + const bool oldChannelScaling = params.filmNegative.redBase == -1.f; + + // If the film base values are not set in params, estimate multipliers from each channel's median value. + if (params.filmNegative.redBase <= 0.f) { + + // Channel medians + float rmed, gmed, bmed; + + if (oldChannelScaling) { + // If using the old method, calculate nedians on the whole image + calcMedians(baseImg, 0, 0, rwidth, rheight, rmed, gmed, bmed); + } else { + // The new method cuts out a 20% border from medians calculation. + const int bW = rwidth * 20 / 100; + const int bH = rheight * 20 / 100; + calcMedians(baseImg, bW, bH, rwidth - bW, rheight - bH, rmed, gmed, bmed); + } + + if (settings->verbose) { + printf("Thumbnail input channel medians: %g %g %g\n", rmed, gmed, bmed); + } + + // Calculate output medians + rmed = powf(rmed, rexp); + gmed = powf(gmed, gexp); + bmed = powf(bmed, bexp); + + // Calculate output multipliers so that the median value is 1/24 of the output range. + rmult = (MAX_OUT_VALUE / 24.f) / rmed; + gmult = (MAX_OUT_VALUE / 24.f) / gmed; + bmult = (MAX_OUT_VALUE / 24.f) / bmed; + + } else { + + // Read film-base values from params + float rbase = params.filmNegative.redBase; + float gbase = params.filmNegative.greenBase; + float bbase = params.filmNegative.blueBase; + + // Reconstruct scale_mul coefficients from thumbnail metadata: + // redMultiplier / camwbRed is pre_mul[0] + // pre_mul[0] * scaleGain is scale_mul[0] + // Apply channel scaling to raw (unscaled) input base values, to + // match with actual (scaled) data in baseImg + rbase *= (redMultiplier / camwbRed) * scaleGain; + gbase *= (greenMultiplier / camwbGreen) * scaleGain; + bbase *= (blueMultiplier / camwbBlue) * scaleGain; + + if (settings->verbose) { + printf("Thumbnail input film base values: %g %g %g\n", rbase, gbase, bbase); + } + + // Apply exponents to get output film base values + rbase = powf(rbase, rexp); + gbase = powf(gbase, gexp); + bbase = powf(bbase, bexp); + + if (settings->verbose) { + printf("Thumbnail output film base values: %g %g %g\n", rbase, gbase, bbase); + } + + // Calculate multipliers so that film base value is 1/512th of the output range. + rmult = (MAX_OUT_VALUE / 512.f) / rbase; + gmult = (MAX_OUT_VALUE / 512.f) / gbase; + bmult = (MAX_OUT_VALUE / 512.f) / bbase; + + } + + + if (oldChannelScaling) { + // Need to calculate channel averages, to fake the same conditions + // found in rawimagesource, where get_ColorsCoeff is called with + // forceAutoWB=true. + float rsum = 0.f, gsum = 0.f, bsum = 0.f; + + for (int i = 0; i < rheight; i++) { + for (int j = 0; j < rwidth; j++) { + rsum += baseImg->r(i, j); + gsum += baseImg->g(i, j); + bsum += baseImg->b(i, j); + } + } + + const float ravg = rsum / (rheight * rwidth); + const float gavg = gsum / (rheight * rwidth); + const float bavg = bsum / (rheight * rwidth); + + // Shifting current WB multipliers, based on channel averages. + rmult /= gavg / ravg; + // gmult /= gAvg / gAvg; green chosen as reference channel + bmult /= gavg / bavg; + + } else { + + // Get and un-apply multipliers to adapt the thumbnail to a known fixed WB setting, + // as in the main image processing. + + double r, g, b; + ColorTemp(3500., 1., 1., "Custom").getMultipliers(r, g, b); + //iColorMatrix is cam_rgb + const double rm = camwbRed / (iColorMatrix[0][0] * r + iColorMatrix[0][1] * g + iColorMatrix[0][2] * b); + const double gm = camwbGreen / (iColorMatrix[1][0] * r + iColorMatrix[1][1] * g + iColorMatrix[1][2] * b); + const double bm = camwbBlue / (iColorMatrix[2][0] * r + iColorMatrix[2][1] * g + iColorMatrix[2][2] * b); + + // Normalize max WB multiplier to 1.f + const double m = max(rm, gm, bm); + rmult /= rm / m; + gmult /= gm / m; + bmult /= bm / m; + } + if (settings->verbose) { - printf("Thumbnail channel medians: %g %g %g\n", rmed, gmed, bmed); - printf("Thumbnail computed multipliers: %g %g %g\n", rmult, gmult, bmult); + printf("Thumbnail computed multipliers: %g %g %g\n", static_cast(rmult), static_cast(gmult), static_cast(bmult)); } + #ifdef __SSE2__ const vfloat clipv = F2V(MAXVALF); const vfloat rexpv = F2V(rexp); @@ -109,12 +219,15 @@ void rtengine::Thumbnail::processFilmNegative( float *bline = baseImg->b(i); int j = 0; #ifdef __SSE2__ - for (; j < rwidth - 3; j +=4) { + + for (; j < rwidth - 3; j += 4) { STVFU(rline[j], vminf(rmultv * pow_F(LVFU(rline[j]), rexpv), clipv)); STVFU(gline[j], vminf(gmultv * pow_F(LVFU(gline[j]), gexpv), clipv)); STVFU(bline[j], vminf(bmultv * pow_F(LVFU(bline[j]), bexpv), clipv)); } + #endif + for (; j < rwidth; ++j) { rline[j] = CLIP(rmult * pow_F(rline[j], rexp)); gline[j] = CLIP(gmult * pow_F(gline[j], gexp)); diff --git a/rtengine/green_equil_RT.cc b/rtengine/green_equil_RT.cc index fc4f18548..a66bca160 100644 --- a/rtengine/green_equil_RT.cc +++ b/rtengine/green_equil_RT.cc @@ -47,7 +47,7 @@ void RawImageSource::green_equilibrate_global(array2D &rawData) for (int i = border; i < H - border; i++) { double avgg = 0.; for (int j = border + ((FC(i, border) & 1) ^ 1); j < W - border; j += 2) { - avgg += rawData[i][j]; + avgg += static_cast(rawData[i][j]); } int ng = (W - 2 * border + (FC(i, border) & 1)) / 2; @@ -71,15 +71,15 @@ void RawImageSource::green_equilibrate_global(array2D &rawData) avgg2 = 1.0; } - double corrg1 = (avgg1 / ng1 + avgg2 / ng2) / 2.0 / (avgg1 / ng1); - double corrg2 = (avgg1 / ng1 + avgg2 / ng2) / 2.0 / (avgg2 / ng2); + const float corrg1 = (avgg1 / ng1 + avgg2 / ng2) / 2.0 / (avgg1 / ng1); + const float corrg2 = (avgg1 / ng1 + avgg2 / ng2) / 2.0 / (avgg2 / ng2); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif 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) { rawData[i][j] *= corrg; @@ -220,7 +220,7 @@ void RawImageSource::green_equilibrate(const GreenEqulibrateThreshold &thresh, a float tf = thresh(rr, cc); - if (c1 + c2 < 6 * tf * fabs(d1 - d2)) { + if (c1 + c2 < 6 * tf * std::fabs(d1 - d2)) { //pixel interpolation float gin = cfa[rr][cc >> 1]; diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index 697a5e3d3..1ba42a68b 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -323,7 +323,7 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue if (settings->verbose) { 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(chmax[c]), c, static_cast(clmax[c]), c, static_cast(chmax[c] / clmax[c])); } } @@ -366,7 +366,7 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue if (settings->verbose) { 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(factor[c])); } } @@ -496,7 +496,7 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue && blue[i + miny][j + minx] < max_f[2] ) { // 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(channelblur[0][i][j]); ++hipass_norm; 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(epsilon)); if (plistener) { progress += 0.05; diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index f5d16866e..0053cb0d4 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -179,7 +179,7 @@ void mappingToCurve(const std::vector &mapping, std::vector &curve) }; idx = -1; for (ssize_t i = curve.size()-1; i > 0; i -= 2) { - if (curve[i] <= 0.f) { + if (curve[i] <= 0.0) { idx = i+1; break; } @@ -328,7 +328,7 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, st int tw = target->getWidth(), th = target->getHeight(); 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)); - if (std::abs(thumb_ratio - target_ratio) > 0.01) { + if (std::abs(thumb_ratio - target_ratio) > 0.01f) { int cx = 0, cy = 0; if (thumb_ratio > target_ratio) { // crop the height @@ -342,7 +342,7 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, st tw -= cw; } 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) { diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index 9d7024bff..6b2be1713 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -635,7 +635,7 @@ public: MyMutex::MyLock lock(mutex); - for (const auto profile : fileProfiles) { + for (const auto& profile : fileProfiles) { if ( ( type == ICCStore::ProfileType::MONITOR diff --git a/rtengine/iimage.h b/rtengine/iimage.h index 247d0cdaa..cd8aa9a9e 100644 --- a/rtengine/iimage.h +++ b/rtengine/iimage.h @@ -27,7 +27,7 @@ #include "imagedimensions.h" #include "LUT.h" #include "rt_math.h" - +#include "procparams.h" #include "../rtgui/threadutils.h" #define TR_NONE 0 @@ -111,6 +111,10 @@ public: { rm = gm = bm = 1.0; } + virtual void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) + { + rm = gm = bm = 1.0; + } }; diff --git a/rtengine/image16.cc b/rtengine/image16.cc index 4bcd9d5c0..07fc66fad 100644 --- a/rtengine/image16.cc +++ b/rtengine/image16.cc @@ -147,10 +147,10 @@ void Image16::getStdImage(const ColorTemp &ctemp, int tran, Imagefloat* image, P gm = dgm; bm = dbm; - rm = 1.0 / rm; - gm = 1.0 / gm; - bm = 1.0 / bm; - float mul_lum = 0.299 * rm + 0.587 * gm + 0.114 * bm; + rm = 1.f / rm; + gm = 1.f / gm; + bm = 1.f / bm; + float mul_lum = 0.299f * rm + 0.587f * gm + 0.114f * bm; rm /= mul_lum; gm /= mul_lum; bm /= mul_lum; diff --git a/rtengine/image8.cc b/rtengine/image8.cc index 8784c962e..67b38d0c1 100644 --- a/rtengine/image8.cc +++ b/rtengine/image8.cc @@ -111,10 +111,10 @@ void Image8::getStdImage (const ColorTemp &ctemp, int tran, Imagefloat* image, P gm = dgm; bm = dbm; - rm = 1.0 / rm; - gm = 1.0 / gm; - bm = 1.0 / bm; - float mul_lum = 0.299 * rm + 0.587 * gm + 0.114 * bm; + rm = 1.f / rm; + gm = 1.f / gm; + bm = 1.f / bm; + float mul_lum = 0.299f * rm + 0.587f * gm + 0.114f * bm; rm /= mul_lum; gm /= mul_lum; bm /= mul_lum; diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index bbbe8794e..f9406b270 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -509,13 +509,13 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* } 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 if (iso_speed == 65535 || iso_speed == 0) { - rtexif::Tag* baseIsoTag = mnote->getTag("ISO"); + const rtexif::Tag* const baseIsoTag = mnote->getTag("ISO"); if (baseIsoTag) { - std::string isoData = baseIsoTag->valueToString(); + const std::string isoData = baseIsoTag->valueToString(); if (isoData.size() > 1) { - iso_speed = stoi(isoData); + iso_speed = std::stoi(isoData); } } } diff --git a/rtengine/imagefloat.cc b/rtengine/imagefloat.cc index 1da91a4b4..f905134a0 100644 --- a/rtengine/imagefloat.cc +++ b/rtengine/imagefloat.cc @@ -178,10 +178,10 @@ void Imagefloat::getStdImage (const ColorTemp &ctemp, int tran, Imagefloat* imag gm = dgm; bm = dbm; - rm = 1.0 / rm; - gm = 1.0 / gm; - bm = 1.0 / bm; - float mul_lum = 0.299 * rm + 0.587 * gm + 0.114 * bm; + rm = 1.f / rm; + gm = 1.f / gm; + bm = 1.f / bm; + float mul_lum = 0.299f * rm + 0.587f * gm + 0.114f * bm; rm /= mul_lum; gm /= mul_lum; bm /= mul_lum; @@ -368,7 +368,7 @@ Imagefloat::to16() const void Imagefloat::normalizeFloat(float srcMinVal, float srcMaxVal) { - float scale = MAXVALD / (srcMaxVal - srcMinVal); + float scale = MAXVALF / (srcMaxVal - srcMinVal); int w = width; int h = height; diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 76f4e435a..ea049d37c 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -26,6 +26,8 @@ #include "coord2d.h" #include "imagedata.h" #include "rtengine.h" +#include "colortemp.h" +#include "array2D.h" template class LUT; @@ -85,19 +87,19 @@ protected: public: ImageSource () : references (1), redAWBMul(-1.), greenAWBMul(-1.), blueAWBMul(-1.), - embProfile(nullptr), idata(nullptr), dirpyrdenoiseExpComp(INFINITY) {} + embProfile(nullptr), idata(nullptr), dirpyrdenoiseExpComp(RT_INFINITY) {} ~ImageSource () override {} virtual int load (const Glib::ustring &fname) = 0; virtual void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) {}; - virtual void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) {}; + virtual void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms, std::array& filmBaseValues) {}; virtual bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const procparams::FilmNegativeParams& currentParams, std::array& newExps) { return false; }; + virtual bool getRawSpotValues (Coord2D spot, int spotSize, int tran, const procparams::FilmNegativeParams ¶ms, std::array& rawValues) { return false; }; virtual void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache = false) {}; virtual void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {}; virtual void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {}; virtual void retinexPrepareBuffers (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI) {}; - virtual void flushRawData () {}; - virtual void flushRGB () {}; + virtual void flush () = 0; virtual void HLRecovery_Global (const procparams::ToneCurveParams &hrp) {}; virtual void HLRecovery_inpaint (float** red, float** green, float** blue) {}; @@ -118,8 +120,11 @@ public: virtual void convertColorSpace (Imagefloat* image, const procparams::ColorManagementParams &cmp, const ColorTemp &wb) = 0; // DIRTY HACK: this method is derived in rawimagesource and strimagesource, but (...,RAWParams raw) will be used ONLY for raw images virtual void getAutoWBMultipliers (double &rm, double &gm, double &bm) = 0; + virtual void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double & greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) = 0; virtual ColorTemp getWB () const = 0; virtual ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) = 0; + virtual void WBauto(double &tempref, double &greenref, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &studgood, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) = 0; + virtual void getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) = 0; virtual double getDefGain () const { diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index ed8b63b34..8ef72e2cb 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -37,6 +37,7 @@ #include "lcp.h" #include "procparams.h" #include "refreshmap.h" +#include "guidedfilter.h" #include "../rtgui/options.h" @@ -44,6 +45,22 @@ #include #endif +namespace +{ +using rtengine::Coord2D; +Coord2D translateCoord(const rtengine::ImProcFunctions& ipf, int fw, int fh, int x, int y) { + + const std::vector points = {Coord2D(x, y)}; + + std::vector red; + std::vector green; + std::vector blue; + ipf.transCoord(fw, fh, points, red, green, blue); + + return green[0]; +} + +} namespace rtengine { @@ -60,6 +77,7 @@ ImProcCoordinator::ImProcCoordinator() : imgsrc(nullptr), lastAwbEqual(0.), lastAwbTempBias(0.0), + lastAwbauto(""), monitorIntent(RI_RELATIVE), softProof(false), gamutCheck(false), @@ -347,11 +365,12 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) MyMutex::MyLock processingLock(mProcessing); bool highDetailNeeded = options.prevdemo == PD_Sidecar ? true : (todo & M_HIGHQUAL); + // printf("metwb=%s \n", params->wb.method.c_str()); // Check if any detail crops need high detail. If not, take a fast path short cut if (!highDetailNeeded) { for (size_t i = 0; i < crops.size(); i++) { - if (crops[i]->get_skip() == 1) { // skip=1 -> full resolution + if (crops[i]->get_skip() == 1) { // skip=1 -> full resolution highDetailNeeded = true; break; } @@ -368,7 +387,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) RAWParams rp = params->raw; ColorManagementParams cmp = params->icm; LCurveParams lcur = params->labCurve; - + if (!highDetailNeeded) { // if below 100% magnification, take a fast path if (rp.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::NONE) && rp.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)) { @@ -413,7 +432,15 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) ) && params->filmNegative.enabled ) { - imgsrc->filmNegativeProcess(params->filmNegative); + std::array filmBaseValues = { + static_cast(params->filmNegative.redBase), + static_cast(params->filmNegative.greenBase), + static_cast(params->filmNegative.blueBase) + }; + imgsrc->filmNegativeProcess(params->filmNegative, filmBaseValues); + if (filmNegListener && params->filmNegative.redBase <= 0.f) { + filmNegListener->filmBaseValuesChanged(filmBaseValues); + } } } @@ -463,7 +490,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener && autoContrast) { bayerAutoContrastListener->autoContrastChanged(contrastThreshold); } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener && autoContrast) { - xtransAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0); + + xtransAutoContrastListener->autoContrastChanged(contrastThreshold); } // if a demosaic happened we should also call getimage later, so we need to set the M_INIT flag @@ -504,6 +532,12 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } } + if (todo & (M_INIT | M_LINDENOISE | M_HDR)) { + if (params->wb.method == "autitcgreen") { + imgsrc->getrgbloc(0, 0, fh, fw, 0, 0, fh, fw); + } + } + if ((todo & (M_RETINEX | M_INIT)) && params->retinex.enabled) { bool dehacontlutili = false; bool mapcontlutili = false; @@ -520,6 +554,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } } + const bool autowb = (params->wb.method == "autold" || params->wb.method == "autitcgreen"); + if (settings->verbose) { + printf("automethod=%s \n", params->wb.method.c_str()); + } if (todo & (M_INIT | M_LINDENOISE | M_HDR)) { MyMutex::MyLock initLock(minit); // Also used in crop window @@ -531,28 +569,53 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } currWB = ColorTemp(params->wb.temperature, params->wb.green, params->wb.equal, params->wb.method); + float studgood = 1000.f; if (!params->wb.enabled) { currWB = ColorTemp(); } else if (params->wb.method == "Camera") { currWB = imgsrc->getWB(); - } else if (params->wb.method == "Auto") { - if (lastAwbEqual != params->wb.equal || lastAwbTempBias != params->wb.tempBias) { + lastAwbauto = ""; //reinitialize auto + } else if (autowb) { + if (params->wb.method == "autitcgreen" || lastAwbEqual != params->wb.equal || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) { double rm, gm, bm; - imgsrc->getAutoWBMultipliers(rm, gm, bm); + double tempitc = 5000.f; + double greenitc = 1.; + currWBitc = imgsrc->getWB(); + double tempref = currWBitc.getTemp() * (1. + params->wb.tempBias); + double greenref = currWBitc.getGreen(); + if (settings->verbose && params->wb.method == "autitcgreen") { + printf("tempref=%f greref=%f\n", tempref, greenref); + } + + imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw); + + if (params->wb.method == "autitcgreen") { + params->wb.temperature = tempitc; + params->wb.green = greenitc; + currWB = ColorTemp(params->wb.temperature, params->wb.green, 1., params->wb.method); + currWB.getMultipliers(rm, gm, bm); + } if (rm != -1.) { - autoWB.update(rm, gm, bm, params->wb.equal, params->wb.tempBias); + double bias = params->wb.tempBias; + + if (params->wb.method == "autitcgreen") { + bias = 0.; + } + + autoWB.update(rm, gm, bm, params->wb.equal, bias); lastAwbEqual = params->wb.equal; lastAwbTempBias = params->wb.tempBias; + lastAwbauto = params->wb.method; } else { lastAwbEqual = -1.; lastAwbTempBias = 0.0; + lastAwbauto = ""; autoWB.useDefaults(params->wb.equal); } - - //double rr,gg,bb; - //autoWB.getMultipliers(rr,gg,bb); + + } currWB = autoWB; @@ -563,9 +626,13 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) params->wb.green = currWB.getGreen(); } - if (params->wb.method == "Auto" && awbListener && params->wb.enabled) { - awbListener->WBChanged(params->wb.temperature, params->wb.green); - } + if (autowb && awbListener && params->wb.method == "autitcgreen") { + awbListener->WBChanged(params->wb.temperature, params->wb.green, studgood); + } + + if (autowb && awbListener && params->wb.method == "autold") { + awbListener->WBChanged(params->wb.temperature, params->wb.green, -1.f); + } /* GammaValues g_a; @@ -956,7 +1023,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (params->blackwhite.enabled && params->blackwhite.autoc && abwListener) { 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(bwAutoR), static_cast(bwAutoG), static_cast(bwAutoB)); } abwListener->BWChanged((float) rrm, (float) ggm, (float) bbm); @@ -1384,14 +1451,217 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) wavcontlutili = false; CurveFactory::curveWavContL(wavcontlutili, params->wavelet.wavclCurve, wavclCurve, scale == 1 ? 1 : 16); - if ((params->wavelet.enabled)) { WaveletParams WaveParams = params->wavelet; - WaveParams.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); - + WaveParams.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); int kall = 0; - ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); + LabImage *unshar = nullptr; + Glib::ustring provis; + LabImage *provradius = nullptr; + bool procont = WaveParams.expcontrast; + bool prochro = WaveParams.expchroma; + bool proedge = WaveParams.expedge; + bool profin = WaveParams.expfinal; + bool proton = WaveParams.exptoning; + bool pronois = WaveParams.expnoise; + if(WaveParams.showmask) { + // WaveParams.showmask = false; + // WaveParams.expclari = true; + } + + if (WaveParams.softrad > 0.f) { + provradius = new LabImage(pW, pH); + provradius->CopyFrom(nprevl); + } + + + + + if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { + unshar = new LabImage(pW, pH); + provis = params->wavelet.CLmethod; + params->wavelet.CLmethod = "all"; + ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); + + unshar->CopyFrom(nprevl); + + params->wavelet.CLmethod = provis; + + WaveParams.expcontrast = false; + WaveParams.expchroma = false; + WaveParams.expedge = false; + WaveParams.expfinal = false; + WaveParams.exptoning = false; + WaveParams.expnoise = false; + } + + ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); + + + if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { + WaveParams.expcontrast = procont; + WaveParams.expchroma = prochro; + WaveParams.expedge = proedge; + WaveParams.expfinal = profin; + WaveParams.exptoning = proton; + WaveParams.expnoise = pronois; + + if (WaveParams.softrad > 0.f) { + + array2D ble(pW, pH); + array2D guid(pW, pH); + Imagefloat *tmpImage = nullptr; + tmpImage = new Imagefloat(pW, pH); + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < pH; ir++) + for (int jr = 0; jr < pW; jr++) { + float X, Y, Z; + float L = provradius->L[ir][jr]; + float a = provradius->a[ir][jr]; + float b = provradius->b[ir][jr]; + Color::Lab2XYZ(L, a, b, X, Y, Z); + + guid[ir][jr] = Y / 32768.f; + float La = nprevl->L[ir][jr]; + float aa = nprevl->a[ir][jr]; + float ba = nprevl->b[ir][jr]; + Color::Lab2XYZ(La, aa, ba, X, Y, Z); + tmpImage->r(ir, jr) = X; + tmpImage->g(ir, jr) = Y; + tmpImage->b(ir, jr) = Z; + ble[ir][jr] = Y / 32768.f; + } + + double epsilmax = 0.0001; + double epsilmin = 0.00001; + double aepsil = (epsilmax - epsilmin) / 90.f; + double bepsil = epsilmax - 100.f * aepsil; + double epsil = aepsil * WaveParams.softrad + bepsil; + + float blur = 10.f / scale * (0.0001f + 0.8f * WaveParams.softrad); + // rtengine::guidedFilter(guid, ble, ble, blur, 0.001, multiTh); + rtengine::guidedFilter(guid, ble, ble, blur, epsil, false); + + + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < pH; ir++) + for (int jr = 0; jr < pW; jr++) { + float X = tmpImage->r(ir, jr); + float Y = 32768.f * ble[ir][jr]; + float Z = tmpImage->b(ir, jr); + float L, a, b; + Color::XYZ2Lab(X, Y, Z, L, a, b); + nprevl->L[ir][jr] = L; + } + + delete tmpImage; + + } + + } + + if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { + float mL = (float)(WaveParams.mergeL / 100.f); + float mC = (float)(WaveParams.mergeC / 100.f); + float mL0; + float mC0; + float background = 0.f; + int show = 0; + + + + if ((WaveParams.CLmethod == "one" || WaveParams.CLmethod == "inf") && WaveParams.Backmethod == "black") { + mL0 = mC0 = 0.f; + mL = - 1.5f * mL; + mC = -mC; + background = 12000.f; + show = 0; + } else if (WaveParams.CLmethod == "sup" && WaveParams.Backmethod == "resid") { + mL0 = mL; + mC0 = mC; + background = 0.f; + show = 0; + } else { + mL0 = mL = mC0 = mC = 0.f; + background = 0.f; + show = 0; + } + float indic = 1.f; + + if(WaveParams.showmask){ + mL0 = mC0 = -1.f; + indic = -1.f; + mL = fabs(mL); + mC = fabs(mC); + show = 1; + } +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int x = 0; x < pH; x++) + for (int y = 0; y < pW; y++) { + nprevl->L[x][y] = LIM((1.f + mL0) * (unshar->L[x][y]) + show * background - mL * indic * nprevl->L[x][y], 0.f, 32768.f); + nprevl->a[x][y] = (1.f + mC0) * (unshar->a[x][y]) - mC * indic * nprevl->a[x][y]; + nprevl->b[x][y] = (1.f + mC0) * (unshar->b[x][y]) - mC * indic * nprevl->b[x][y]; + } + + delete unshar; + unshar = NULL; +/* + if (WaveParams.softrad > 0.f) { + array2D ble(pW, pH); + array2D guid(pW, pH); +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < pH; ir++) + for (int jr = 0; jr < pW; jr++) { + ble[ir][jr] = (nprevl->L[ir][jr] - provradius->L[ir][jr]) / 32768.f; + guid[ir][jr] = provradius->L[ir][jr] / 32768.f; + } + double epsilmax = 0.001; + double epsilmin = 0.0001; + double aepsil = (epsilmax - epsilmin) / 90.f; + double bepsil = epsilmax - 100.f * aepsil; + double epsil = aepsil * WaveParams.softrad + bepsil; + + float blur = 10.f / scale * (0.001f + 0.8f * WaveParams.softrad); + // rtengine::guidedFilter(guid, ble, ble, blur, 0.001, multiTh); + rtengine::guidedFilter(guid, ble, ble, blur, epsil, false); + + + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < pH; ir++) + for (int jr = 0; jr < pW; jr++) { + nprevl->L[ir][jr] = provradius->L[ir][jr] + 32768.f * ble[ir][jr]; + } + } +*/ + if (WaveParams.softrad > 0.f) { + + delete provradius; + provradius = NULL; + + } + + + } + } ipf.softLight(nprevl, params->softlight); @@ -1441,7 +1711,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) 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 += 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 } @@ -1467,17 +1737,23 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) ipf.ciecam_02float(ncie, float (adap), pW, 2, nprevl, params.get(), customColCurve1, customColCurve2, customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 0, scale, execsharp, d, dj, yb, 1); - if ((params->colorappearance.autodegree || params->colorappearance.autodegreeout) && acListener && params->colorappearance.enabled) { + if ((params->colorappearance.autodegree || params->colorappearance.autodegreeout) && acListener && params->colorappearance.enabled && !params->colorappearance.presetcat02) { acListener->autoCamChanged(100.* (double)d, 100.* (double)dj); } - if (params->colorappearance.autoadapscen && acListener && params->colorappearance.enabled) { + if (params->colorappearance.autoadapscen && acListener && params->colorappearance.enabled && !params->colorappearance.presetcat02) { acListener->adapCamChanged(adap); //real value of adapt scene } - if (params->colorappearance.autoybscen && acListener && params->colorappearance.enabled) { + if (params->colorappearance.autoybscen && acListener && params->colorappearance.enabled && !params->colorappearance.presetcat02) { acListener->ybCamChanged((int) yb); //real value Yb scene } + + if (params->colorappearance.enabled && params->colorappearance.presetcat02 && params->colorappearance.autotempout) { + // acListener->wbCamChanged(params->wb.temperature, params->wb.green); //real temp and tint + acListener->wbCamChanged(params->wb.temperature, 1.f); //real temp and tint = 1. + } + } else { // CIECAM is disabled, we free up its image buffer to save some space if (ncie) { @@ -1716,18 +1992,27 @@ bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, dou { if (imgsrc) { - if (lastAwbEqual != equal || lastAwbTempBias != tempBias) { + if (lastAwbEqual != equal || lastAwbTempBias != tempBias || lastAwbauto != params->wb.method) { // Issue 2500 MyMutex::MyLock lock(minit); // Also used in crop window double rm, gm, bm; - imgsrc->getAutoWBMultipliers(rm, gm, bm); + params->wb.method = "autold";//same result as before muliple Auto WB + + // imgsrc->getAutoWBMultipliers(rm, gm, bm); + double tempitc = 5000.; + double greenitc = 1.; + float studgood = 1000.f; + double tempref, greenref; + imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw); if (rm != -1) { autoWB.update(rm, gm, bm, equal, tempBias); lastAwbEqual = equal; lastAwbTempBias = tempBias; + lastAwbauto = params->wb.method; } else { lastAwbEqual = -1.; autoWB.useDefaults(equal); + lastAwbauto = ""; lastAwbTempBias = 0.0; } } @@ -1790,26 +2075,22 @@ bool ImProcCoordinator::getFilmNegativeExponents(int xA, int yA, int xB, int yB, { MyMutex::MyLock lock(mProcessing); - const auto xlate = - [this](int x, int y) -> Coord2D { - const std::vector points = {Coord2D(x, y)}; - - std::vector red; - std::vector green; - std::vector blue; - ipf.transCoord(fw, fh, points, red, green, blue); - - return green[0]; - }; - const int tr = getCoarseBitMask(params->coarse); - const Coord2D p1 = xlate(xA, yA); - const Coord2D p2 = xlate(xB, yB); + const Coord2D p1 = translateCoord(ipf, fw, fh, xA, yA); + const Coord2D p2 = translateCoord(ipf, fw, fh, xB, yB); return imgsrc->getFilmNegativeExponents(p1, p2, tr, params->filmNegative, newExps); } +bool ImProcCoordinator::getRawSpotValues(int x, int y, int spotSize, std::array& rawValues) +{ + MyMutex::MyLock lock(mProcessing); + + return imgsrc->getRawSpotValues(translateCoord(ipf, fw, fh, x, y), spotSize, + getCoarseBitMask(params->coarse), params->filmNegative, rawValues); +} + void ImProcCoordinator::getAutoCrop(double ratio, int &x, int &y, int &w, int &h) { @@ -1901,7 +2182,7 @@ void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool a if (params->wb.method == "Camera") { currWB = imgsrc->getWB(); - } else if (params->wb.method == "Auto") { + } else if (params->wb.method == "autold") { if (lastAwbEqual != params->wb.equal || lastAwbTempBias != params->wb.tempBias) { double rm, gm, bm; imgsrc->getAutoWBMultipliers(rm, gm, bm); diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index b0bbed66d..6e467b689 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -73,9 +73,13 @@ protected: ColorTemp currWB; ColorTemp autoWB; + ColorTemp currWBloc; + ColorTemp autoWBloc; + ColorTemp currWBitc; double lastAwbEqual; double lastAwbTempBias; + Glib::ustring lastAwbauto; Glib::ustring monitorProfile; RenderingIntent monitorIntent; @@ -135,6 +139,7 @@ protected: NoiseCurve noiseLCurve; NoiseCurve noiseCCurve; WavCurve wavCLVCurve; + Wavblcurve wavblcurve; WavOpacityCurveRG waOpacityCurveRG; WavOpacityCurveBY waOpacityCurveBY; WavOpacityCurveW waOpacityCurveW; @@ -170,6 +175,7 @@ protected: AutoRadiusListener *pdSharpenAutoRadiusListener; FrameCountListener *frameCountListener; ImageTypeListener *imageTypeListener; + FilmNegListener *filmNegListener; AutoColorTonListener* actListener; AutoChromaListener* adnListener; WaveletListener* awavListener; @@ -427,6 +433,7 @@ public: void getCamWB (double& temp, double& green) override; void getSpotWB (int x, int y, int rectSize, double& temp, double& green) override; bool getFilmNegativeExponents(int xA, int yA, int xB, int yB, std::array& newExps) override; + bool getRawSpotValues(int x, int y, int spotSize, std::array& rawValues) override; void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) override; bool getHighQualComputed() override; void setHighQualComputed() override; @@ -557,6 +564,11 @@ public: imageTypeListener = itl; } + void setFilmNegListener (FilmNegListener* fnl) override + { + filmNegListener = fnl; + } + void saveInputICCReference (const Glib::ustring& fname, bool apply_wb) override; InitialImage* getInitialImage () override diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index a75275c97..77f43bf84 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -135,7 +135,7 @@ void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, flo float b = btemp[ti * tileSize + tj + k]; float tonefactor = ((r < MAXVALF ? hltonecurve[r] : CurveFactory::hlcurve(exp_scale, comp, hlrange, r)) + (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 rtemp[ti * tileSize + tj + k] = r * tonefactor; @@ -163,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 = ((r < MAXVALF ? hltonecurve[r] : CurveFactory::hlcurve(exp_scale, comp, hlrange, r)) + (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 rtemp[ti * tileSize + tj] = r * tonefactor; @@ -532,8 +532,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb int width = lab->W, height = lab->H; float minQ = 10000.f; float maxQ = -1000.f; - float Yw; - Yw = 1.0; + double Yw = 1.0; 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 fl, n, nbb, ncb, aw; //d @@ -610,13 +609,13 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb algepd = true; } - xwd = 100.f * Xwout; - zwd = 100.f * Zwout; - ywd = 100.f / params->colorappearance.greenout;//approximation to simplify + xwd = 100.0 * Xwout; + zwd = 100.0 * Zwout; + ywd = 100.0 / params->colorappearance.greenout;//approximation to simplify - xws = 100.f * Xwsc; - zws = 100.f * Zwsc; - yws = 100.f / params->colorappearance.greensc;//approximation to simplify + xws = 100.0 * Xwsc; + zws = 100.0 * Zwsc; + yws = 100.0 / params->colorappearance.greensc;//approximation to simplify /* @@ -714,20 +713,20 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb if (alg == 3 || alg == 1) { schr = params->colorappearance.schroma; - if (schr > 0.0) { - schr = schr / 2.0f; //divide sensibility for saturation + if (schr > 0.f) { + schr = schr / 2.f; //divide sensibility for saturation } if (alg == 3) { - if (schr == -100.0f) { + if (schr == -100.f) { schr = -99.f; } - if (schr == 100.0f) { + if (schr == 100.f) { schr = 98.f; } } else { - if (schr == -100.0f) { + if (schr == -100.f) { schr = -99.8f; } } @@ -803,7 +802,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb #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 float currL = lab->L[i][j] / 327.68f; float koef; //rough correspondence between L and J @@ -864,10 +863,11 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb //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(koef) * static_cast(lab->L[i][j]); //evaluate mean J to calculate Yb //sumQ += whestim * sqrt ((koef * (lab->L[i][j])) / 32768.f); //can be used in case of... } + } #ifdef _OPENMP #pragma omp critical @@ -884,7 +884,7 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb } 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 @@ -931,9 +931,9 @@ void ImProcFunctions::ciecam_02float(CieImage* ncie, float adap, int pW, int pwb const bool highlight = params->toneCurve.hrenabled; //Get the value if "highlight reconstruction" is activated const int gamu = (params->colorappearance.gamut) ? 1 : 0; - xw = 100.0f * Xw; - yw = 100.0f * Yw; - zw = 100.0f * Zw; + xw = 100.0 * Xw; + yw = 100.0 * Yw; + zw = 100.0 * Zw; 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 @@ -2006,8 +2006,8 @@ void ImProcFunctions::moyeqt(Imagefloat* working, float &moyS, float &eqty) { BENCHFUN - int tHh = working->getHeight(); - int tWw = working->getWidth(); + const int height = working->getHeight(); + const int width = working->getWidth(); double moy = 0.0; double sqrs = 0.0; @@ -2015,17 +2015,17 @@ void ImProcFunctions::moyeqt(Imagefloat* working, float &moyS, float &eqty) #pragma omp parallel for reduction(+:moy,sqrs) schedule(dynamic,16) #endif - for (int i = 0; i < tHh; i++) { - 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))); + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + const double s = Color::rgb2s(CLIP(working->r (i, j)), CLIP(working->g (i, j)), CLIP(working->b (i, j))); moy += s; sqrs += SQR(s); } } - moy /= (tHh * tWw); - sqrs /= (tHh * tWw); - eqty = sqrt(sqrs - SQR(moy)); + moy /= (height * width); + sqrs /= (height * width); + eqty = std::sqrt(std::max(sqrs - SQR(moy), 0.0)); moyS = moy; } @@ -2123,17 +2123,17 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer float toxyz[3][3] = { { - static_cast(wprof[0][0] / Color::D50x), - static_cast(wprof[0][1] / Color::D50x), - static_cast(wprof[0][2] / Color::D50x) + static_cast(wprof[0][0] / static_cast(Color::D50x)), + static_cast(wprof[0][1] / static_cast(Color::D50x)), + static_cast(wprof[0][2] / static_cast(Color::D50x)) }, { static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2]) }, { - static_cast(wprof[2][0] / Color::D50z), - static_cast(wprof[2][1] / Color::D50z), - static_cast(wprof[2][2] / Color::D50z) + static_cast(wprof[2][0] / static_cast(Color::D50z)), + static_cast(wprof[2][1] / static_cast(Color::D50z)), + static_cast(wprof[2][2] / static_cast(Color::D50z)) } }; float maxFactorToxyz = max(toxyz[1][0], toxyz[1][1], toxyz[1][2]); @@ -2255,8 +2255,8 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer const float exp_scale = pow(2.0, expcomp); 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 hlrange = 65536.0 - shoulder; + const float shoulder = ((65536.f / max(1.0f, exp_scale)) * (hlcomprthresh / 200.f)) + 0.1f; + const float hlrange = 65536.f - shoulder; const bool isProPhoto = (params->icm.workingProfile == "ProPhoto"); // extracting data from 'params' to avoid cache flush (to be confirmed) ToneCurveMode curveMode = params->toneCurve.curveMode; @@ -2318,43 +2318,43 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer } */ - float RedLow = params->colorToning.redlow / 100.f; - float GreenLow = params->colorToning.greenlow / 100.f; - float BlueLow = params->colorToning.bluelow / 100.f; - float RedMed = params->colorToning.redmed / 100.f; - float GreenMed = params->colorToning.greenmed / 100.f; - float BlueMed = params->colorToning.bluemed / 100.f; - float RedHigh = params->colorToning.redhigh / 100.f; - float GreenHigh = params->colorToning.greenhigh / 100.f; - float BlueHigh = params->colorToning.bluehigh / 100.f; - float SatLow = float (params->colorToning.shadowsColSat.getBottom()) / 100.f; - float SatHigh = float (params->colorToning.hlColSat.getBottom()) / 100.f; + float RedLow = params->colorToning.redlow / 100.0; + float GreenLow = params->colorToning.greenlow / 100.0; + float BlueLow = params->colorToning.bluelow / 100.0; + float RedMed = params->colorToning.redmed / 100.0; + float GreenMed = params->colorToning.greenmed / 100.0; + float BlueMed = params->colorToning.bluemed / 100.0; + float RedHigh = params->colorToning.redhigh / 100.0; + float GreenHigh = params->colorToning.greenhigh / 100.0; + float BlueHigh = params->colorToning.bluehigh / 100.0; + float SatLow = params->colorToning.shadowsColSat.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 chMixRG = float (params->chmixer.red[1])/10.f; - float chMixRB = float (params->chmixer.red[2])/10.f; - float chMixGR = float (params->chmixer.green[0])/10.f; - float chMixGG = float (params->chmixer.green[1])/10.f; - float chMixGB = float (params->chmixer.green[2])/10.f; - float chMixBR = float (params->chmixer.blue[0])/10.f; - float chMixBG = float (params->chmixer.blue[1])/10.f; - float chMixBB = float (params->chmixer.blue[2])/10.f; + float chMixRR = params->chmixer.red[0] / 10.f; + float chMixRG = params->chmixer.red[1] / 10.f; + float chMixRB = params->chmixer.red[2] / 10.f; + float chMixGR = params->chmixer.green[0] / 10.f; + float chMixGG = params->chmixer.green[1] / 10.f; + float chMixGB = params->chmixer.green[2] / 10.f; + float chMixBR = params->chmixer.blue[0] / 10.f; + float chMixBG = params->chmixer.blue[1] / 10.f; + float chMixBB = params->chmixer.blue[2] / 10.f; bool blackwhite = params->blackwhite.enabled; bool complem = params->blackwhite.enabledcc; - float bwr = float (params->blackwhite.mixerRed); - float bwg = float (params->blackwhite.mixerGreen); - float bwb = float (params->blackwhite.mixerBlue); - float bwrgam = float (params->blackwhite.gammaRed); - float bwggam = float (params->blackwhite.gammaGreen); - float bwbgam = float (params->blackwhite.gammaBlue); - float mixerOrange = float (params->blackwhite.mixerOrange); - float mixerYellow = float (params->blackwhite.mixerYellow); - float mixerCyan = float (params->blackwhite.mixerCyan); - float mixerMagenta = float (params->blackwhite.mixerMagenta); - float mixerPurple = float (params->blackwhite.mixerPurple); + float bwr = params->blackwhite.mixerRed; + float bwg = params->blackwhite.mixerGreen; + float bwb = params->blackwhite.mixerBlue; + float bwrgam = params->blackwhite.gammaRed; + float bwggam = params->blackwhite.gammaGreen; + float bwbgam = params->blackwhite.gammaBlue; + float mixerOrange = params->blackwhite.mixerOrange; + float mixerYellow = params->blackwhite.mixerYellow; + float mixerCyan = params->blackwhite.mixerCyan; + float mixerMagenta = params->blackwhite.mixerMagenta; + float mixerPurple = params->blackwhite.mixerPurple; int algm = 0; if (params->blackwhite.method == "Desaturation") { @@ -2741,7 +2741,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer //HSV equalizer if (hCurveEnabled) { - h = (hCurve->getVal(double (h)) - 0.5) * 2.f + h; + h = (hCurve->getVal(h) - 0.5) * 2.0 + static_cast(h); if (h > 1.0f) { h -= 1.0f; @@ -2772,7 +2772,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer } //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)))); if (valparam > 0.00001f) { @@ -3085,7 +3085,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer if (bwlCurveEnabled) { L /= 32768.f; 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 //reduct action for low chroma and increase action for high chroma valparam *= kcc; @@ -3341,9 +3341,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer for (int i = 0; i < tH; i++) { for (int j = 0; j < tW; j++) { - nr += tmpImage->r(i, j); - ng += tmpImage->g(i, j); - nb += tmpImage->b(i, j); + nr += static_cast(tmpImage->r(i, j)); + ng += static_cast(tmpImage->g(i, j)); + nb += static_cast(tmpImage->b(i, j)); } } @@ -3685,7 +3685,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer delete vCurve; } - // shadowsHighlights(lab); + // shadowsHighlights(lab); shadowsHighlights(lab, params->sh.enabled, params->sh.lab,params->sh.highlights ,params->sh.shadows, params->sh.radius, scale, params->sh.htonalwidth, params->sh.stonalwidth); if (params->localContrast.enabled) { @@ -4422,8 +4422,7 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW float factnoise = 1.f; if (params->dirpyrDenoise.enabled) { - factnoise = (1.f + params->dirpyrDenoise.chroma / 500.f); //levels=5 -// if(yyyy) factnoise=(1.f+params->dirpyrDenoise.chroma/100.f);//levels=7 + factnoise = 1.0 + params->dirpyrDenoise.chroma / 500.0; //levels=5 } const float scaleConst = 100.0f / 100.1f; @@ -4601,10 +4600,9 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW float l_r;//Luminance Lab in 0..1 l_r = Lprov1 / 100.f; { - //double hr = 0.5 * ((HH / rtengine::RT_PI) + 1.); + float valparam = lhCurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5; //get l_r=f(H) //float valparam = float ((lhCurve->getVal (hr - 0.5f)*2));//get l_r=f(H) - float valparam = float ((lhCurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f)); //get l_r=f(H) float valparamneg; valparamneg = valparam; float kcc = (CC / amountchroma); //take Chroma into account...40 "middle low" of chromaticity (arbitrary and simple), one can imagine other algorithme @@ -4637,9 +4635,9 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW float fx = (0.002f * aprov1) + fy; float fz = fy - (0.005f * bprov1); - float x_ = 65535.0f * Color::f2xyz(fx) * Color::D50x; - float z_ = 65535.0f * Color::f2xyz(fz) * Color::D50z; - float y_ = (Lprov1 > Color::epskap) ? 65535.0 * fy * fy * fy : 65535.0 * Lprov1 / Color::kappa; + float x_ = 65535.f * Color::f2xyz (fx) * Color::D50x; + float z_ = 65535.f * Color::f2xyz (fz) * Color::D50z; + float y_ = Lprov1 > Color::epskapf ? 65535.f * fy * fy * fy : 65535.f * Lprov1 / Color::kappaf; float R, G, B; Color::xyz2rgb(x_, y_, z_, R, G, B, wip); @@ -4667,9 +4665,8 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW // calculate C=f(H) if (chutili) { double hr = Color::huelab_to_huehsv2(HH); - //double hr = 0.5 * ((HH / rtengine::RT_PI) + 1.); + float chparam = (chCurve->getVal(hr) - 0.5) * 2.0; //get C=f(H) - float chparam = float ((chCurve->getVal(hr) - 0.5f) * 2.0f); //get C=f(H) float chromaChfactor = 1.0f + chparam; atmp *= chromaChfactor;//apply C=f(H) btmp *= chromaChfactor; @@ -4677,7 +4674,7 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW if (hhutili) { // H=f(H) //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(HH); //get H=f(H) 1.7 optimisation ! HH = valparam; sincosval = xsincosf(HH); } @@ -4755,11 +4752,11 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW 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 } - if (chromaCfactor > 1.0) { + if (chromaCfactor > 1.f) { float interm = (chromaCfactor - 1.0f) * 100.0f; factorskin = 1.0f + (interm * scale) / 100.0f; factorskinext = 1.0f + (interm * scaleext) / 100.0f; @@ -4816,11 +4813,11 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW 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 } - if (chromaCfactor > 1.0) { + if (chromaCfactor > 1.f) { float interm = (chromaCfactor - 1.0f) * 100.0f; factorskin = 1.0f + (interm * scale) / 100.0f; factorskinext = 1.0f + (interm * scaleext) / 100.0f; @@ -5103,7 +5100,7 @@ void ImProcFunctions::impulsedenoise(LabImage* lab) 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); } } @@ -5113,7 +5110,7 @@ void ImProcFunctions::impulsedenoisecam(CieImage* ncie, float **buffers[3]) 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); } } @@ -5183,11 +5180,11 @@ void ImProcFunctions::EPDToneMapCIE(CieImage *ncie, float a_w, float c_, int Wid float sca = params->epd.scale; float gamm = params->epd.gamma; 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]; if (settings->verbose) { - printf("minQ=%f maxQ=%f Qpro=%f\n", minQ, maxQ, Qpro); + printf ("minQ=%f maxQ=%f Qpro=%f\n", static_cast(minQ), static_cast(maxQ), static_cast(Qpro)); } if (maxQ > Qpro) { @@ -5214,7 +5211,7 @@ void ImProcFunctions::EPDToneMapCIE(CieImage *ncie, float a_w, float c_, int Wid //Auto select number of iterates. Note that p->EdgeStopping = 0 makes a Gaussian blur. 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 @@ -5531,7 +5528,7 @@ void ImProcFunctions::getAutoExp(const LUTu &histogram, int histcompr, double cl octile[count] += histogram[j]; 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); } } @@ -5544,7 +5541,7 @@ void ImProcFunctions::getAutoExp(const LUTu &histogram, int histcompr, double cl octile[count] += histogram[j]; 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); } } @@ -5619,7 +5616,7 @@ void ImProcFunctions::getAutoExp(const LUTu &histogram, int histcompr, double cl } //compute clipped white point - unsigned int clippable = (int)(sum * clip / 100.f); + unsigned int clippable = (int) (static_cast(sum) * clip / 100.0 ); clipped = 0; int whiteclip = (imax) - 1; @@ -5678,8 +5675,8 @@ void ImProcFunctions::getAutoExp(const LUTu &histogram, int histcompr, double cl hlcomprthresh = 0; //this is a series approximation of the actual formula for comp, //which is a transcendental equation - float comp = (gain * ((float)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)); + double comp = (gain * whiteclip / scale - 1.f) * 2.3f; // 2.3 instead of 2 to increase slightly comp + hlcompr = 100.0 * comp / (max(0.0, expcomp) + 1.0); hlcompr = max(0, min(100, hlcompr)); //now find brightness if gain didn't bring ave to midgray using @@ -5687,9 +5684,9 @@ void ImProcFunctions::getAutoExp(const LUTu &histogram, int histcompr, double cl float midtmp = gain * sqrt(median * ave) / scale; if (midtmp < 0.1f) { - bright = (midgray - midtmp) * 15.0 / (midtmp); + bright = (midgray - midtmp) * 15.f / (midtmp); } 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); @@ -5698,7 +5695,7 @@ void ImProcFunctions::getAutoExp(const LUTu &histogram, int histcompr, double cl contr = (int) 50.0f * (1.1f - ospread); contr = max(0, min(100, contr)); //take gamma into account - double whiteclipg = (int)(CurveFactory::gamma2(whiteclip * corr / 65536.0) * 65536.0); + double whiteclipg = (int) (CurveFactory::gamma2(whiteclip * static_cast(corr) / 65536.0) * 65536.0); float gavg = 0.; @@ -5720,7 +5717,7 @@ void ImProcFunctions::getAutoExp(const LUTu &histogram, int histcompr, double cl } } - 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 black = (int)((65535 * black) / whiteclipg); @@ -5955,8 +5952,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) { - const float factor = ColorToningParams::LABGRID_CORR_MAX * 3.f; - const float scaling = ColorToningParams::LABGRID_CORR_SCALE; + const double factor = ColorToningParams::LABGRID_CORR_MAX * 3.0; + const double scaling = ColorToningParams::LABGRID_CORR_SCALE; float a_scale = (params->colorToning.labgridAHigh - params->colorToning.labgridALow) / factor / scaling; float a_base = params->colorToning.labgridALow / scaling; float b_scale = (params->colorToning.labgridBHigh - params->colorToning.labgridBLow) / factor / scaling; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 23154ecd2..d47a6f60e 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -66,6 +66,7 @@ class OpacityCurve; class PipetteBuffer; class ToneCurve; class WavCurve; +class Wavblcurve; class WavOpacityCurveBY; class WavOpacityCurveRG; class WavOpacityCurveW; @@ -219,6 +220,7 @@ public: void EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0); void CompressDR(float *Source, int W_L, int H_L, float Compression, float DetailBoost); void Compresslevels(float **Source, int W_L, int H_L, float compression, float detailattenuator, float thres, float mean, float maxp, float meanN, float maxN, float madL); + void Compresslevels2(float **Source, int W_L, int H_L, float compression, float detailattenuator, float thres, float mean, float maxp, float meanN, float maxN, float madL); void ContrastResid(float * WavCoeffs_L0, struct cont_params &cp, int W_L, int H_L, float max0, float min0); void EPDToneMap(LabImage *lab, unsigned int Iterates = 0, int skip = 1); @@ -367,30 +369,34 @@ public: void Tile_calc(int tilesize, int overlap, int kall, int imwidth, int imheight, int &numtiles_W, int &numtiles_H, int &tilewidth, int &tileheight, int &tileWskip, int &tileHskip); - void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, LUTf &wavclCurve, int skip); + void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip); - void WaveletcontAllL(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_L, + void WaveletcontAllL(LabImage * lab, float **varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_L, const Wavblcurve & wavblcurve, struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); - void WaveletcontAllLfinal(wavelet_decomposition &WaveletCoeffs_L, struct cont_params &cp, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); - void WaveletcontAllAB(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_a, const WavOpacityCurveW & waOpacityCurveW, - struct cont_params &cp, const bool useChannelA); - void WaveletAandBAllAB(wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, - struct cont_params &cp, FlatCurve* hhcurve, bool hhutili); + void WaveletcontAllLfinal(const wavelet_decomposition &WaveletCoeffs_L, const cont_params &cp, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); + void WaveletcontAllAB(LabImage * lab, float **varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_a, const Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW, + struct cont_params &cp, const bool useChannelA, int skip, float *meanab, float *sigmaab); + void WaveletAandBAllAB(const wavelet_decomposition &WaveletCoeffs_a, const wavelet_decomposition &WaveletCoeffs_b, + const cont_params &cp, FlatCurve* hhcurve, bool hhutili); void ContAllL(float **koeLi, float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); - void finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, + void finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp, int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); void ContAllAB(LabImage * lab, int maxlvl, float **varhue, float **varchrom, float ** WavCoeffs_a, float * WavCoeffs_a0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, int W_ab, int H_ab, const bool useChannelA); - void Evaluate2(wavelet_decomposition &WaveletCoeffs_L, + void Evaluate2(const wavelet_decomposition &WaveletCoeffs_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN); void Eval2(float ** WavCoeffs_L, int level, int W_L, int H_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN); + void calceffect(int level, float *mean, float *sigma, float *mea, float effect, float offs); + void Aver(float * HH_Coeffs, int datalen, float &averagePlus, float &averageNeg, float &max, float &min); void Sigma(float * HH_Coeffs, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg); +// void calckoe(float ** WavCoeffs_LL, const cont_params& cp, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC = nullptr); // void calckoe(float ** WavCoeffs_LL, const struct cont_params& cp, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC = nullptr); void calckoe(float ** WavCoeffs_LL, float gradw, float tloww, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC = nullptr); + void softproc2(const LabImage* bufcolorig, const LabImage* bufcolfin, float rad, int bfh, int bfw, double epsilmax, double epsilmin, float thres, int sk, bool multiThread, int flag); void Median_Denoise(float **src, float **dst, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); @@ -400,18 +406,22 @@ public: void RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, bool isRAW, const LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &minredaut, float & minblueaut, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread = false); void RGBtile_denoise(float * fLblox, int hblproc, float noisevar_Ldetail); //for DCT void RGBoutput_tile_row(float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top); - bool WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels); - bool WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels); - bool WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels); void WaveletDenoiseAll_info(int levwav, const wavelet_decomposition &WaveletCoeffs_a, const wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float & minblueaut, int schoice, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb); + bool WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels); + bool WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels); + bool WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels); + bool WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels); + void ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge); void ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * variC, int local, float * madaab = nullptr, bool madCalculated = false); + + void ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, int W_ab, int H_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, int lvl, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb); @@ -439,7 +449,7 @@ public: void ToneMapFattal02(Imagefloat *rgb, const procparams::FattalToneMappingParams &fatParams, int detail_level, int Lalone, float **Lum, int WW, int HH, int algo); void localContrast(LabImage *lab, float **destination, const procparams::LocalContrastParams &localContrastParams, bool fftwlc, double scale); void colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread); - // void shadowsHighlights(LabImage *lab); + //void shadowsHighlights(LabImage *lab); void shadowsHighlights(LabImage *lab, bool ena, int labmode, int hightli, int shado, int rad, int scal, int hltonal, int shtonal); void softLight(LabImage *lab, const procparams::SoftLightParams &softLightParams); diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 4b72e269d..127f60976 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -266,9 +266,9 @@ float estimate_ambient_light(const array2D &R, const array2D &G, c float b = B[y][x]; if (r + g + b >= bright_lim) { - rr += r; - gg += g; - bb += b; + rr += static_cast(r); + gg += static_cast(g); + bb += static_cast(b); ++n; } } diff --git a/rtengine/iplabregions.cc b/rtengine/iplabregions.cc index 6526419f5..786d42e56 100644 --- a/rtengine/iplabregions.cc +++ b/rtengine/iplabregions.cc @@ -139,7 +139,7 @@ BENCHFUN auto &hm = hmask[i]; auto &cm = cmask[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; } } @@ -147,8 +147,8 @@ BENCHFUN } for (int i = begin_idx; i < end_idx; ++i) { - float blur = params->colorToning.labregions[i].maskBlur; - blur = blur < 0.f ? -1.f/blur : 1.f + blur; + double blur = params->colorToning.labregions[i].maskBlur; + blur = blur < 0.0 ? -1.0 / blur : 1.0 + blur; int r1 = max(int(4 / 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); @@ -188,7 +188,7 @@ BENCHFUN auto &r = params->colorToning.labregions[i]; abca[i] = abcoord(r.a); 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; offset[i] = r.offset; power[i] = r.power; diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index 6bc9834e3..d04f9d3e7 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -155,8 +155,8 @@ void mean_stddv2(float **dst, float &mean, float &stddv, int W_L, int H_L, float for (int i = 0; i < H_L; i++) for (int j = 0; j < W_L; j++) { - sum += dst[i][j]; - vsquared += (dst[i][j] * dst[i][j]); + sum += static_cast(dst[i][j]); + vsquared += rtengine::SQR(dst[i][j]); lmax = dst[i][j] > lmax ? dst[i][j] : lmax; lmin = dst[i][j] < lmin ? dst[i][j] : lmin; @@ -173,8 +173,8 @@ void mean_stddv2(float **dst, float &mean, float &stddv, int W_L, int H_L, float } mean = sum / (double)(W_L * H_L); vsquared /= (double) W_L * H_L; - stddv = (vsquared - (mean * mean)); - stddv = (float)sqrt(stddv); + stddv = vsquared - rtengine::SQR(mean); + stddv = std::sqrt(stddv); } } @@ -731,9 +731,9 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e float valparam; if (useHsl || useHslLin) { - valparam = shcurve->getVal(HH) - 0.5f; + valparam = shcurve->getVal(HH) - 0.5; } 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); diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc index 9292fb7bd..7d6b0f90a 100644 --- a/rtengine/ipsharpen.cc +++ b/rtengine/ipsharpen.cc @@ -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) { - const float dampingFac = -2.0 / (damping * damping); + const float dampingFac = -2.f / (damping * damping); #ifdef __SSE2__ 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) { - if (sharpenParam.deconvamount == 0 && sharpenParam.blurradius < 0.25f) { + if (sharpenParam.deconvamount == 0 && sharpenParam.blurradius < 0.25) { return; } BENCHFUN @@ -180,7 +180,7 @@ BENCHFUN JaggedArray* blurbuffer = nullptr; - if (sharpenParam.blurradius >= 0.25f) { + if (sharpenParam.blurradius >= 0.25) { blurbuffer = new JaggedArray(W, H); JaggedArray &blur = *blurbuffer; #ifdef _OPENMP @@ -229,7 +229,7 @@ BENCHFUN } } - if (sharpenParam.blurradius >= 0.25f) { + if (sharpenParam.blurradius >= 0.25) { JaggedArray &blur = *blurbuffer; #ifdef _OPENMP #pragma omp for @@ -356,7 +356,7 @@ void ImProcFunctions::sharpening (LabImage* lab, const procparams::SharpeningPar // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); - float contrast = sharpenParam.contrast / 100.f; + float contrast = sharpenParam.contrast / 100.0; buildBlendMask(lab->L, blend, W, H, contrast); if(showMask) { @@ -393,7 +393,7 @@ BENCHFUN JaggedArray blur(W, H); - if (sharpenParam.blurradius >= 0.25f) { + if (sharpenParam.blurradius >= 0.25) { #ifdef _OPENMP #pragma omp parallel #endif @@ -473,7 +473,7 @@ BENCHFUN delete [] b3; } - if (sharpenParam.blurradius >= 0.25f) { + if (sharpenParam.blurradius >= 0.25) { #ifdef _OPENMP #pragma omp parallel for #endif @@ -486,241 +486,6 @@ BENCHFUN } -// To the extent possible under law, Manuel Llorens -// 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 // has waived all copyright and related or neighboring rights to this work. // This code is licensed under CC0 v1.0, see license information at @@ -741,10 +506,10 @@ BENCHFUN // k=2 matrix 5x5 k=1 matrix 3x3 const int width = W, height = H; 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) { - printf ("Micro-contrast amount %f\n", amount); + printf ("Micro-contrast amount %f\n", static_cast(amount)); printf ("Micro-contrast uniformity %i\n", unif); } @@ -775,7 +540,7 @@ BENCHFUN // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); - float contrast = params->sharpenMicro.contrast / 100.f; + float contrast = params->sharpenMicro.contrast / 100.0; buildBlendMask(luminance, blend, W, H, contrast); #ifdef _OPENMP @@ -984,7 +749,7 @@ void ImProcFunctions::sharpeningcam (CieImage* ncie, float** b2, bool showMask) // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray 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); if(showMask) { #ifdef _OPENMP diff --git a/rtengine/ipsharpenedges.cc b/rtengine/ipsharpenedges.cc new file mode 100644 index 000000000..6a44ee40a --- /dev/null +++ b/rtengine/ipsharpenedges.cc @@ -0,0 +1,217 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2020 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . +*/ + +#include +#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 +// 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 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); + } + } + } + } + } +} + +} diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index a9a84ea3f..a71715107 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -689,11 +689,11 @@ static void calcGradientParams (int oW, int oH, const GradientParams& gradient, gp.ta = tan (gradient_angle); gp.xc = w * gradient_center_x; gp.yc = h * gradient_center_y; - gp.ys = sqrt ((float)h * h + (float)w * w) * (gradient_span / cos (gradient_angle)); - gp.ys_inv = 1.0 / gp.ys; - gp.top_edge_0 = gp.yc - gp.ys / 2.0; + gp.ys = rtengine::norm2(static_cast(h), static_cast(w)) * (gradient_span / cos(gradient_angle)); + gp.ys_inv = 1.f / gp.ys; + 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 = 0; } @@ -723,7 +723,7 @@ float ImProcFunctions::calcGradientFactor (const struct grad_params& gp, int x, val = 1.f - pow3 (xcosf (val)); } - return gp.scale + val * (1.0 - gp.scale); + return gp.scale + val * (1.f - gp.scale); } } else { int gy = gp.transpose ? x : y; @@ -747,7 +747,7 @@ float ImProcFunctions::calcGradientFactor (const struct grad_params& gp, int x, 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 - double roundness = pcvignette.roundness / 100.0; + float roundness = pcvignette.roundness / 100.f; pcv.feather = pcvignette.feather / 100.0; if (crop.enabled) { @@ -783,42 +783,40 @@ static void calcPCVignetteParams (int fW, int fH, int oW, int oH, const PCVignet pcv.h = oH; } - pcv.fadeout_mul = 1.0 / (0.05 * sqrtf (oW * oW + oH * oH)); + pcv.fadeout_mul = 20.0 / rtengine::norm2(static_cast(oW), static_cast(oW)); float short_side = (pcv.w < pcv.h) ? pcv.w : pcv.h; float long_side = (pcv.w > pcv.h) ? pcv.w : pcv.h; pcv.sep = 2; 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.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_portrait = (pcv.w < pcv.h); - if (roundness < 0.5) { + if (roundness < 0.5f) { // make super-ellipse of higher and higher degree 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.sepmix = (sepf - pcv.sep) * 0.5; // 0.0 to 1.0 - pcv.oe1_a = powf (2.0, 1.0 / pcv.sep) * long_side * 0.5; + pcv.sepmix = (sepf - pcv.sep) * 0.5f; // 0.0 to 1.0 + 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.ie1_mul = (1.0 / powf (2.0, 1.0 / pcv.sep)) * (1.0 - pcv.feather); - pcv.oe2_a = powf (2.0, 1.0 / (pcv.sep + 2)) * long_side * 0.5; + pcv.ie1_mul = (1.f - pcv.feather) / std::pow(2.f, 1.f / pcv.sep); + 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.ie2_mul = (1.0 / powf (2.0, 1.0 / (pcv.sep + 2))) * (1.0 - pcv.feather); - } - - if (roundness > 0.5) { + pcv.ie2_mul = (1.f - pcv.feather) / std::pow(2.f, 1.f / (pcv.sep + 2)); + } else if (roundness > 0.5f) { // 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(pcv.w), static_cast(pcv.h)) / 2.f; float diff_a = rad - pcv.oe_a; float diff_b = rad - pcv.oe_b; - pcv.oe_a = pcv.oe_a + diff_a * 2 * (roundness - 0.5); - pcv.oe_b = pcv.oe_b + diff_b * 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.5f); } - pcv.scale = powf (2, -pcvignette.strength); + pcv.scale = std::pow(2, -pcvignette.strength); if (pcvignette.strength >= 6.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); 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 { - factor = v + mul * tanh (b * (maxRadius - r) / maxRadius); + factor = v + mul * tanh(b * (maxRadius - r) / maxRadius); } } if (applyGradient) { - factor *= calcGradientFactor (gp, cx + x, cy + y); + factor *= static_cast(calcGradientFactor(gp, cx + x, cy + y)); } if (applyPCVignetting) { - factor *= calcPCVignetteFactor (pcv, cx + x, cy + y); + factor *= static_cast(calcPCVignetteFactor(pcv, cx + x, cy + y)); } - transformed->r (y, x) = original->r (y, x) * factor; - transformed->g (y, x) = original->g (y, x) * factor; - transformed->b (y, x) = original->b (y, x) * factor; + transformed->r(y, x) = static_cast(original->r(y, x)) * factor; + transformed->g(y, x) = static_cast(original->g(y, x)) * factor; + transformed->b(y, x) = static_cast(original->b(y, x)) * factor; } } } @@ -1147,11 +1145,11 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I } if (enableGradient) { - vignmul *= calcGradientFactor(gp, cx + x, cy + y); + vignmul *= static_cast(calcGradientFactor(gp, cx + x, cy + y)); } if (enablePCVignetting) { - vignmul *= calcPCVignetteFactor(pcv, cx + x, cy + y); + vignmul *= static_cast(calcPCVignetteFactor(pcv, cx + x, cy + y)); } if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) { diff --git a/rtengine/ipvibrance.cc b/rtengine/ipvibrance.cc index e081a696b..43002c2a3 100644 --- a/rtengine/ipvibrance.cc +++ b/rtengine/ipvibrance.cc @@ -48,7 +48,7 @@ void fillCurveArrayVib (DiagonalCurve* diagCurve, LUTf &outCurve) // change to [0,1] range // apply custom/parametric/NURBS curve, if any // 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 { outCurve.makeIdentity(); @@ -605,7 +605,7 @@ void ImProcFunctions::vibrance (LabImage* lab, const procparams::VibranceParams bool inGamut; 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(Color::epskap)) ? fyy * fyy*fyy : Lprov / Color::kappaf; float ChprovOld = std::numeric_limits::min(); do { inGamut = true; diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 6c73844dc..30b4289e2 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -3,7 +3,7 @@ // // // -// code dated: December , 2014 +// code dated: 9 , 2019 // // Ipwaveletcc is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . -// * 2014 Jacques Desmis +// * 2014 - 2019 2020 - Jacques Desmis // * 2014 Ingo Weyrich // @@ -26,15 +26,16 @@ #include #include -#include "../rtgui/threadutils.h" - #include "array2D.h" #include "color.h" #include "curves.h" #include "EdgePreservingDecomposition.h" #include "iccstore.h" #include "improcfun.h" +#include "imagefloat.h" #include "labimage.h" +#include "gauss.h" +#include "boxblur.h" #include "LUT.h" #include "median.h" #include "opthelper.h" @@ -43,7 +44,7 @@ #include "rtengine.h" #include "sleef.h" #include "../rtgui/options.h" - +#include "guidedfilter.h" #ifdef _OPENMP #include #endif @@ -55,14 +56,21 @@ namespace rtengine struct cont_params { float mul[10]; + float sigm; int chrom; int chro; + float chrwav; int contrast; float th; float thH; float conres; float conresH; + float blurres; + float blurcres; + float bluwav; + float radius; float chrores; + bool oldsh; float hueres; float sky; float b_l, t_l, b_r, t_r; @@ -74,6 +82,7 @@ struct cont_params { float b_lpast, t_lpast, b_rpast, t_rpast; float b_lsat, t_lsat, b_rsat, t_rsat; int rad; + float eff; int val; int til; int numlevH, numlevS; @@ -123,55 +132,55 @@ struct cont_params { bool finena; bool toningena; bool noiseena; + bool blena; int maxilev; float edgsens; float edgampl; int neigh; bool lipp; + float ballum; + float balchrom; + float chromfi; + float chromco; }; int wavNestedLevels = 1; -void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, LUTf &wavclCurve, int skip) +void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip) + { #ifdef _DEBUG // init variables to display Munsell corrections MunsellDebugInfo* MunsDebugInfo = new MunsellDebugInfo(); #endif - TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix (params->icm.workingProfile); + TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(params->icm.workingProfile); const double wip[3][3] = { {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, {wiprof[2][0], wiprof[2][1], wiprof[2][2]} }; - const short int imheight = lab->H, imwidth = lab->W; + const int imheight = lab->H, imwidth = lab->W; + struct cont_params cp; + cp.avoi = params->wavelet.avoid; if (params->wavelet.Medgreinf == "more") { cp.reinforce = 1; - } - - if (params->wavelet.Medgreinf == "none") { + } else if (params->wavelet.Medgreinf == "none") { cp.reinforce = 2; - } - - if (params->wavelet.Medgreinf == "less") { + } else if (params->wavelet.Medgreinf == "less") { cp.reinforce = 3; } if (params->wavelet.NPmethod == "none") { cp.lip3 = false; - } - - if (params->wavelet.NPmethod == "low") { + } else if (params->wavelet.NPmethod == "low") { cp.lip3 = true; cp.neigh = 0; - } - - if (params->wavelet.NPmethod == "high") { + } else if (params->wavelet.NPmethod == "high") { cp.lip3 = true; cp.neigh = 1; } @@ -180,15 +189,9 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.diag = params->wavelet.tmr; cp.balan = (float)params->wavelet.balance; cp.ite = params->wavelet.iter; - cp.tonemap = false; + cp.tonemap = params->wavelet.tmrs != 0; cp.bam = false; - if (params->wavelet.tmrs == 0) { - cp.tonemap = false; - } else { - cp.tonemap = true; - } - if (params->wavelet.TMmethod == "cont") { cp.contmet = 1; } else if (params->wavelet.TMmethod == "tm") { @@ -197,18 +200,17 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (params->wavelet.BAmethod != "none") { cp.bam = true; + + if (params->wavelet.BAmethod == "sli") { + cp.BAmet = 1; + } else if (params->wavelet.BAmethod == "cur") { + cp.BAmet = 2; + } } - if (params->wavelet.BAmethod == "sli") { - cp.BAmet = 1; - } - - if (params->wavelet.BAmethod == "cur") { - cp.BAmet = 2; - } + cp.sigm = params->wavelet.sigma; cp.tmstrength = params->wavelet.tmrs; - //cp.tonemap = params->wavelet.tmr; cp.contena = params->wavelet.expcontrast; cp.chromena = params->wavelet.expchroma; cp.edgeena = params->wavelet.expedge; @@ -216,16 +218,14 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.finena = params->wavelet.expfinal; cp.toningena = params->wavelet.exptoning; cp.noiseena = params->wavelet.expnoise; + cp.blena = params->wavelet.expbl; + cp.chrwav = 0.01f * params->wavelet.chrwav; if (params->wavelet.Backmethod == "black") { cp.backm = 0; - } - - if (params->wavelet.Backmethod == "grey") { + } else if (params->wavelet.Backmethod == "grey") { cp.backm = 1; - } - - if (params->wavelet.Backmethod == "resid") { + } else if (params->wavelet.Backmethod == "resid") { cp.backm = 2; } @@ -242,8 +242,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.edgampl = (float) params->wavelet.edgeampli; } - //int N = imheight * imwidth; - int maxmul = params->wavelet.thres; + const int maxmul = params->wavelet.thres; cp.maxilev = maxmul; static const float scales[10] = {1.f, 2.f, 4.f, 8.f, 16.f, 32.f, 64.f, 128.f, 256.f, 512.f}; float scaleskip[10]; @@ -252,42 +251,30 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const scaleskip[sc] = scales[sc] / skip; } - float atten0 = 0.40f; - float atten123 = 0.90f; + constexpr float atten0 = 0.40f; + constexpr float atten123 = 0.90f; //int DaubLen = settings->daubech ? 8 : 6; int DaubLen; if (params->wavelet.daubcoeffmethod == "2_") { DaubLen = 4; - } - - if (params->wavelet.daubcoeffmethod == "4_") { + } else if (params->wavelet.daubcoeffmethod == "4_") { DaubLen = 6; - } - - if (params->wavelet.daubcoeffmethod == "6_") { + } else if (params->wavelet.daubcoeffmethod == "6_") { DaubLen = 8; - } - - if (params->wavelet.daubcoeffmethod == "10_") { + } else if (params->wavelet.daubcoeffmethod == "10_") { DaubLen = 12; - } - - if (params->wavelet.daubcoeffmethod == "14_") { + } else { /* if (params->wavelet.daubcoeffmethod == "14_") */ DaubLen = 16; } cp.CHSLmet = 1; -// if(params->wavelet.CHSLmethod=="SL") cp.CHSLmet=1; -// if(params->wavelet.CHSLmethod=="CU") cp.CHSLmet=2; cp.EDmet = 1; if (params->wavelet.EDmethod == "SL") { cp.EDmet = 1; - } - - if (params->wavelet.EDmethod == "CU") { + } else if (params->wavelet.EDmethod == "CU") { cp.EDmet = 2; } @@ -309,9 +296,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (params->wavelet.CHmethod == "with") { cp.CHmet = 1; - } - - if (params->wavelet.CHmethod == "link") { + } else if (params->wavelet.CHmethod == "link") { cp.CHmet = 2; } @@ -319,7 +304,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.HSmet = true; } - cp.strength = min (1.f, max (0.f, ((float)params->wavelet.strength / 100.f))); + cp.strength = rtengine::min(1.f, rtengine::max(0.f, ((float)params->wavelet.strength / 100.f))); for (int m = 0; m < maxmul; m++) { cp.mulC[m] = waparams.ch[m]; @@ -391,7 +376,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } -// if(settings->verbose) printf("Wav mul 0=%f 1=%f 2=%f 3=%f 4=%f 5=%f 6=%f 7=%f 8=%f 9=%f\n",cp.mul[0],cp.mul[1],cp.mul[2],cp.mul[3],cp.mul[4],cp.mul[5],cp.mul[6],cp.mul[7],cp.mul[8],cp.mul[9]); for (int sc = 0; sc < 9; sc++) { //reduce strength if zoom < 100% for chroma and tuning if (sc == 0) { if (scaleskip[sc] < 1.f) { @@ -414,14 +398,24 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.rad = waparams.edgrad; cp.val = waparams.edgval; cp.til = waparams.edgthresh; + cp.eff = waparams.edgeffect; + cp.balchrom = waparams.balchrom; + cp.chromfi = 0.1f * waparams.chromfi; + cp.chromco = 0.1f * waparams.chromco; + cp.ballum = waparams.ballum; cp.conres = waparams.rescon; cp.conresH = waparams.resconH; + cp.radius = waparams.radius; cp.chrores = waparams.reschro; + cp.oldsh = waparams.oldsh; + cp.blurres = waparams.resblur; + cp.blurcres = waparams.resblurc; + cp.bluwav = waparams.bluwav; //cp.hueres=waparams.reshue; cp.hueres = 2.f; - cp.th = float (waparams.thr); - cp.thH = float (waparams.thrH); + cp.th = float(waparams.thr); + cp.thH = float(waparams.thrH); cp.sky = waparams.sky; //skin cp.b_l = static_cast(params->wavelet.hueskin.getBottomLeft()) / 100.0f; @@ -442,14 +436,12 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.t_rsl = static_cast(params->wavelet.bllev.getTopRight()); cp.numlevS = params->wavelet.threshold2; int maxlevS = 9 - cp.numlevH; - cp.numlevS = MIN (cp.numlevS, maxlevS); - //printf("levHigh=%d levShad=%d\n",cp.numlevH,cp.numlevS); + cp.numlevS = rtengine::min(cp.numlevS, maxlevS); //highlight cp.b_lhl = static_cast(params->wavelet.hllev.getBottomLeft()); cp.t_lhl = static_cast(params->wavelet.hllev.getTopLeft()); cp.b_rhl = static_cast(params->wavelet.hllev.getBottomRight()); cp.t_rhl = static_cast(params->wavelet.hllev.getTopRight()); - //printf("BL=%f TL=%f BR=%f TR=%f\n",cp.b_lhl,cp.t_lhl,cp.b_rhl,cp.t_rhl); //pastel cp.b_lpast = static_cast(params->wavelet.pastlev.getBottomLeft()); cp.t_lpast = static_cast(params->wavelet.pastlev.getTopLeft()); @@ -476,8 +468,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.lev3n = static_cast(params->wavelet.level3noise.getTop()); cp.detectedge = params->wavelet.medianlev; - //printf("low=%f mean=%f sd=%f max=%f\n",cp.edg_low,cp.edg_mean,cp.edg_sd,cp.edg_max); - int minwin = min (imwidth, imheight); + int minwin = rtengine::min(imwidth, imheight); int maxlevelcrop = 9; if (cp.mul[9] != 0) { @@ -505,7 +496,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const maxlevelcrop = 5; } - // printf("minwin=%d maxcrop=%d\n",minwin, maxlevelcrop); int levwav = params->wavelet.thres; @@ -513,10 +503,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const levwav = 10; } - levwav = min (maxlevelcrop, levwav); + levwav = rtengine::min(maxlevelcrop, levwav); // determine number of levels to process. - // for(levwav=min(maxlevelcrop,levwav);levwav>0;levwav--) + // for(levwav=rtengine::min(maxlevelcrop,levwav);levwav>0;levwav--) // if(cp.mul[levwav-1]!=0.f || cp.curv) // if(cp.mul[levwav-1]!=0.f) // break; @@ -535,10 +525,11 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const realtile = 22; } - if (params->wavelet.Tilesmethod == "lit") { - realtile = 12; - } - + /* + if (params->wavelet.Tilesmethod == "lit") { + realtile = 12; + } + */ int tilesize = 128 * realtile; int overlap = (int) tilesize * 0.125f; int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; @@ -547,7 +538,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const kall = 0; } - Tile_calc (tilesize, overlap, kall, imwidth, imheight, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); + Tile_calc(tilesize, overlap, kall, imwidth, imheight, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); const int numtiles = numtiles_W * numtiles_H; LabImage * dsttmp; @@ -555,7 +546,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (numtiles == 1) { dsttmp = dst; } else { - dsttmp = new LabImage (imwidth, imheight); + dsttmp = new LabImage(imwidth, imheight); for (int n = 0; n < 3 * imwidth * imheight; n++) { dsttmp->data[n] = 0; @@ -564,7 +555,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const //now we have tile dimensions, overlaps //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - int minsizetile = min (tilewidth, tileheight); + int minsizetile = rtengine::min(tilewidth, tileheight); int maxlev2 = 10; if (minsizetile < 1024 && levwav == 10) { @@ -583,9 +574,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const maxlev2 = 6; } - levwav = min (maxlev2, levwav); - - //printf("levwav = %d\n",levwav); + levwav = rtengine::min(maxlev2, levwav); #ifdef _OPENMP int numthreads = 1; @@ -613,7 +602,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const maxnumberofthreadsforwavelet = 8; } - //printf("maxNRT=%d\n",maxnumberofthreadsforwavelet); if ((maxnumberofthreadsforwavelet == 6 || maxnumberofthreadsforwavelet == 8) && levwav == 10) { maxnumberofthreadsforwavelet -= 2; } @@ -623,18 +611,17 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } - //printf("maxthre=%d\n",maxnumberofthreadsforwavelet); // Calculate number of tiles. If less than omp_get_max_threads(), then limit num_threads to number of tiles - if ( options.rgbDenoiseThreadLimit > 0) { - maxnumberofthreadsforwavelet = min (max (options.rgbDenoiseThreadLimit / 2, 1), maxnumberofthreadsforwavelet); + if (options.rgbDenoiseThreadLimit > 0) { + maxnumberofthreadsforwavelet = rtengine::LIM(options.rgbDenoiseThreadLimit / 2, 1, maxnumberofthreadsforwavelet); } - numthreads = MIN (numtiles, omp_get_max_threads()); + numthreads = rtengine::min(numtiles, omp_get_max_threads()); if (maxnumberofthreadsforwavelet > 0) { - numthreads = MIN (numthreads, maxnumberofthreadsforwavelet); + numthreads = rtengine::min(numthreads, maxnumberofthreadsforwavelet); } #ifdef _OPENMP @@ -644,7 +631,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (wavNestedLevels < 2) { wavNestedLevels = 1; } else { - omp_set_nested (true); + omp_set_nested(true); } if (maxnumberofthreadsforwavelet > 0) @@ -655,7 +642,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const #endif if (settings->verbose) { - printf ("Ip Wavelet uses %d main thread(s) and up to %d nested thread(s) for each main thread\n", numthreads, wavNestedLevels); + printf("Ip Wavelet uses %d main thread(s) and up to %d nested thread(s) for each main thread\n", numthreads, wavNestedLevels); } #pragma omp parallel num_threads(numthreads) @@ -668,17 +655,22 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const float MaxP[10]; float MaxN[10]; + float meanab[10]; + float meanNab[10]; + float sigmaab[10]; + float sigmaNab[10]; + float MaxPab[10]; + float MaxNab[10]; + + array2D varchro(tilewidth, tileheight); + float** varhue = new float*[tileheight]; for (int i = 0; i < tileheight; i++) { varhue[i] = new float[tilewidth]; } - float** varchro = new float*[tileheight]; - for (int i = 0; i < tileheight; i++) { - varchro[i] = new float[tilewidth]; - } #ifdef _OPENMP #pragma omp for schedule(dynamic) collapse(2) @@ -686,8 +678,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const for (int tiletop = 0; tiletop < imheight; tiletop += tileHskip) { for (int tileleft = 0; tileleft < imwidth ; tileleft += tileWskip) { - int tileright = MIN (imwidth, tileleft + tilewidth); - int tilebottom = MIN (imheight, tiletop + tileheight); + int tileright = rtengine::min(imwidth, tileleft + tilewidth); + int tilebottom = rtengine::min(imheight, tiletop + tileheight); int width = tileright - tileleft; int height = tilebottom - tiletop; LabImage * labco; @@ -700,7 +692,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (cp.avoi) { // we need a buffer to hold a copy of the L channel Lold = new float*[tileheight]; LoldBuffer = new float[tilewidth * tileheight]; - memcpy (LoldBuffer, lab->L[0], tilewidth * tileheight * sizeof (float)); + memcpy(LoldBuffer, lab->L[0], tilewidth * tileheight * sizeof(float)); for (int i = 0; i < tileheight; i++) { Lold[i] = LoldBuffer + i * tilewidth; @@ -708,7 +700,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } else { - labco = new LabImage (width, height); + labco = new LabImage(width, height); Lold = lab->L; } @@ -717,38 +709,33 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const #endif for (int i = tiletop; i < tilebottom; i++) { - int i1 = i - tiletop; - int j; + const int i1 = i - tiletop; + int j = tileleft; #ifdef __SSE2__ - __m128 c327d68v = _mm_set1_ps (327.68f); - __m128 av, bv, huev, chrov; + const vfloat c327d68v = F2V(327.68f); - for (j = tileleft; j < tileright - 3; j += 4) { - int j1 = j - tileleft; - av = LVFU (lab->a[i][j]); - bv = LVFU (lab->b[i][j]); - huev = xatan2f (bv, av); - chrov = vsqrtf(SQRV(av) + SQRV(bv)) / c327d68v; - _mm_storeu_ps (&varhue[i1][j1], huev); - _mm_storeu_ps (&varchro[i1][j1], chrov); + for (; j < tileright - 3; j += 4) { + const int j1 = j - tileleft; + const vfloat av = LVFU(lab->a[i][j]); + const vfloat bv = LVFU(lab->b[i][j]); + STVFU(varhue[i1][j1], xatan2f(bv, av)); + STVFU(varchro[i1][j1], vsqrtf(SQRV(av) + SQRV(bv)) / c327d68v); if (labco != lab) { - _mm_storeu_ps (& (labco->L[i1][j1]), LVFU (lab->L[i][j])); - _mm_storeu_ps (& (labco->a[i1][j1]), av); - _mm_storeu_ps (& (labco->b[i1][j1]), bv); + STVFU((labco->L[i1][j1]), LVFU(lab->L[i][j])); + STVFU((labco->a[i1][j1]), av); + STVFU((labco->b[i1][j1]), bv); } } -#else - j = tileleft; #endif for (; j < tileright; j++) { - int j1 = j - tileleft; - float a = lab->a[i][j]; - float b = lab->b[i][j]; - varhue[i1][j1] = xatan2f (b, a); - varchro[i1][j1] = (sqrtf (a * a + b * b)) / 327.68f; + const int j1 = j - tileleft; + const float a = lab->a[i][j]; + const float b = lab->b[i][j]; + varhue[i1][j1] = xatan2f(b, a); + varchro[i1][j1] = (sqrtf(a * a + b * b)) / 327.68f; if (labco != lab) { labco->L[i1][j1] = lab->L[i][j]; @@ -770,7 +757,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const tmL[i] = new float[wid]; } - for (int i = borderL; i < hei - borderL; i++ ) { + for (int i = borderL; i < hei - borderL; i++) { for (int j = borderL; j < wid - borderL; j++) { tmL[i][j] = labco->L[i][j]; } @@ -783,12 +770,12 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const for (int i = 1; i < hei - 1; i++) { for (int j = 1; j < wid - 1; j++) { if ((varhue[i][j] < -1.3f && varhue[i][j] > - 2.5f) && (varchro[i][j] > 15.f && varchro[i][j] < 55.f) && labco->L[i][j] > 6000.f) { //blue sky + med3x3 ==> after for more effect use denoise - tmL[i][j] = median (labco->L[i][j] , labco->L[i - 1][j], labco->L[i + 1][j] , labco->L[i][j + 1], labco->L[i][j - 1], labco->L[i - 1][j - 1], labco->L[i - 1][j + 1], labco->L[i + 1][j - 1], labco->L[i + 1][j + 1]); //3x3 + tmL[i][j] = median(labco->L[i][j], labco->L[i - 1][j], labco->L[i + 1][j], labco->L[i][j + 1], labco->L[i][j - 1], labco->L[i - 1][j - 1], labco->L[i - 1][j + 1], labco->L[i + 1][j - 1], labco->L[i + 1][j + 1]); //3x3 } } } - for (int i = borderL; i < hei - borderL; i++ ) { + for (int i = borderL; i < hei - borderL; i++) { for (int j = borderL; j < wid - borderL; j++) { labco->L[i][j] = tmL[i][j]; } @@ -804,7 +791,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (numtiles == 1) { // reduce the varhue array to get faster access in following processing and reduce peak memory usage - float temphue[ (tilewidth + 1) / 2] ALIGNED64; + float temphue[(tilewidth + 1) / 2] ALIGNED64; for (int i = 0; i < (tileheight + 1) / 2; i++) { for (int j = 0; j < (tilewidth + 1) / 2; j++) { @@ -812,8 +799,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } delete [] varhue[i]; - varhue[i] = new float[ (tilewidth + 1) / 2]; - memcpy (varhue[i], temphue, ((tilewidth + 1) / 2) * sizeof (float)); + varhue[i] = new float[(tilewidth + 1) / 2]; + memcpy(varhue[i], temphue, ((tilewidth + 1) / 2) * sizeof(float)); } for (int i = (tileheight + 1) / 2; i < tileheight; i++) { @@ -837,41 +824,65 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const ref0 = true; } - // printf("LevwavL before: %d\n",levwavL); - if (cp.contrast == 0.f && !cp.tonemap && cp.conres == 0.f && cp.conresH == 0.f && cp.val == 0 && !ref0 && params->wavelet.CLmethod == "all") { // no processing of residual L or edge=> we probably can reduce the number of levels + bool wavcurvecomp = false;//not enable if 0.75 + + if (wavblcurve) { + for (int i = 0; i < 500; i++) { + if (wavblcurve[i] != 0.) { + wavcurvecomp = true; + } + } + } + + bool exblurL = cp.blena && wavcurvecomp; + + if (exblurL) { + if (cp.mul[0] == 0.f) { + cp.mul[0] = 0.01f;//to always enable WaveletcontAllL if no contrast is nead + } + } + + if (!exblurL && cp.contrast == 0.f && cp.blurres == 0.f && !cp.tonemap && cp.conres == 0.f && cp.conresH == 0.f && cp.val == 0 && !ref0 && params->wavelet.CLmethod == "all") { // no processing of residual L or edge=> we probably can reduce the number of levels while (levwavL > 0 && cp.mul[levwavL - 1] == 0.f) { // cp.mul[level] == 0.f means no changes to level levwavL--; } } - // printf("LevwavL after: %d\n",levwavL); - // if(cp.noiseena){ - if (levwavL < 4 ) { + if (cp.chromfi > 0.f || cp.chromco > 0.f) { + if (levwavL < 7) { + levwavL = 7; + } + } + + if (levwavL < 4) { levwavL = 4; //to allow edge => I always allocate 3 (4) levels..because if user select wavelet it is to do something !! } - // } - // else { - // if(levwavL < 3) levwavL=3;//to allow edge => I always allocate 3 (4) levels..because if user select wavelet it is to do something !! - // } + if (settings->verbose) { + printf("Level decomp L=%i\n", levwavL); + } + + bool usechrom = cp.chromfi > 0.f || cp.chromco > 0.f; + if (levwavL > 0) { - wavelet_decomposition* Ldecomp = new wavelet_decomposition (labco->data, labco->W, labco->H, levwavL, 1, skip, max (1, wavNestedLevels), DaubLen ); + const std::unique_ptr Ldecomp(new wavelet_decomposition(labco->data, labco->W, labco->H, levwavL, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); + float madL[8][3]; if (!Ldecomp->memoryAllocationFailed) { - float madL[8][3]; + // float madL[8][3]; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) collapse(2) num_threads(wavNestedLevels) if(wavNestedLevels>1) #endif - for (int lvl = 0; lvl < 4; lvl++) { + for (int lvl = 0; lvl < levwavL; lvl++) { for (int dir = 1; dir < 4; dir++) { - int Wlvl_L = Ldecomp->level_W (lvl); - int Hlvl_L = Ldecomp->level_H (lvl); + int Wlvl_L = Ldecomp->level_W(lvl); + int Hlvl_L = Ldecomp->level_H(lvl); - float ** WavCoeffs_L = Ldecomp->level_coeffs (lvl); + float ** WavCoeffs_L = Ldecomp->level_coeffs(lvl); - madL[lvl][dir - 1] = SQR (Mad (WavCoeffs_L[dir], Wlvl_L * Hlvl_L)); + madL[lvl][dir - 1] = SQR(Mad(WavCoeffs_L[dir], Wlvl_L * Hlvl_L)); } } @@ -889,29 +900,76 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } - if(cp.val > 0 || ref || contr) {//edge + if (cp.val > 0 || ref || contr) { //edge Evaluate2(*Ldecomp, mean, meanN, sigma, sigmaN, MaxP, MaxN); } //init for edge and denoise float vari[4]; - vari[0] = 8.f * SQR ((cp.lev0n / 125.0) * (1.0 + cp.lev0n / 25.0)); - vari[1] = 8.f * SQR ((cp.lev1n / 125.0) * (1.0 + cp.lev1n / 25.0)); - vari[2] = 8.f * SQR ((cp.lev2n / 125.0) * (1.0 + cp.lev2n / 25.0)); - vari[3] = 8.f * SQR ((cp.lev3n / 125.0) * (1.0 + cp.lev3n / 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.f) * (1.f + cp.lev1n / 25.f)); + vari[2] = 8.f * SQR((cp.lev2n / 125.f) * (1.f + cp.lev2n / 25.f)); + vari[3] = 8.f * SQR((cp.lev3n / 125.f) * (1.f + cp.lev3n / 25.f)); + float kr3 = 1.f; + + if (cp.lev3n < 10.f) { + kr3 = 0.f; + } else if (cp.lev3n < 30.f) { + kr3 = 0.5f; + } else if (cp.lev3n < 70.f) { + kr3 = 0.7f; + } else { + kr3 = 1.f; + } if ((cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f || cp.lev3n > 0.1f) && cp.noiseena) { - int edge = 1; - vari[0] = max (0.0001f, vari[0]); - vari[1] = max (0.0001f, vari[1]); - vari[2] = max (0.0001f, vari[2]); - vari[3] = max (0.0001f, vari[3]); - float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL + int edge = 4; + vari[0] = rtengine::max(0.0001f, vari[0]); + vari[1] = rtengine::max(0.0001f, vari[1]); + vari[2] = rtengine::max(0.0001f, vari[2]); + vari[3] = rtengine::max(0.0001f, kr3 * vari[3]); + // float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL + int GWL = labco->W; + int GHL = labco->H; + float* noisevarlum = new float[GHL * GWL]; + int GW2L = (GWL + 1) / 2; - WaveletDenoiseAllL (*Ldecomp, noisevarlum, madL, vari, edge, 1); - - } + float nvlh[13] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 0.7f, 0.5f}; //high value + float nvll[13] = {0.1f, 0.15f, 0.2f, 0.25f, 0.3f, 0.35f, 0.4f, 0.45f, 0.7f, 0.8f, 1.f, 1.f, 1.f}; //low value + + float seuillow = 3000.f;//low + float seuilhigh = 18000.f;//high + int i = 10 - cp.ballum; + float ac = (nvlh[i] - nvll[i]) / (seuillow - seuilhigh); + float bc = nvlh[i] - seuillow * ac; + +#ifdef _OPENMP + #pragma omp parallel for + +#endif + + for (int ir = 0; ir < GHL; ir++) + for (int jr = 0; jr < GWL; jr++) { + float lN = labco->L[ir][jr]; + + if (lN < seuillow) { + noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvlh[i]; + } else if (lN < seuilhigh) { + noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = ac * lN + bc; + } else { + noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvll[i]; + } + } + + if (cp.lev3n < 0.5f) { + WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1); + } else { + WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL, vari, edge, 1); + + WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1); + } + } //Flat curve for Contrast=f(H) in levels FlatCurve* ChCurve = new FlatCurve(params->wavelet.Chcurve); //curve C=f(H) @@ -926,110 +984,370 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const Chutili = true; } + WaveletcontAllL(labco, varhue, varchro, *Ldecomp, wavblcurve, cp, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); - WaveletcontAllL(labco, varhue, varchro, *Ldecomp, cp, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); - - if(cp.val > 0 || ref || contr || cp.diagcurv) {//edge + if (cp.val > 0 || ref || contr || cp.diagcurv) { //edge Evaluate2(*Ldecomp, mean, meanN, sigma, sigmaN, MaxP, MaxN); } - WaveletcontAllLfinal (*Ldecomp, cp, mean, sigma, MaxP, waOpacityCurveWL); + WaveletcontAllLfinal(*Ldecomp, cp, mean, sigma, MaxP, waOpacityCurveWL); + //Evaluate2(*Ldecomp, cp, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL); - - Ldecomp->reconstruct (labco->data, cp.strength); - } - - delete Ldecomp; - } - - //Flat curve for H=f(H) in residual image - FlatCurve* hhCurve = new FlatCurve(params->wavelet.hhcurve); //curve H=f(H) - bool hhutili = false; - - if (!hhCurve || hhCurve->isIdentity()) { - if (hhCurve) { - delete hhCurve; - hhCurve = nullptr; - } - } else { - hhutili = true; - } - - - if (!hhutili) { //always a or b - int levwava = levwav; - - // printf("Levwava before: %d\n",levwava); - if (cp.chrores == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels - while (levwava > 0 && !cp.diag && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwava - 1] == 0.f )) || (cp.CHmet != 2 && (levwava == 10 || (!cp.curv || cp.mulC[levwava - 1] == 0.f))))) && (!cp.opaRG || levwava == 10 || (cp.opaRG && cp.mulopaRG[levwava - 1] == 0.f)) && ((levwava == 10 || (cp.CHSLmet == 1 && cp.mulC[levwava - 1] == 0.f)))) { - levwava--; - } - } - - //printf("Levwava after: %d\n",levwava); - if (levwava > 0) { - wavelet_decomposition* adecomp = new wavelet_decomposition (labco->data + datalen, labco->W, labco->H, levwava, 1, skip, max (1, wavNestedLevels), DaubLen ); - - if (!adecomp->memoryAllocationFailed) { - WaveletcontAllAB (labco, varhue, varchro, *adecomp, waOpacityCurveW, cp, true); - adecomp->reconstruct (labco->data + datalen, cp.strength); + /* + Ldecomp->reconstruct(labco->data, cp.strength); + } + } + */ + if (!usechrom) { + Ldecomp->reconstruct(labco->data, cp.strength); } - delete adecomp; - } + float variC[7]; + float variCb[7]; - int levwavb = levwav; + float noisecfr = cp.chromfi; + float noiseccr = cp.chromco; - //printf("Levwavb before: %d\n",levwavb); - if (cp.chrores == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels - while (levwavb > 0 && !cp.diag && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwavb - 1] == 0.f )) || (cp.CHmet != 2 && (levwavb == 10 || (!cp.curv || cp.mulC[levwavb - 1] == 0.f))))) && (!cp.opaBY || levwavb == 10 || (cp.opaBY && cp.mulopaBY[levwavb - 1] == 0.f)) && ((levwavb == 10 || (cp.CHSLmet == 1 && cp.mulC[levwavb - 1] == 0.f)))) { - levwavb--; - } - } - - // printf("Levwavb after: %d\n",levwavb); - if (levwavb > 0) { - wavelet_decomposition* bdecomp = new wavelet_decomposition (labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, max (1, wavNestedLevels), DaubLen ); - - if (!bdecomp->memoryAllocationFailed) { - WaveletcontAllAB (labco, varhue, varchro, *bdecomp, waOpacityCurveW, cp, false); - bdecomp->reconstruct (labco->data + 2 * datalen, cp.strength); + if (cp.balchrom > 0.f) { + noisecfr = cp.chromfi * ((100.f + cp.balchrom) / 10.f); + noiseccr = cp.chromco + ((100.f + cp.balchrom) / 10.f); } - delete bdecomp; - } - } else {// a and b - int levwavab = levwav; - - // printf("Levwavab before: %d\n",levwavab); - if (cp.chrores == 0.f && !hhutili && params->wavelet.CLmethod == "all") { // no processing of residual ab => we probably can reduce the number of levels - while (levwavab > 0 && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwavab - 1] == 0.f )) || (cp.CHmet != 2 && (levwavab == 10 || (!cp.curv || cp.mulC[levwavab - 1] == 0.f))))) && (!cp.opaRG || levwavab == 10 || (cp.opaRG && cp.mulopaRG[levwavab - 1] == 0.f)) && ((levwavab == 10 || (cp.CHSLmet == 1 && cp.mulC[levwavab - 1] == 0.f)))) { - levwavab--; - } - } - - // printf("Levwavab after: %d\n",levwavab); - if (levwavab > 0) { - wavelet_decomposition* adecomp = new wavelet_decomposition (labco->data + datalen, labco->W, labco->H, levwavab, 1, skip, max (1, wavNestedLevels), DaubLen ); - wavelet_decomposition* bdecomp = new wavelet_decomposition (labco->data + 2 * datalen, labco->W, labco->H, levwavab, 1, skip, max (1, wavNestedLevels), DaubLen ); - - if(!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { - WaveletcontAllAB(labco, varhue, varchro, *adecomp, waOpacityCurveW, cp, true); - WaveletcontAllAB(labco, varhue, varchro, *bdecomp, waOpacityCurveW, cp, false); - WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili ); - - adecomp->reconstruct (labco->data + datalen, cp.strength); - bdecomp->reconstruct (labco->data + 2 * datalen, cp.strength); + float noisecfb = cp.chromfi; + float noiseccb = cp.chromco; + if (cp.balchrom < 0.f) { + noisecfb = cp.chromfi * ((100.f - cp.balchrom) / 10.f); + noiseccb = cp.chromco * ((100.f - cp.balchrom) / 10.f); } - delete adecomp; - delete bdecomp; - } - } - if (hhCurve) { - delete hhCurve; + if (noisecfr < 0.f) { + noisecfr = 0.0001f; + } + + if (noiseccr < 0.f) { + noiseccr = 0.0001f; + } + + if (noisecfb < 0.f) { + noisecfb = 0.0001f; + } + + if (noiseccb < 0.f) { + noiseccb = 0.0001f; + } + + int edge = 2; + variC[0] = SQR(noisecfr); + variC[1] = SQR(noisecfr); + variC[2] = SQR(noisecfr); + + variC[3] = SQR(noisecfr); + variC[4] = SQR(noisecfr); + variC[5] = SQR(noiseccr); + variC[6] = SQR(noiseccr); + + variCb[0] = SQR(noisecfb); + variCb[1] = SQR(noisecfb); + variCb[2] = SQR(noisecfb); + + variCb[3] = SQR(noisecfb); + variCb[4] = SQR(noisecfb); + variCb[5] = SQR(noiseccb); + variCb[6] = SQR(noiseccb); + + float k1 = 0.f; + float k2 = 0.f; + float k3 = 0.f; + + if (cp.chromfi < 0.2f) { + k1 = 0.f; + k2 = 0.f; + k3 = 0.f; + } else if (cp.chromfi < 0.3f) { + k1 = 0.1f; + k2 = 0.0f; + k3 = 0.f; + } else if (cp.chromfi < 0.5f) { + k1 = 0.2f; + k2 = 0.1f; + k3 = 0.f; + } else if (cp.chromfi < 0.8f) { + k1 = 0.3f; + k2 = 0.25f; + k3 = 0.f; + } else if (cp.chromfi < 1.f) { + k1 = 0.4f; + k2 = 0.25f; + k3 = 0.1f; + } else if (cp.chromfi < 2.f) { + k1 = 0.5f; + k2 = 0.3f; + k3 = 0.15f; + } else if (cp.chromfi < 3.f) { + k1 = 0.6f; + k2 = 0.45f; + k3 = 0.3f; + } else if (cp.chromfi < 4.f) { + k1 = 0.7f; + k2 = 0.5f; + k3 = 0.4f; + } else if (cp.chromfi < 5.f) { + k1 = 0.8f; + k2 = 0.6f; + k3 = 0.5f; + } else if (cp.chromfi < 6.f) { + k1 = 0.85f; + k2 = 0.7f; + k3 = 0.6f; + } else if (cp.chromfi < 8.f) { + k1 = 0.9f; + k2 = 0.8f; + k3 = 0.7f; + } else if (cp.chromfi < 10.f) { + k1 = 1.f; + k2 = 1.f; + k3 = 0.9f; + + } else { + k1 = 1.f; + k2 = 1.f; + k3 = 1.f; + } + + float minic = 0.0001f; + variC[0] = max(minic, variC[0]); + variC[1] = max(minic, k1 * variC[1]); + variC[2] = max(minic, k2 * variC[2]); + variC[3] = max(minic, k3 * variC[3]); + + variCb[0] = max(minic, variCb[0]); + variCb[1] = max(minic, k1 * variCb[1]); + variCb[2] = max(minic, k2 * variCb[2]); + variCb[3] = max(minic, k3 * variCb[3]); + + float k4 = 0.f; + float k5 = 0.f; + float k6 = 0.f; + + if (cp.chromco == 0.01f) { + k4 = 0.f; + k5 = 0.0f; + } else if (cp.chromco < 0.2f) { + k4 = 0.1f; + k5 = 0.0f; + } else if (cp.chromco < 0.5f) { + k4 = 0.15f; + k5 = 0.0f; + } else if (cp.chromco < 1.f) { + k4 = 0.15f; + k5 = 0.1f; + } else if (cp.chromco < 3.f) { + k4 = 0.3f; + k5 = 0.15f; + } else if (cp.chromco < 4.f) { + k4 = 0.6f; + k5 = 0.4f; + } else if (cp.chromco < 6.f) { + k4 = 0.8f; + k5 = 0.6f; + } else { + k4 = 1.f; + k5 = 1.f; + } + + variC[4] = max(0.0001f, k4 * variC[4]); + variC[5] = max(0.0001f, k5 * variC[5]); + variCb[4] = max(0.0001f, k4 * variCb[4]); + variCb[5] = max(0.0001f, k5 * variCb[5]); + + if (cp.chromco < 4.f) { + k6 = 0.f; + } else if (cp.chromco < 5.f) { + k6 = 0.4f; + } else if (cp.chromco < 6.f) { + k6 = 0.7f; + } else { + k6 = 1.f; + } + + variC[6] = max(0.0001f, k6 * variC[6]); + variCb[6] = max(0.0001f, k6 * variCb[6]); + /* + for (int y = 0; y < 7; y++) { + printf("y=%i madL=%f varia=%f variab=%f\n", y, madL[y][1], variC[y], variCb[y]); + } + */ + float nvch = 0.6f;//high value + float nvcl = 0.1f;//low value + + if (cp.chromco > 30.f) { + nvch = 0.8f; + nvcl = 0.4f; + } + + float seuil = 4000.f;//low + float seuil2 = 15000.f;//high + //ac and bc for transition + float ac = (nvch - nvcl) / (seuil - seuil2); + float bc = nvch - seuil * ac; + int GW = labco->W; + int GH = labco->H; + float* noisevarchrom = new float[GH * GW]; + //noisevarchrom in function chroma + int GW2 = (GW + 1) / 2; + float noisevarab_r = 100.f; + + for (int ir = 0; ir < GH; ir++) + for (int jr = 0; jr < GW; jr++) { + float cN = sqrt(SQR(labco->a[ir][jr]) + SQR(labco->b[ir][jr])); + + if (cN < seuil) { + noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = nvch; + } else if (cN < seuil2) { + noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = ac * cN + bc; + } else { + noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = nvcl; + } + } + + + //Flat curve for H=f(H) in residual image + FlatCurve* hhCurve = new FlatCurve(params->wavelet.hhcurve); //curve H=f(H) + bool hhutili = false; + + if (!hhCurve || hhCurve->isIdentity()) { + if (hhCurve) { + delete hhCurve; + hhCurve = nullptr; + } + } else { + hhutili = true; + } + + bool exblurab = cp.chrwav > 0.f && exblurL; + + if (!hhutili) { //always a or b + int levwava = levwav; + + if (!exblurab && cp.chrores == 0.f && cp.blurcres == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels + while (levwava > 0 && !cp.diag && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwava - 1] == 0.f)) || (cp.CHmet != 2 && (levwava == 10 || (!cp.curv || cp.mulC[levwava - 1] == 0.f))))) && (!cp.opaRG || levwava == 10 || (cp.opaRG && cp.mulopaRG[levwava - 1] == 0.f)) && ((levwava == 10 || (cp.CHSLmet == 1 && cp.mulC[levwava - 1] == 0.f)))) { + levwava--; + } + } + + if (cp.chromfi > 0.f || cp.chromco > 0.f) { + if (levwava < 7) { + levwava = 7; + } + } + + if (settings->verbose) { + printf("Leval decomp a=%i\n", levwava); + } + + if (levwava > 0) { + const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); + + if (!adecomp->memoryAllocationFailed) { + if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + } + + Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); + WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); + adecomp->reconstruct(labco->data + datalen, cp.strength); + } + } + + int levwavb = levwav; + + if (!exblurab && cp.chrores == 0.f && cp.blurcres == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels + while (levwavb > 0 && !cp.diag && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwavb - 1] == 0.f)) || (cp.CHmet != 2 && (levwavb == 10 || (!cp.curv || cp.mulC[levwavb - 1] == 0.f))))) && (!cp.opaBY || levwavb == 10 || (cp.opaBY && cp.mulopaBY[levwavb - 1] == 0.f)) && ((levwavb == 10 || (cp.CHSLmet == 1 && cp.mulC[levwavb - 1] == 0.f)))) { + levwavb--; + } + } + + if (cp.chromfi > 0.f || cp.chromco > 0.f) { + if (levwavb < 7) { + levwavb = 7; + } + } + + if (settings->verbose) { + printf("Leval decomp b=%i\n", levwavb); + } + + + if (levwavb > 0) { + const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); + + if (!bdecomp->memoryAllocationFailed) { + if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + } + + Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); + bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength); + } + } + } else {// a and b + int levwavab = levwav; + + if (!exblurab && cp.chrores == 0.f && cp.blurcres == 0.f && !hhutili && params->wavelet.CLmethod == "all") { // no processing of residual ab => we probably can reduce the number of levels + while (levwavab > 0 && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwavab - 1] == 0.f)) || (cp.CHmet != 2 && (levwavab == 10 || (!cp.curv || cp.mulC[levwavab - 1] == 0.f))))) && (!cp.opaRG || levwavab == 10 || (cp.opaRG && cp.mulopaRG[levwavab - 1] == 0.f)) && ((levwavab == 10 || (cp.CHSLmet == 1 && cp.mulC[levwavab - 1] == 0.f)))) { + levwavab--; + } + } + + if (cp.chromfi > 0.f || cp.chromco > 0.f) { + if (levwavab < 7) { + levwavab = 7; + } + } + + if (levwavab > 0) { + const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); + const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); + + if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { + if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + } + + Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); + WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); + WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); + + if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); + WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); + } + + adecomp->reconstruct(labco->data + datalen, cp.strength); + bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength); + + } + } + } + + delete[] noisevarchrom; + + if (hhCurve) { + delete hhCurve; + } + + if (usechrom) { + Ldecomp->reconstruct(labco->data, cp.strength); + } + } } if (numtiles > 1 || (numtiles == 1 /*&& cp.avoi*/)) { //in all case since I add contrast curve @@ -1047,7 +1365,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } for (int i = 0; i < overlap; i++) { - float mask = SQR (sin ((rtengine::RT_PI * i) / (2 * overlap))); + float mask = SQR(sin((rtengine::RT_PI * i) / (2 * overlap))); if (tiletop > 0) { Vmask[i] = mask; @@ -1074,56 +1392,52 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const #endif for (int i = tiletop; i < tilebottom; i++) { - int i1 = i - tiletop; + const int i1 = i - tiletop; float L, a, b; #ifdef __SSE2__ - int rowWidth = tileright - tileleft; + const int rowWidth = tileright - tileleft; float atan2Buffer[rowWidth] ALIGNED64; float chprovBuffer[rowWidth] ALIGNED64; float xBuffer[rowWidth] ALIGNED64; float yBuffer[rowWidth] ALIGNED64; if (cp.avoi) { - int col; - __m128 av, bv; - __m128 cv, yv, xv; - __m128 zerov = _mm_setzero_ps(); - __m128 onev = _mm_set1_ps (1.f); - __m128 c327d68v = _mm_set1_ps (327.68f); - vmask xyMask; + int col = 0; + const vfloat onev = F2V(1.f); + const vfloat c327d68v = F2V(327.68f); - for (col = 0; col < rowWidth - 3; col += 4) { - av = LVFU (labco->a[i1][col]); - bv = LVFU (labco->b[i1][col]); - STVF (atan2Buffer[col], xatan2f (bv, av)); + for (; col < rowWidth - 3; col += 4) { + const vfloat av = LVFU(labco->a[i1][col]); + const vfloat bv = LVFU(labco->b[i1][col]); + STVF(atan2Buffer[col], xatan2f(bv, av)); - cv = vsqrtf(SQRV(av) + SQRV(bv)); - yv = av / cv; - xv = bv / cv; - xyMask = vmaskf_eq (zerov, cv); - yv = vself (xyMask, onev, yv); - xv = vself (xyMask, zerov, xv); - STVF (yBuffer[col], yv); - STVF (xBuffer[col], xv); - STVF (chprovBuffer[col], cv / c327d68v); + const vfloat cv = vsqrtf(SQRV(av) + SQRV(bv)); + vfloat yv = av / cv; + vfloat xv = bv / cv; + const vmask xyMask = vmaskf_eq(ZEROV, cv); + yv = vself(xyMask, onev, yv); + xv = vselfnotzero(xyMask, xv); + STVF(yBuffer[col], yv); + STVF(xBuffer[col], xv); + STVF(chprovBuffer[col], cv / c327d68v); } for (; col < rowWidth; col++) { - float a = labco->a[i1][col]; - float b = labco->b[i1][col]; - atan2Buffer[col] = xatan2f (b, a); - float Chprov1 = sqrtf (SQR (a) + SQR (b)); - yBuffer[col] = (Chprov1 == 0.f) ? 1.f : a / Chprov1; - xBuffer[col] = (Chprov1 == 0.f) ? 0.f : b / Chprov1; - chprovBuffer[col] = Chprov1 / 327.68; + const float la = labco->a[i1][col]; + const float lb = labco->b[i1][col]; + atan2Buffer[col] = xatan2f(lb, la); + const float Chprov1 = sqrtf(SQR(la) + SQR(lb)); + yBuffer[col] = (Chprov1 == 0.f) ? 1.f : la / Chprov1; + xBuffer[col] = (Chprov1 == 0.f) ? 0.f : lb / Chprov1; + chprovBuffer[col] = Chprov1 / 327.68f; } } #endif for (int j = tileleft; j < tileright; j++) { - int j1 = j - tileleft; + const int j1 = j - tileleft; if (cp.avoi) { //Gamut and Munsell #ifdef __SSE2__ @@ -1135,14 +1449,13 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const #else a = labco->a[i1][j1]; b = labco->b[i1][j1]; - float HH = xatan2f (b, a); - float Chprov1 = sqrtf (SQR (a) + SQR (b)); + float HH = xatan2f(b, a); + float Chprov1 = sqrtf(SQR(a) + SQR(b)); float2 sincosv; sincosv.y = (Chprov1 == 0.0f) ? 1.f : a / (Chprov1); sincosv.x = (Chprov1 == 0.0f) ? 0.f : b / (Chprov1); Chprov1 /= 327.68f; #endif - L = labco->L[i1][j1]; const float Lin = labco->L[i1][j1]; if (wavclCurve && cp.finena) { @@ -1158,9 +1471,9 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const #ifdef _DEBUG bool neg = false; bool more_rgb = false; - Color::gamutLchonly (HH, sincosv, Lprov1, Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f, neg, more_rgb); + Color::gamutLchonly(HH, sincosv, Lprov1, Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f, neg, more_rgb); #else - Color::gamutLchonly (HH, sincosv, Lprov1, Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f); + Color::gamutLchonly(HH, sincosv, Lprov1, Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f); #endif L = Lprov1 * 327.68f; @@ -1169,19 +1482,19 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const float correctionHue = 0.0f; // Munsell's correction float correctlum = 0.0f; Lprov1 = L / 327.68f; - float Chprov = sqrtf (SQR (a) + SQR (b)) / 327.68f; + const float Chprov = sqrtf(SQR(a) + SQR(b)) / 327.68f; #ifdef _DEBUG - Color::AllMunsellLch (true, Lprov1, Lprov2, HH, Chprov, memChprov, correctionHue, correctlum, MunsDebugInfo); + Color::AllMunsellLch(true, Lprov1, Lprov2, HH, Chprov, memChprov, correctionHue, correctlum, MunsDebugInfo); #else - Color::AllMunsellLch (true, Lprov1, Lprov2, HH, Chprov, memChprov, correctionHue, correctlum); + Color::AllMunsellLch(true, Lprov1, Lprov2, HH, Chprov, memChprov, correctionHue, correctlum); #endif if (correctionHue != 0.f || correctlum != 0.f) { // only calculate sin and cos if HH changed - if (fabs (correctionHue) < 0.015f) { + if (std::fabs(correctionHue) < 0.015f) { HH += correctlum; // correct only if correct Munsell chroma very little. } - sincosv = xsincosf (HH + correctionHue); + sincosv = xsincosf(HH + correctionHue); } a = 327.68f * Chprov * sincosv.y; // apply Munsell @@ -1231,44 +1544,76 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } delete [] varhue; - - for (int i = 0; i < tileheight; i++) { - delete [] varchro[i]; - } - - delete [] varchro; - } #ifdef _OPENMP - omp_set_nested (oldNested); + omp_set_nested(oldNested); #endif - if(numtiles != 1) { + if (numtiles != 1) { dst->CopyFrom(dsttmp); delete dsttmp; } + if (waparams.softradend > 0.f && cp.finena) { + array2D ble(lab->W, lab->H); + array2D guid(lab->W, lab->H); + + bool multiTh = false; + +#ifdef _OPENMP + + if (numthreads > 1) { + multiTh = true; + } + + #pragma omp parallel for +#endif + + for (int ir = 0; ir < lab->H; ir++) { + for (int jr = 0; jr < lab->W; jr++) { + guid[ir][jr] = Color::L2Y(lab->L[ir][jr]) / 32768.f; + ble[ir][jr] = Color::L2Y(dst->L[ir][jr]) / 32768.f; + } + } + + constexpr double epsilmax = 0.002; + constexpr double epsilmin = 0.0005; + constexpr double aepsil = 0.01f * (epsilmax - epsilmin); + constexpr double bepsil = epsilmin; + const double epsil = aepsil * waparams.softradend + bepsil; + + const float blur = 10.f / scale * (0.001f + 0.8f * waparams.softradend); + + rtengine::guidedFilter(guid, ble, ble, blur, epsil, multiTh); + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < lab->H; ir++) { + for (int jr = 0; jr < lab->W; jr++) { + dst->L[ir][jr] = Color::computeXYZ2LabY(32768.f * ble[ir][jr]); + } + } + } + #ifdef _DEBUG delete MunsDebugInfo; #endif } -#undef TS -#undef fTS -#undef offset -#undef epsilon -void ImProcFunctions::Aver ( float * RESTRICT DataList, int datalen, float &averagePlus, float &averageNeg, float &max, float &min) +void ImProcFunctions::Aver(float * RESTRICT DataList, int datalen, float &averagePlus, float &averageNeg, float &max, float &min) { //find absolute mean int countP = 0, countN = 0; double averaP = 0.0, averaN = 0.0; // use double precision for large summations - float thres = 5.f;//different fom zero to take into account only data large enough + constexpr float thres = 32.7f;//different fom zero to take into account only data large enough 32.7 = 0.1 in range 0..100 very low value max = 0.f; - min = 0.f; + min = RT_INFINITY_F; #ifdef _OPENMP #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) #endif @@ -1280,20 +1625,12 @@ void ImProcFunctions::Aver ( float * RESTRICT DataList, int datalen, float &ave for (int i = 0; i < datalen; i++) { if (DataList[i] >= thres) { - averaP += DataList[i]; - - if (DataList[i] > lmax) { - lmax = DataList[i]; - } - + averaP += static_cast(DataList[i]); + lmax = rtengine::max(lmax, DataList[i]); countP++; } else if (DataList[i] < -thres) { - averaN += DataList[i]; - - if (DataList[i] < lmin) { - lmin = DataList[i]; - } - + averaN += static_cast(DataList[i]); + lmin = rtengine::min(lmin, DataList[i]); countN++; } } @@ -1302,8 +1639,8 @@ void ImProcFunctions::Aver ( float * RESTRICT DataList, int datalen, float &ave #pragma omp critical #endif { - max = max > lmax ? max : lmax; - min = min < lmin ? min : lmin; + max = rtengine::max(max, lmax); + min = rtengine::min(min, lmin); } } @@ -1322,11 +1659,11 @@ void ImProcFunctions::Aver ( float * RESTRICT DataList, int datalen, float &ave } -void ImProcFunctions::Sigma ( float * RESTRICT DataList, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg) +void ImProcFunctions::Sigma(float * RESTRICT DataList, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg) { int countP = 0, countN = 0; double variP = 0.0, variN = 0.0; // use double precision for large summations - float thres = 5.f;//different fom zero to take into account only data large enough + float thres = 32.7f;//different fom zero to take into account only data large enough 32.7 = 0.1 in range 0..100 #ifdef _OPENMP #pragma omp parallel for reduction(+:variP,variN,countP,countN) num_threads(wavNestedLevels) if(wavNestedLevels>1) @@ -1334,29 +1671,29 @@ void ImProcFunctions::Sigma ( float * RESTRICT DataList, int datalen, float ave for (int i = 0; i < datalen; i++) { if (DataList[i] >= thres) { - variP += SQR (DataList[i] - averagePlus); + variP += static_cast(SQR(DataList[i] - averagePlus)); countP++; } else if (DataList[i] <= -thres) { - variN += SQR (DataList[i] - averageNeg); + variN += static_cast(SQR(DataList[i] - averageNeg)); countN++; } } if (countP > 0) { - sigmaPlus = sqrt (variP / countP); + sigmaPlus = sqrt(variP / countP); } else { sigmaPlus = 0; } if (countN > 0) { - sigmaNeg = sqrt (variN / countN); + sigmaNeg = sqrt(variN / countN); } else { sigmaNeg = 0; } } -void ImProcFunctions::Evaluate2(wavelet_decomposition &WaveletCoeffs_L, +void ImProcFunctions::Evaluate2(const wavelet_decomposition &WaveletCoeffs_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN) { //StopWatch Stop1("Evaluate2"); @@ -1364,17 +1701,70 @@ void ImProcFunctions::Evaluate2(wavelet_decomposition &WaveletCoeffs_L, for (int lvl = 0; lvl < maxlvl; lvl++) { - int Wlvl_L = WaveletCoeffs_L.level_W (lvl); - int Hlvl_L = WaveletCoeffs_L.level_H (lvl); + int Wlvl_L = WaveletCoeffs_L.level_W(lvl); + int Hlvl_L = WaveletCoeffs_L.level_H(lvl); float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); - Eval2 (WavCoeffs_L, lvl, Wlvl_L, Hlvl_L, mean, meanN, sigma, sigmaN, MaxP, MaxN); + Eval2(WavCoeffs_L, lvl, Wlvl_L, Hlvl_L, mean, meanN, sigma, sigmaN, MaxP, MaxN); } } -void ImProcFunctions::Eval2 (float ** WavCoeffs_L, int level, - int W_L, int H_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN) + +void ImProcFunctions::calceffect(int level, float *mean, float *sigma, float *mea, float effect, float offs) +{ + float rap = 0.f; + float sig = 1.f; + + if (effect < 1.f) { + sig = effect; + } + + if (effect <= 1.f) { + rap = offs * mean[level] - sig * sigma[level]; + } + + if (rap > 0.f) { + mea[0] = rap; + } else { + mea[0] = mean[level] / 6.f; + } + + rap = 0.f; + + if (effect <= 1.f) { + rap = offs * mean[level] - 0.5f * sig * sigma[level]; + } + + if (rap > 0.f) { + mea[1] = rap; + } else { + mea[1] = mean[level] / 4.f; + } + + rap = 0.f; + + if (effect <= 1.f) { + rap = offs * mean[level] - 0.2f * sig * sigma[level]; + } + + if (rap > 0.f) { + mea[2] = rap; + } else { + mea[2] = mean[level] / 2.f; + } + + mea[3] = offs * mean[level]; // 50% data + mea[4] = offs * mean[level] + effect * sigma[level] / 2.f; + mea[5] = offs * mean[level] + effect * sigma[level]; //66% + mea[6] = offs * mean[level] + effect * 1.2f * sigma[level]; + mea[7] = offs * mean[level] + effect * 1.5f * sigma[level]; // + mea[8] = offs * mean[level] + effect * 2.f * sigma[level]; //95% + mea[9] = offs * mean[level] + effect * 2.5f * sigma[level]; //99% +} + +void ImProcFunctions::Eval2(float ** WavCoeffs_L, int level, + int W_L, int H_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN) { float avLP[4], avLN[4]; @@ -1383,8 +1773,8 @@ void ImProcFunctions::Eval2 (float ** WavCoeffs_L, int level, float AvL, AvN, SL, SN, maxLP, maxLN; for (int dir = 1; dir < 4; dir++) { - Aver (WavCoeffs_L[dir], W_L * H_L, avLP[dir], avLN[dir], maxL[dir], minL[dir]); - Sigma (WavCoeffs_L[dir], W_L * H_L, avLP[dir], avLN[dir], sigP[dir], sigN[dir]); + Aver(WavCoeffs_L[dir], W_L * H_L, avLP[dir], avLN[dir], maxL[dir], minL[dir]); + Sigma(WavCoeffs_L[dir], W_L * H_L, avLP[dir], avLN[dir], sigP[dir], sigN[dir]); } AvL = 0.f; @@ -1424,24 +1814,23 @@ void ImProcFunctions::CompressDR(float *Source, int W_L, int H_L, float Compress float exponent; - if (DetailBoost > 0.f && DetailBoost < 0.05f ) { - float betemp = expf (- (2.f - DetailBoost + 0.693147f)) - 1.f; //0.693147 = log(2) - exponent = 1.2f * xlogf( -betemp); + if (DetailBoost > 0.f && DetailBoost < 0.05f) { + float betemp = expf(-(2.f - DetailBoost + 0.694f)) - 1.f; //0.694 = log(2) + exponent = 1.2f * xlogf(-betemp); exponent /= 20.f; - } else if (DetailBoost >= 0.05f && DetailBoost < 0.25f ) { - float betemp = expf (- (2.f - DetailBoost + 0.693147f)) - 1.f; - exponent = 1.2f * xlogf( -betemp); + } else if (DetailBoost >= 0.05f && DetailBoost < 0.25f) { + float betemp = expf(-(2.f - DetailBoost + 0.694f)) - 1.f; //0.694 = log(2) + exponent = 1.2f * xlogf(-betemp); exponent /= (-75.f * DetailBoost + 23.75f); } else if (DetailBoost >= 0.25f) { - float betemp = expf (- (2.f - DetailBoost + 0.693147f)) - 1.f; - exponent = 1.2f * xlogf( -betemp); + float betemp = expf(-(2.f - DetailBoost + 0.694f)) - 1.f; //0.694 = log(2) + exponent = 1.2f * xlogf(-betemp); exponent /= (-2.f * DetailBoost + 5.5f); } else { exponent = (Compression - 1.0f) / 20.f; } exponent += 1.f; - const float eps = 0.0001f; // now calculate Source = pow(Source, exponent) #ifdef __SSE2__ @@ -1449,20 +1838,18 @@ void ImProcFunctions::CompressDR(float *Source, int W_L, int H_L, float Compress #pragma omp parallel #endif { - vfloat exponentv = F2V(exponent); - __m128 epsv = _mm_set1_ps( eps ); - + const vfloat exponentv = F2V(exponent); #ifdef _OPENMP #pragma omp for #endif for (int i = 0; i < n - 3; i += 4) { - STVFU(Source[i], xexpf(xlogf(LVFU(Source[i]) + epsv) * exponentv)); + STVFU(Source[i], xexpf(xlogf(LVFU(Source[i])) * exponentv)); } } for (int i = n - (n % 4); i < n; i++) { - Source[i] = xexpf(xlogf(Source[i] + eps) * exponent); + Source[i] = xexpf(xlogf(Source[i]) * exponent); } #else @@ -1500,7 +1887,7 @@ void ImProcFunctions::ContrastResid(float * WavCoeffs_L0, struct cont_params &cp WavCoeffs_L0[i] *= gamm; } - float Compression = expf (-stren); //This modification turns numbers symmetric around 0 into exponents. + float Compression = expf(-stren); //This modification turns numbers symmetric around 0 into exponents. float DetailBoost = stren; if (stren < 0.0f) { @@ -1523,16 +1910,16 @@ void ImProcFunctions::ContrastResid(float * WavCoeffs_L0, struct cont_params &cp -void ImProcFunctions::EPDToneMapResid (float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0) +void ImProcFunctions::EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0) { float stren = cp.tmstrength; - float edgest = params->epd.edgeStopping; - float sca = params->epd.scale; + float edgest = params->wavelet.edgs; + float sca = params->wavelet.scale; float gamm = params->wavelet.gamma; - float rew = params->epd.reweightingIterates; - EdgePreservingDecomposition epd2 (W_L, H_L); + int rew = 0; //params->epd.reweightingIterates; + EdgePreservingDecomposition epd2(W_L, H_L); cp.TMmeth = 2; //default after testing if (cp.TMmeth == 1) { @@ -1552,7 +1939,7 @@ void ImProcFunctions::EPDToneMapResid (float * WavCoeffs_L0, unsigned int Itera WavCoeffs_L0[i] *= gamm; } - float Compression = expf (-stren); //This modification turns numbers symmetric around 0 into exponents. + float Compression = expf(-stren); //This modification turns numbers symmetric around 0 into exponents. float DetailBoost = stren; if (stren < 0.0f) { @@ -1561,7 +1948,7 @@ void ImProcFunctions::EPDToneMapResid (float * WavCoeffs_L0, unsigned int Itera //Auto select number of iterates. Note that p->EdgeStopping = 0 makes a Gaussian blur. if (Iterates == 0) { - Iterates = (unsigned int) (edgest * 15.0f); + Iterates = (unsigned int)(edgest * 15.0f); } @@ -1577,35 +1964,31 @@ void ImProcFunctions::EPDToneMapResid (float * WavCoeffs_L0, unsigned int Itera } } -void ImProcFunctions::WaveletcontAllLfinal (wavelet_decomposition &WaveletCoeffs_L, struct cont_params &cp, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL) +void ImProcFunctions::WaveletcontAllLfinal(const wavelet_decomposition &WaveletCoeffs_L, const cont_params &cp, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL) { int maxlvl = WaveletCoeffs_L.maxlevel(); float * WavCoeffs_L0 = WaveletCoeffs_L.coeff0; for (int dir = 1; dir < 4; dir++) { for (int lvl = 0; lvl < maxlvl; lvl++) { - int Wlvl_L = WaveletCoeffs_L.level_W (lvl); - int Hlvl_L = WaveletCoeffs_L.level_H (lvl); - float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs (lvl); - finalContAllL (WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, mean, sigma, MaxP, waOpacityCurveWL); + int Wlvl_L = WaveletCoeffs_L.level_W(lvl); + int Hlvl_L = WaveletCoeffs_L.level_H(lvl); + float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); + finalContAllL(WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, mean, sigma, MaxP, waOpacityCurveWL); } } } -void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_L, +void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_L, const Wavblcurve & wavblcurve, struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili) { - int maxlvl = WaveletCoeffs_L.maxlevel(); - int W_L = WaveletCoeffs_L.level_W (0); - int H_L = WaveletCoeffs_L.level_H (0); + const int maxlvl = WaveletCoeffs_L.maxlevel(); + const int W_L = WaveletCoeffs_L.level_W(0); + const int H_L = WaveletCoeffs_L.level_H(0); float * WavCoeffs_L0 = WaveletCoeffs_L.coeff0; - float maxh = 2.5f; //amplification contrast above mean - float maxl = 2.5f; //reduction contrast under mean float contrast = cp.contrast; - float multL = (float)contrast * (maxl - 1.f) / 100.f + 1.f; - float multH = (float) contrast * (maxh - 1.f) / 100.f + 1.f; double avedbl = 0.0; // use double precision for large summations float max0 = 0.f; float min0 = FLT_MAX; @@ -1616,7 +1999,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * #endif for (int i = 0; i < W_L * H_L; i++) { - avedbl += WavCoeffs_L0[i]; + avedbl += static_cast(WavCoeffs_L0[i]); } #ifdef _OPENMP @@ -1658,7 +2041,6 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } - // printf("MAXmax0=%f MINmin0=%f\n",max0,min0); //tone mapping if (cp.tonemap && cp.contmet == 2 && cp.resena) { @@ -1672,15 +2054,8 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * max0 /= 327.68f; min0 /= 327.68f; - float ave = avedbl / (double) (W_L * H_L); - float av = ave / 327.68f; - float ah = (multH - 1.f) / (av - max0); // - float bh = 1.f - max0 * ah; - float al = (multL - 1.f) / (av - min0); - float bl = 1.f - min0 * al; - float factorx = 1.f; -// float *koeLi[9]; -// float maxkoeLi[9]; + float ave = avedbl / (double)(W_L * H_L); + float avg = ave / 32768.f; float *koeLi[12]; float maxkoeLi[12]; @@ -1701,38 +2076,38 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * koeLi[j][i] = 0.f; } + avg = LIM01(avg); + double contreal = 0.6 * contrast; + DiagonalCurve resid_contrast({ + DCT_NURBS, + 0, 0, + avg - avg * (0.6 - contreal / 250.0), avg - avg * (0.6 + contreal / 250.0), + avg + (1. - avg) * (0.6 - contreal / 250.0), avg + (1. - avg) * (0.6 + contreal / 250.0), + 1, 1 + }); + + #ifdef _OPENMP #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) #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 #pragma omp for #endif - for (int i = 0; i < W_L * H_L; i++) { //contrast - if (WavCoeffs_L0[i] < 32768.f) { - float prov; - - if ( WavCoeffs_L0[i] > ave) { - float kh = ah * (WavCoeffs_L0[i] / 327.68f) + bh; - prov = WavCoeffs_L0[i]; - WavCoeffs_L0[i] = ave + kh * (WavCoeffs_L0[i] - ave); - } else { - float kl = al * (WavCoeffs_L0[i] / 327.68f) + bl; - prov = WavCoeffs_L0[i]; - WavCoeffs_L0[i] = ave - kl * (ave - WavCoeffs_L0[i]); - } - - float diflc = WavCoeffs_L0[i] - prov; - diflc *= factorx; - WavCoeffs_L0[i] = prov + diflc; - } + for (int i = 0; i < W_L * H_L; i++) { + float buf = LIM01(WavCoeffs_L0[i] / 32768.f); + buf = resid_contrast.getVal(buf); + buf *= 32768.f; + WavCoeffs_L0[i] = buf; } } } + if (cp.tonemap && cp.contmet == 1 && cp.resena) { float maxp = max0 * 256.f; float minp = min0 * 256.f; @@ -1741,62 +2116,122 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * #endif ContrastResid(WavCoeffs_L0, cp, W_L, H_L, maxp, minp); } + } + if ((cp.conres >= 0.f || cp.conresH >= 0.f) && cp.resena && !cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step + LabImage *temp = nullptr; + temp = new LabImage(W_L, H_L); #ifdef _OPENMP - #pragma omp barrier + #pragma omp for #endif - if ((cp.conres != 0.f || cp.conresH != 0.f) && cp.resena) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step -#ifdef _OPENMP - #pragma omp for nowait -#endif - - for (int i = 0; i < W_L * H_L; i++) { - float LL = WavCoeffs_L0[i]; - float LL100 = LL / 327.68f; - float tran = 5.f;//transition - //shadow - float alp = 3.f; //increase contrast sahdow in lowlights between 1 and ?? - - if (cp.th > (100.f - tran)) { - tran = 100.f - cp.th; - } - - if (LL100 < cp.th) { - float aalp = (1.f - alp) / cp.th; //no changes for LL100 = cp.th - float kk = aalp * LL100 + alp; - WavCoeffs_L0[i] *= (1.f + kk * cp.conres / 200.f); - } else if (LL100 < cp.th + tran) { - float ath = -cp.conres / tran; - float bth = cp.conres - ath * cp.th; - WavCoeffs_L0[i] *= (1.f + (LL100 * ath + bth) / 200.f); - } - - //highlight - tran = 5.f; - - if (cp.thH < (tran)) { - tran = cp.thH; - } - - if (LL100 > cp.thH) { - WavCoeffs_L0[i] *= (1.f + cp.conresH / 200.f); - } else if (LL100 > (cp.thH - tran)) { - float athH = cp.conresH / tran; - float bthH = cp.conresH - athH * cp.thH; - WavCoeffs_L0[i] *= (1.f + (LL100 * athH + bthH) / 200.f); - } + for (int i = 0; i < H_L; i++) { + for (int j = 0; j < W_L; j++) { + temp->L[i][j] = WavCoeffs_L0[i * W_L + j]; } } + { + ImProcFunctions::shadowsHighlights(temp, true, 1, cp.conresH, cp.conres, cp.radius, skip, cp.thH, cp.th); + } + +#ifdef _OPENMP + #pragma omp for +#endif + + for (int i = 0; i < H_L; i++) { + for (int j = 0; j < W_L; j++) { + WavCoeffs_L0[i * W_L + j] = temp->L[i][j]; + } + } + + delete temp; + + } + +#ifdef _OPENMP + #pragma omp barrier +#endif + + if ((cp.conres != 0.f || cp.conresH != 0.f) && cp.resena && cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step +#ifdef _OPENMP + #pragma omp for nowait +#endif + + for (int i = 0; i < W_L * H_L; i++) { + float LL = WavCoeffs_L0[i]; + float LL100 = LL / 327.68f; + float tran = 5.f;//transition + //shadow + float alp = 3.f; //increase contrast sahdow in lowlights between 1 and ?? + + if (cp.th > (100.f - tran)) { + tran = 100.f - cp.th; + } + + if (LL100 < cp.th) { + float aalp = (1.f - alp) / cp.th; //no changes for LL100 = cp.th + float kk = aalp * LL100 + alp; + WavCoeffs_L0[i] *= (1.f + kk * cp.conres / 200.f); + } else if (LL100 < cp.th + tran) { + float ath = -cp.conres / tran; + float bth = cp.conres - ath * cp.th; + WavCoeffs_L0[i] *= (1.f + (LL100 * ath + bth) / 200.f); + } + + //highlight + tran = 5.f; + + if (cp.thH < (tran)) { + tran = cp.thH; + } + + if (LL100 > cp.thH) { + WavCoeffs_L0[i] *= (1.f + cp.conresH / 200.f); + } else if (LL100 > (cp.thH - tran)) { + float athH = cp.conresH / tran; + float bthH = cp.conresH - athH * cp.thH; + WavCoeffs_L0[i] *= (1.f + (LL100 * athH + bthH) / 200.f); + } + } + } + +//Blur luma + if (cp.blurres != 0.f && cp.resena) { + float rad = 0.7f * cp.blurres / skip; + float * bef = new float[W_L * H_L]; + float * aft = new float[W_L * H_L]; + + for (int i = 0; i < H_L * W_L; i++) { + bef[i] = WavCoeffs_L0[i]; + } + + boxblur(bef, aft, rad, W_L, H_L, false); + + for (int i = 0; i < H_L * W_L; i++) { + WavCoeffs_L0[i] = aft[i]; + } + + delete[] bef; + delete[] aft; + } + +// + int n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n32; + n0 = n1 = n2 = n3 = n4 = n5 = n6 = n7 = n8 = n9 = n10 = n32 = 0; + +#ifdef _OPENMP + #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) +#endif + { //enabled Lipschitz..replace simple by complex edge detection // I found this concept on the web (doctoral thesis on medical Imaging) // I was inspired by the principle of Canny and Lipschitz (continuity and derivability) // I adapted the principle but have profoundly changed the algorithm // One can 1) change all parameters and found good parameters; //one can also change in calckoe - float edd = 3.f; - float eddlow = 15.f; + constexpr float edd = 3.f; + constexpr float eddlow = 15.f; float eddlipinfl = 0.005f * cp.edgsens + 0.4f; float eddlipampl = 1.f + cp.edgampl / 50.f; @@ -1817,12 +2252,9 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * for (int lvl = 0; lvl < 4; lvl++) { for (int dir = 1; dir < 4; dir++) { - int W_L = WaveletCoeffs_L.level_W (lvl); - int H_L = WaveletCoeffs_L.level_H (lvl); - - float ** WavCoeffs_LL = WaveletCoeffs_L.level_coeffs (lvl); + float ** WavCoeffs_LL = WaveletCoeffs_L.level_coeffs(lvl); + // calckoe(WavCoeffs_LL, cp, koeLi, lvl, dir, WaveletCoeffs_L.level_W(lvl), WaveletCoeffs_L.level_H(lvl), edd, maxkoeLi, tmC); calckoe (WavCoeffs_LL, gradw, tloww, koeLi, lvl , dir, W_L, H_L, edd, maxkoeLi, tmC); -// calckoe (WavCoeffs_LL, cp, koeLi, lvl , dir, W_L, H_L, edd, maxkoeLi, tmC); // return convolution KoeLi and maxkoeLi of level 0 1 2 3 and Dir Horiz, Vert, Diag } } @@ -1848,18 +2280,18 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * const auto somm = neigh ? 40.f : 50.f; for (int dir = 1; dir < 4; dir++) { //neighbours proxi - koeLi[lvl * 3 + dir - 1][i * W_L + j] = (kneigh * koeLi[lvl * 3 + dir - 1][i * W_L + j] + 2.f * koeLi[lvl * 3 + dir - 1][ (i - 1) * W_L + j] + 2.f * koeLi[lvl * 3 + dir - 1][ (i + 1) * W_L + j] - + 2.f * koeLi[lvl * 3 + dir - 1][i * W_L + j + 1] + 2.f * koeLi[lvl * 3 + dir - 1][i * W_L + j - 1] + koeLi[lvl * 3 + dir - 1][ (i - 1) * W_L + j - 1] - + koeLi[lvl * 3 + dir - 1][ (i - 1) * W_L + j + 1] + koeLi[lvl * 3 + dir - 1][ (i + 1) * W_L + j - 1] + koeLi[lvl * 3 + dir - 1][ (i + 1) * W_L + j + 1]) / somm; + koeLi[lvl * 3 + dir - 1][i * W_L + j] = (kneigh * koeLi[lvl * 3 + dir - 1][i * W_L + j] + 2.f * koeLi[lvl * 3 + dir - 1][(i - 1) * W_L + j] + 2.f * koeLi[lvl * 3 + dir - 1][(i + 1) * W_L + j] + + 2.f * koeLi[lvl * 3 + dir - 1][i * W_L + j + 1] + 2.f * koeLi[lvl * 3 + dir - 1][i * W_L + j - 1] + koeLi[lvl * 3 + dir - 1][(i - 1) * W_L + j - 1] + + koeLi[lvl * 3 + dir - 1][(i - 1) * W_L + j + 1] + koeLi[lvl * 3 + dir - 1][(i + 1) * W_L + j - 1] + koeLi[lvl * 3 + dir - 1][(i + 1) * W_L + j + 1]) / somm; } } for (int dir = 1; dir < 4; dir++) { //here I evaluate combinaison of vert / diag / horiz...we are with multiplicators of the signal - interm += SQR (koeLi[lvl * 3 + dir - 1][i * W_L + j]); + interm += SQR(koeLi[lvl * 3 + dir - 1][i * W_L + j]); } - interm = sqrt (interm); + interm = sqrt(interm); // interm /= 1.732f;//interm = pseudo variance koeLi interm *= 0.57736721f; @@ -1903,9 +2335,9 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * if (alph > eddlipinfl) { AmpLip = alipinfl * alph + blipinfl; //If beta low reduce kampli - kampli = SQR (bet) * AmpLip * aamp; + kampli = SQR(bet) * AmpLip * aamp; } else { - AmpLip = (1.f / eddlipinfl) * SQR (SQR (alph * bet)); //Strong Reduce if beta low + AmpLip = (1.f / eddlipinfl) * SQR(SQR(alph * bet)); //Strong Reduce if beta low kampli = AmpLip / aamp; } @@ -1935,21 +2367,107 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * // end } + bool wavcurvecomp = false;//not enable if 0.75 + + if (wavblcurve) { + for (int i = 0; i < 500; i++) { + if (wavblcurve[i] != 0.) { + wavcurvecomp = true; + } + } + } + #ifdef _OPENMP - #pragma omp for schedule(dynamic) collapse(2) + // #pragma omp for schedule(dynamic) collapse(2) + #pragma omp for reduction(+:n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n32) schedule(dynamic) collapse(2) #endif for (int dir = 1; dir < 4; dir++) { for (int lvl = 0; lvl < maxlvl; lvl++) { - int Wlvl_L = WaveletCoeffs_L.level_W (lvl); - int Hlvl_L = WaveletCoeffs_L.level_H (lvl); + int Wlvl_L = WaveletCoeffs_L.level_W(lvl); + int Hlvl_L = WaveletCoeffs_L.level_H(lvl); - float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs (lvl); + float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); - ContAllL (koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); + ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); + //blur level + float klev = 1.f; + + if (wavblcurve && wavcurvecomp && cp.blena) { + // printf("Blur level L\n"); + float mea[10]; + float effect = cp.bluwav; + float beta = 0.f; + float offs = 1.f; + + calceffect(lvl, mean, sigma, mea, effect, offs); + + float * bef = new float[Wlvl_L * Hlvl_L]; + float * aft = new float[Wlvl_L * Hlvl_L]; + + for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { + bef[co] = WavCoeffs_L[dir][co]; + float WavCL = std::fabs(WavCoeffs_L[dir][co]); + + if (WavCL < mea[0]) { + beta = 0.05f; + n0++; + + if (WavCL < 32.7) { + n32++; + } + } else if (WavCL < mea[1]) { + beta = 0.2f; + n1++; + } else if (WavCL < mea[2]) { + beta = 0.7f; + n2++; + } else if (WavCL < mea[3]) { + beta = 1.f; //standard + n3++; + } else if (WavCL < mea[4]) { + beta = 1.f; + n4++; + } else if (WavCL < mea[5]) { + beta = 0.8f; //+sigma + n5++; + } else if (WavCL < mea[6]) { + beta = 0.6f; + n6++; + } else if (WavCL < mea[7]) { + beta = 0.4f; + n7++; + } else if (WavCL < mea[8]) { + beta = 0.2f; // + 2 sigma + n8++; + } else if (WavCL < mea[9]) { + beta = 0.1f; + n9++; + } else { + beta = 0.01f; + n10++; + } + } + + if (settings->verbose) { + printf("lvl=%i n0=%i n32=%i n1=%i n2=%i n3=%i n4=%i n5=%i n6=%i n7=%i n8=%i n9=%i n10=%i\n", lvl, n0, n0 - n32, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10); + } + + klev = (wavblcurve[lvl * 55.5f]); + + klev *= beta * 100.f / skip; + boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false); + + for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { + WavCoeffs_L[dir][co] = aft[co]; + } + + delete[] bef; + delete[] aft; + } } } } @@ -1960,13 +2478,13 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } } -void ImProcFunctions::WaveletAandBAllAB(wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, - struct cont_params &cp, FlatCurve* hhCurve, bool hhutili) +void ImProcFunctions::WaveletAandBAllAB(const wavelet_decomposition &WaveletCoeffs_a, const wavelet_decomposition &WaveletCoeffs_b, + const cont_params &cp, FlatCurve* hhCurve, bool hhutili) { // StopWatch Stop1("WaveletAandBAllAB"); if (hhutili && cp.resena) { // H=f(H) - int W_L = WaveletCoeffs_a.level_W (0); - int H_L = WaveletCoeffs_a.level_H (0); + int W_L = WaveletCoeffs_a.level_W(0); + int H_L = WaveletCoeffs_a.level_H(0); float * WavCoeffs_a0 = WaveletCoeffs_a.coeff0; float * WavCoeffs_b0 = WaveletCoeffs_b.coeff0; @@ -1988,17 +2506,15 @@ void ImProcFunctions::WaveletAandBAllAB(wavelet_decomposition &WaveletCoeffs_a, int k; for (k = 0; k < W_L - 3; k += 4) { - __m128 av = LVFU (WavCoeffs_a0[i * W_L + k]); - __m128 bv = LVFU (WavCoeffs_b0[i * W_L + k]); - __m128 huev = xatan2f (bv, av); - __m128 chrv = vsqrtf(SQRV(av) + SQRV(bv)); - STVF (huebuffer[k], huev); - STVF (chrbuffer[k], chrv); + const vfloat av = LVFU(WavCoeffs_a0[i * W_L + k]); + const vfloat bv = LVFU(WavCoeffs_b0[i * W_L + k]); + STVF(huebuffer[k], xatan2f(bv, av)); + STVF(chrbuffer[k], vsqrtf(SQRV(av) + SQRV(bv))); } for (; k < W_L; k++) { - huebuffer[k] = xatan2f (WavCoeffs_b0[i * W_L + k], WavCoeffs_a0[i * W_L + k]); - chrbuffer[k] = sqrtf (SQR (WavCoeffs_b0[i * W_L + k]) + SQR (WavCoeffs_a0[i * W_L + k])) / 327.68f; + huebuffer[k] = xatan2f(WavCoeffs_b0[i * W_L + k], WavCoeffs_a0[i * W_L + k]); + chrbuffer[k] = sqrtf(SQR(WavCoeffs_b0[i * W_L + k]) + SQR(WavCoeffs_a0[i * W_L + k])) / 327.68f; } #endif // __SSE2__ @@ -2009,16 +2525,16 @@ void ImProcFunctions::WaveletAandBAllAB(wavelet_decomposition &WaveletCoeffs_a, float hueR = huebuffer[j]; float chR = chrbuffer[j]; #else - float hueR = xatan2f (WavCoeffs_b0[i * W_L + j], WavCoeffs_a0[i * W_L + j]); - float chR = sqrtf (SQR (WavCoeffs_b0[i * W_L + j]) + SQR (WavCoeffs_a0[i * W_L + j])); + float hueR = xatan2f(WavCoeffs_b0[i * W_L + j], WavCoeffs_a0[i * W_L + j]); + float chR = sqrtf(SQR(WavCoeffs_b0[i * W_L + j]) + SQR(WavCoeffs_a0[i * W_L + j])); #endif /* if (editID == EUID_WW_HHCurve) {//H pipette float valpar =Color::huelab_to_huehsv2(hueR); 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 ! - float2 sincosval = xsincosf (valparam); + float valparam = (static_cast(hhCurve->getVal(Color::huelab_to_huehsv2(hueR))) - 0.5f) * 1.7f + hueR; //get H=f(H) 1.7 optimisation ! + float2 sincosval = xsincosf(valparam); WavCoeffs_a0[i * W_L + j] = chR * sincosval.y; WavCoeffs_b0[i * W_L + j] = chR * sincosval.x; } @@ -2028,13 +2544,13 @@ void ImProcFunctions::WaveletAandBAllAB(wavelet_decomposition &WaveletCoeffs_a, } -void ImProcFunctions::WaveletcontAllAB (LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_ab, const WavOpacityCurveW & waOpacityCurveW, - struct cont_params &cp, const bool useChannelA) +void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_ab, const Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW, + struct cont_params &cp, const bool useChannelA, int skip, float *meanab, float *sigmaab) { int maxlvl = WaveletCoeffs_ab.maxlevel(); - int W_L = WaveletCoeffs_ab.level_W (0); - int H_L = WaveletCoeffs_ab.level_H (0); + int W_L = WaveletCoeffs_ab.level_W(0); + int H_L = WaveletCoeffs_ab.level_H(0); float * WavCoeffs_ab0 = WaveletCoeffs_ab.coeff0; @@ -2152,6 +2668,37 @@ void ImProcFunctions::WaveletcontAllAB (LabImage * labco, float ** varhue, float } } +//Blur chroma + if (cp.blurcres != 0.f && cp.resena) { + float rad = 0.7f * cp.blurcres / skip; + float * bef = new float[W_L * H_L]; + float * aft = new float[W_L * H_L]; + + for (int i = 0; i < H_L * W_L; i++) { + bef[i] = WavCoeffs_ab0[i]; + } + + boxblur(bef, aft, rad, W_L, H_L, false); + + for (int i = 0; i < H_L * W_L; i++) { + WavCoeffs_ab0[i] = aft[i]; + } + + delete[] bef; + delete[] aft; + } + + + bool wavcurvecomp = false;//not enable if 0.75 + + if (wavblcurve) { + for (int i = 0; i < 500; i++) { + if (wavblcurve[i] != 0.) { + wavcurvecomp = true; + } + } + } + #ifdef _OPENMP #pragma omp for schedule(dynamic) collapse(2) #endif @@ -2159,11 +2706,71 @@ void ImProcFunctions::WaveletcontAllAB (LabImage * labco, float ** varhue, float for (int dir = 1; dir < 4; dir++) { for (int lvl = 0; lvl < maxlvl; lvl++) { - int Wlvl_ab = WaveletCoeffs_ab.level_W (lvl); - int Hlvl_ab = WaveletCoeffs_ab.level_H (lvl); + int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); + int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); + + float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); + ContAllAB(labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA); + + if (wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f) { + + float mea[10]; + float effect = cp.bluwav; + float beta = 0.f; + float offs = 1.f; + + calceffect(lvl, meanab, sigmaab, mea, effect, offs); + + float * bef = new float[Wlvl_ab * Hlvl_ab]; + float * aft = new float[Wlvl_ab * Hlvl_ab]; + float klev; + + for (int co = 0; co < Hlvl_ab * Wlvl_ab; co++) { + bef[co] = WavCoeffs_ab[dir][co]; + float WavCab = std::fabs(WavCoeffs_ab[dir][co]); + + if (WavCab < mea[0]) { + beta = 0.05f; + } else if (WavCab < mea[1]) { + beta = 0.2f; + } else if (WavCab < mea[2]) { + beta = 0.7f; + } else if (WavCab < mea[3]) { + beta = 1.f; //standard + } else if (WavCab < mea[4]) { + beta = 1.f; + } else if (WavCab < mea[5]) { + beta = 0.8f; //+sigma + } else if (WavCab < mea[6]) { + beta = 0.6f; + } else if (WavCab < mea[7]) { + beta = 0.4f; + } else if (WavCab < mea[8]) { + beta = 0.2f; // + 2 sigma + } else if (WavCab < mea[9]) { + beta = 0.1f; + } else { + beta = 0.0f; + } + + + } + + klev = (wavblcurve[lvl * 55.5f]); + + klev *= beta * cp.chrwav * 100.f / skip; + + boxblur(bef, aft, klev, Wlvl_ab, Hlvl_ab, false); + + for (int co = 0; co < Hlvl_ab * Wlvl_ab; co++) { + WavCoeffs_ab[dir][co] = aft[co]; + } + + delete[] bef; + delete[] aft; + } + - float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs (lvl); - ContAllAB (labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA); } } @@ -2174,6 +2781,7 @@ void ImProcFunctions::WaveletcontAllAB (LabImage * labco, float ** varhue, float //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//void ImProcFunctions::calckoe(float ** WavCoeffs_LL, const cont_params& cp, float *koeLi[12], int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC) void ImProcFunctions::calckoe (float ** WavCoeffs_LL, float gradw, float tloww, float *koeLi[12], int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC) { int borderL = 2; @@ -2194,9 +2802,9 @@ void ImProcFunctions::calckoe (float ** WavCoeffs_LL, float gradw, float tloww, */ for (int i = 1; i < H_L - 1; i++) { //sigma=0.55 for (int j = 1; j < W_L - 1; j++) { - tmC[i][j] = (8.94f * WavCoeffs_LL[dir][i * W_L + j] + 1.71f * (WavCoeffs_LL[dir][ (i - 1) * W_L + j] + 1.71f * WavCoeffs_LL[dir][ (i + 1) * W_L + j] - + 1.71f * WavCoeffs_LL[dir][i * W_L + j + 1] + 1.71f * WavCoeffs_LL[dir][i * W_L + j - 1]) + 0.33f * WavCoeffs_LL[dir][ (i - 1) * W_L + j - 1] - + 0.33f * WavCoeffs_LL[dir][ (i - 1) * W_L + j + 1] + 0.33f * WavCoeffs_LL[dir][ (i + 1) * W_L + j - 1] + 0.33f * WavCoeffs_LL[dir][ (i + 1) * W_L + j + 1]) * 0.0584795f; + tmC[i][j] = (8.94f * WavCoeffs_LL[dir][i * W_L + j] + 1.71f * (WavCoeffs_LL[dir][(i - 1) * W_L + j] + 1.71f * WavCoeffs_LL[dir][(i + 1) * W_L + j] + + 1.71f * WavCoeffs_LL[dir][i * W_L + j + 1] + 1.71f * WavCoeffs_LL[dir][i * W_L + j - 1]) + 0.33f * WavCoeffs_LL[dir][(i - 1) * W_L + j - 1] + + 0.33f * WavCoeffs_LL[dir][(i - 1) * W_L + j + 1] + 0.33f * WavCoeffs_LL[dir][(i + 1) * W_L + j - 1] + 0.33f * WavCoeffs_LL[dir][(i + 1) * W_L + j + 1]) * 0.0584795f; // apply to each direction Wavelet level : horizontal / vertiacle / diagonal @@ -2207,9 +2815,9 @@ void ImProcFunctions::calckoe (float ** WavCoeffs_LL, float gradw, float tloww, for (int i = 1; i < H_L - 1; i++) { //sigma=0.85 for (int j = 1; j < W_L - 1; j++) { - tmC[i][j] = (4.0091f * WavCoeffs_LL[dir][i * W_L + j] + 2.0068f * (WavCoeffs_LL[dir][ (i - 1) * W_L + j] + 2.0068f * WavCoeffs_LL[dir][ (i + 1) * W_L + j] - + 2.0068f * WavCoeffs_LL[dir][i * W_L + j + 1] + 2.0068f * WavCoeffs_LL[dir][i * W_L + j - 1]) + 1.0045f * WavCoeffs_LL[dir][ (i - 1) * W_L + j - 1] - + 1.0045f * WavCoeffs_LL[dir][ (i - 1) * W_L + j + 1] + 1.0045f * WavCoeffs_LL[dir][ (i + 1) * W_L + j - 1] + 1.0045f * WavCoeffs_LL[dir][ (i + 1) * W_L + j + 1]) * 0.062288f; + tmC[i][j] = (4.0091f * WavCoeffs_LL[dir][i * W_L + j] + 2.0068f * (WavCoeffs_LL[dir][(i - 1) * W_L + j] + 2.0068f * WavCoeffs_LL[dir][(i + 1) * W_L + j] + + 2.0068f * WavCoeffs_LL[dir][i * W_L + j + 1] + 2.0068f * WavCoeffs_LL[dir][i * W_L + j - 1]) + 1.0045f * WavCoeffs_LL[dir][(i - 1) * W_L + j - 1] + + 1.0045f * WavCoeffs_LL[dir][(i - 1) * W_L + j + 1] + 1.0045f * WavCoeffs_LL[dir][(i + 1) * W_L + j - 1] + 1.0045f * WavCoeffs_LL[dir][(i + 1) * W_L + j + 1]) * 0.062288f; // apply to each direction Wavelet level : horizontal / vertiacle / diagonal @@ -2223,16 +2831,17 @@ void ImProcFunctions::calckoe (float ** WavCoeffs_LL, float gradw, float tloww, for (int i = 1; i < H_L - 1; i++) { for (int j = 1; j < W_L - 1; j++) { //sigma=1.1 - tmC[i][j] = (3.025f * WavCoeffs_LL[dir][i * W_L + j] + 2.001f * (WavCoeffs_LL[dir][ (i - 1) * W_L + j] + 2.001f * WavCoeffs_LL[dir][ (i + 1) * W_L + j] - + 2.001f * WavCoeffs_LL[dir][i * W_L + j + 1] + 2.001f * WavCoeffs_LL[dir][i * W_L + j - 1]) + 1.323f * WavCoeffs_LL[dir][ (i - 1) * W_L + j - 1] - + 1.323f * WavCoeffs_LL[dir][ (i - 1) * W_L + j + 1] + 1.323f * WavCoeffs_LL[dir][ (i + 1) * W_L + j - 1] + 1.323f * WavCoeffs_LL[dir][ (i + 1) * W_L + j + 1]) * 0.06127f; + tmC[i][j] = (3.025f * WavCoeffs_LL[dir][i * W_L + j] + 2.001f * (WavCoeffs_LL[dir][(i - 1) * W_L + j] + 2.001f * WavCoeffs_LL[dir][(i + 1) * W_L + j] + + 2.001f * WavCoeffs_LL[dir][i * W_L + j + 1] + 2.001f * WavCoeffs_LL[dir][i * W_L + j - 1]) + 1.323f * WavCoeffs_LL[dir][(i - 1) * W_L + j - 1] + + 1.323f * WavCoeffs_LL[dir][(i - 1) * W_L + j + 1] + 1.323f * WavCoeffs_LL[dir][(i + 1) * W_L + j - 1] + 1.323f * WavCoeffs_LL[dir][(i + 1) * W_L + j + 1]) * 0.06127f; } } } - else { + else if (tloww >= 75.f) { borderL = 2; + //if(cp.lip3 && level > 1) { if (level > 1) { // do not activate 5x5 if level 0 or 1 for (int i = 2; i < H_L - 2; i++) { @@ -2252,25 +2861,25 @@ void ImProcFunctions::calckoe (float ** WavCoeffs_LL, float gradw, float tloww, // 2 4 5 4 2 // divi 159 if (tloww < 85.f) { //sigma=1.1 - tmC[i][j] = (15.f * WavCoeffs_LL[dir][i * W_L + j] + 10.f * WavCoeffs_LL[dir][ (i - 1) * W_L + j] + 10.f * WavCoeffs_LL[dir][ (i + 1) * W_L + j] - + 10.f * WavCoeffs_LL[dir][i * W_L + j + 1] + 10.f * WavCoeffs_LL[dir][i * W_L + j - 1] + 7.f * WavCoeffs_LL[dir][ (i - 1) * W_L + j - 1] - + 7.f * WavCoeffs_LL[dir][ (i - 1) * W_L + j + 1] + 7.f * WavCoeffs_LL[dir][ (i + 1) * W_L + j - 1] + 7.f * WavCoeffs_LL[dir][ (i + 1) * W_L + j + 1] - + 3.f * WavCoeffs_LL[dir][ (i - 2) * W_L + j] + 3.f * WavCoeffs_LL[dir][ (i + 2) * W_L + j] + 3.f * WavCoeffs_LL[dir][i * W_L + j - 2] + 3.f * WavCoeffs_LL[dir][i * W_L + j + 2] - + 2.f * WavCoeffs_LL[dir][ (i - 2) * W_L + j - 1] + 2.f * WavCoeffs_LL[dir][ (i - 2) * W_L + j + 1] + 2.f * WavCoeffs_LL[dir][ (i + 2) * W_L + j + 1] + 2.f * WavCoeffs_LL[dir][ (i + 2) * W_L + j - 1] - + 2.f * WavCoeffs_LL[dir][ (i - 1) * W_L + j - 2] + 2.f * WavCoeffs_LL[dir][ (i - 1) * W_L + j + 2] + 2.f * WavCoeffs_LL[dir][ (i + 1) * W_L + j + 2] + 2.f * WavCoeffs_LL[dir][ (i + 1) * W_L + j - 2] - + 0.5f * WavCoeffs_LL[dir][ (i - 2) * W_L + j - 2] + 0.5f * WavCoeffs_LL[dir][ (i - 2) * W_L + j + 2] + 0.5f * WavCoeffs_LL[dir][ (i + 2) * W_L + j - 2] + 0.5f * WavCoeffs_LL[dir][ (i + 2) * W_L + j + 2] + tmC[i][j] = (15.f * WavCoeffs_LL[dir][i * W_L + j] + 10.f * WavCoeffs_LL[dir][(i - 1) * W_L + j] + 10.f * WavCoeffs_LL[dir][(i + 1) * W_L + j] + + 10.f * WavCoeffs_LL[dir][i * W_L + j + 1] + 10.f * WavCoeffs_LL[dir][i * W_L + j - 1] + 7.f * WavCoeffs_LL[dir][(i - 1) * W_L + j - 1] + + 7.f * WavCoeffs_LL[dir][(i - 1) * W_L + j + 1] + 7.f * WavCoeffs_LL[dir][(i + 1) * W_L + j - 1] + 7.f * WavCoeffs_LL[dir][(i + 1) * W_L + j + 1] + + 3.f * WavCoeffs_LL[dir][(i - 2) * W_L + j] + 3.f * WavCoeffs_LL[dir][(i + 2) * W_L + j] + 3.f * WavCoeffs_LL[dir][i * W_L + j - 2] + 3.f * WavCoeffs_LL[dir][i * W_L + j + 2] + + 2.f * WavCoeffs_LL[dir][(i - 2) * W_L + j - 1] + 2.f * WavCoeffs_LL[dir][(i - 2) * W_L + j + 1] + 2.f * WavCoeffs_LL[dir][(i + 2) * W_L + j + 1] + 2.f * WavCoeffs_LL[dir][(i + 2) * W_L + j - 1] + + 2.f * WavCoeffs_LL[dir][(i - 1) * W_L + j - 2] + 2.f * WavCoeffs_LL[dir][(i - 1) * W_L + j + 2] + 2.f * WavCoeffs_LL[dir][(i + 1) * W_L + j + 2] + 2.f * WavCoeffs_LL[dir][(i + 1) * W_L + j - 2] + + 0.5f * WavCoeffs_LL[dir][(i - 2) * W_L + j - 2] + 0.5f * WavCoeffs_LL[dir][(i - 2) * W_L + j + 2] + 0.5f * WavCoeffs_LL[dir][(i + 2) * W_L + j - 2] + 0.5f * WavCoeffs_LL[dir][(i + 2) * W_L + j + 2] ) * 0.0088495f; } else {//sigma=1.4 - tmC[i][j] = (15.f * WavCoeffs_LL[dir][i * W_L + j] + 12.f * WavCoeffs_LL[dir][ (i - 1) * W_L + j] + 12.f * WavCoeffs_LL[dir][ (i + 1) * W_L + j] - + 12.f * WavCoeffs_LL[dir][i * W_L + j + 1] + 12.f * WavCoeffs_LL[dir][i * W_L + j - 1] + 9.f * WavCoeffs_LL[dir][ (i - 1) * W_L + j - 1] - + 9.f * WavCoeffs_LL[dir][ (i - 1) * W_L + j + 1] + 9.f * WavCoeffs_LL[dir][ (i + 1) * W_L + j - 1] + 9.f * WavCoeffs_LL[dir][ (i + 1) * W_L + j + 1] - + 5.f * WavCoeffs_LL[dir][ (i - 2) * W_L + j] + 5.f * WavCoeffs_LL[dir][ (i + 2) * W_L + j] + 5.f * WavCoeffs_LL[dir][i * W_L + j - 2] + 5.f * WavCoeffs_LL[dir][i * W_L + j + 2] - + 4.f * WavCoeffs_LL[dir][ (i - 2) * W_L + j - 1] + 4.f * WavCoeffs_LL[dir][ (i - 2) * W_L + j + 1] + 4.f * WavCoeffs_LL[dir][ (i + 2) * W_L + j + 1] + 4.f * WavCoeffs_LL[dir][ (i + 2) * W_L + j - 1] - + 4.f * WavCoeffs_LL[dir][ (i - 1) * W_L + j - 2] + 4.f * WavCoeffs_LL[dir][ (i - 1) * W_L + j + 2] + 4.f * WavCoeffs_LL[dir][ (i + 1) * W_L + j + 2] + 4.f * WavCoeffs_LL[dir][ (i + 1) * W_L + j - 2] - + 2.f * WavCoeffs_LL[dir][ (i - 2) * W_L + j - 2] + 2.f * WavCoeffs_LL[dir][ (i - 2) * W_L + j + 2] + 2.f * WavCoeffs_LL[dir][ (i + 2) * W_L + j - 2] + 2.f * WavCoeffs_LL[dir][ (i + 2) * W_L + j + 2] + tmC[i][j] = (15.f * WavCoeffs_LL[dir][i * W_L + j] + 12.f * WavCoeffs_LL[dir][(i - 1) * W_L + j] + 12.f * WavCoeffs_LL[dir][(i + 1) * W_L + j] + + 12.f * WavCoeffs_LL[dir][i * W_L + j + 1] + 12.f * WavCoeffs_LL[dir][i * W_L + j - 1] + 9.f * WavCoeffs_LL[dir][(i - 1) * W_L + j - 1] + + 9.f * WavCoeffs_LL[dir][(i - 1) * W_L + j + 1] + 9.f * WavCoeffs_LL[dir][(i + 1) * W_L + j - 1] + 9.f * WavCoeffs_LL[dir][(i + 1) * W_L + j + 1] + + 5.f * WavCoeffs_LL[dir][(i - 2) * W_L + j] + 5.f * WavCoeffs_LL[dir][(i + 2) * W_L + j] + 5.f * WavCoeffs_LL[dir][i * W_L + j - 2] + 5.f * WavCoeffs_LL[dir][i * W_L + j + 2] + + 4.f * WavCoeffs_LL[dir][(i - 2) * W_L + j - 1] + 4.f * WavCoeffs_LL[dir][(i - 2) * W_L + j + 1] + 4.f * WavCoeffs_LL[dir][(i + 2) * W_L + j + 1] + 4.f * WavCoeffs_LL[dir][(i + 2) * W_L + j - 1] + + 4.f * WavCoeffs_LL[dir][(i - 1) * W_L + j - 2] + 4.f * WavCoeffs_LL[dir][(i - 1) * W_L + j + 2] + 4.f * WavCoeffs_LL[dir][(i + 1) * W_L + j + 2] + 4.f * WavCoeffs_LL[dir][(i + 1) * W_L + j - 2] + + 2.f * WavCoeffs_LL[dir][(i - 2) * W_L + j - 2] + 2.f * WavCoeffs_LL[dir][(i - 2) * W_L + j + 2] + 2.f * WavCoeffs_LL[dir][(i + 2) * W_L + j - 2] + 2.f * WavCoeffs_LL[dir][(i + 2) * W_L + j + 2] ) * 0.0062893f; } @@ -2302,21 +2911,21 @@ void ImProcFunctions::calckoe (float ** WavCoeffs_LL, float gradw, float tloww, thr2 += gradw / 30.f; //to test float diffFactor = (gradw / 100.f); - for (int i = 0; i < H_L; i++ ) { + for (int i = 0; i < H_L; i++) { for (int j = 0; j < W_L; j++) { koeLi[level * 3 + dir - 1][i * W_L + j] = 1.f; } } - for (int i = borderL; i < H_L - borderL; i++ ) { + for (int i = borderL; i < H_L - borderL; i++) { for (int j = borderL; j < W_L - borderL; j++) { // my own algo : probably a little false, but simpler as Lipschitz ! // Thr2 = maximum of the function ==> Lipsitch says = probably edge // float temp = WavCoeffs_LL[dir][i*W_L + j]; // if(temp>=0.f && temp < thr) temp = thr; // if(temp < 0.f && temp > -thr) temp = -thr; - float temp = max (fabsf (WavCoeffs_LL[dir][i * W_L + j]), thr ); - koeLi[level * 3 + dir - 1][i * W_L + j] = min (thr2, fabs (tmC[i][j] / temp)); // limit maxi + float temp = rtengine::max(std::fabs(WavCoeffs_LL[dir][i * W_L + j]), thr); + koeLi[level * 3 + dir - 1][i * W_L + j] = rtengine::min(thr2, std::fabs(tmC[i][j] / temp)); // limit maxi //it will be more complicated to calculate both Wh and Wv, but we have also Wd==> pseudo Lipschitz if (koeLi[level * 3 + dir - 1][i * W_L + j] > maxkoeLi[level * 3 + dir - 1]) { @@ -2331,15 +2940,15 @@ void ImProcFunctions::calckoe (float ** WavCoeffs_LL, float gradw, float tloww, } -void ImProcFunctions::finalContAllL (float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, - int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL) +void ImProcFunctions::finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp, + int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL) { - if (cp.diagcurv && cp.finena && MaxP[level] > 0.f && mean[level] != 0.f && sigma[level] != 0.f ) { //curve + if (cp.diagcurv && cp.finena && MaxP[level] > 0.f && mean[level] != 0.f && sigma[level] != 0.f) { //curve float insigma = 0.666f; //SD - float logmax = log (MaxP[level]); //log Max + float logmax = log(MaxP[level]); //log Max float rapX = (mean[level] + sigma[level]) / MaxP[level]; //rapport between sD / max - float inx = log (insigma); - float iny = log (rapX); + float inx = log(insigma); + float iny = log(rapX); float rap = inx / iny; //koef float asig = 0.166f / sigma[level]; float bsig = 0.5f - asig * mean[level]; @@ -2352,15 +2961,15 @@ void ImProcFunctions::finalContAllL (float ** WavCoeffs_L, float * WavCoeffs_L0, for (int i = 0; i < W_L * H_L; i++) { float absciss; - if (fabsf (WavCoeffs_L[dir][i]) >= (mean[level] + sigma[level])) { //for max - float valcour = xlogf (fabsf (WavCoeffs_L[dir][i])); + if (std::fabs(WavCoeffs_L[dir][i]) >= (mean[level] + sigma[level])) { //for max + float valcour = xlogf(std::fabs(WavCoeffs_L[dir][i])); float valc = valcour - logmax; float vald = valc * rap; - absciss = xexpf (vald); - } else if (fabsf (WavCoeffs_L[dir][i]) >= mean[level]) { - absciss = asig * fabsf (WavCoeffs_L[dir][i]) + bsig; + absciss = xexpf(vald); + } else if (std::fabs(WavCoeffs_L[dir][i]) >= mean[level]) { + absciss = asig * std::fabs(WavCoeffs_L[dir][i]) + bsig; } else { - absciss = amean * fabsf (WavCoeffs_L[dir][i]); + absciss = amean * std::fabs(WavCoeffs_L[dir][i]); } float kc = waOpacityCurveWL[absciss * 500.f] - 0.5f; @@ -2419,18 +3028,18 @@ void ImProcFunctions::finalContAllL (float ** WavCoeffs_L, float * WavCoeffs_L0, if (choiceDir == 0) { // All directions if (level != choicelevel) { // zero all for the levels != choicelevel - for (int dir = 1; dir < 4; dir++) { + for (int d = 1; d < 4; d++) { for (int i = 0; i < W_L * H_L; i++) { - WavCoeffs_L[dir][i] = 0.f; + WavCoeffs_L[d][i] = 0.f; } } } } else { // zero the unwanted directions for level == choicelevel if (choicelevel >= cp.maxilev) { - for (int dir = 1; dir < 4; dir++) { + for (int d = 1; d < 4; d++) { for (int i = 0; i < W_L * H_L; i++) { - WavCoeffs_L[dir][i] = 0.f; + WavCoeffs_L[d][i] = 0.f; } } } else if (level != choicelevel) { // zero all for the levels != choicelevel @@ -2442,9 +3051,9 @@ void ImProcFunctions::finalContAllL (float ** WavCoeffs_L, float * WavCoeffs_L0, } else if (choiceClevel == 1) { // Only below level if (choiceDir == 0) { // All directions if (level > choicelevel) { - for (int dir = 1; dir < 4; dir++) { + for (int d = 1; d < 4; d++) { for (int i = 0; i < W_L * H_L; i++) { - WavCoeffs_L[dir][i] = 0.f; + WavCoeffs_L[d][i] = 0.f; } } } @@ -2458,17 +3067,17 @@ void ImProcFunctions::finalContAllL (float ** WavCoeffs_L, float * WavCoeffs_L0, } else if (choiceClevel == 2) { // Only above level if (choiceDir == 0) { // All directions if (level <= choicelevel) { - for (int dir = 1; dir < 4; dir++) { + for (int d = 1; d < 4; d++) { for (int i = 0; i < W_L * H_L; i++) { - WavCoeffs_L[dir][i] = 0.f; + WavCoeffs_L[d][i] = 0.f; } } } } else { // zero the unwanted directions for level >= choicelevel if (choicelevel >= cp.maxilev) { - for (int dir = 1; dir < 4; dir++) { + for (int d = 1; d < 4; d++) { for (int i = 0; i < W_L * H_L; i++) { - WavCoeffs_L[dir][i] = 0.f; + WavCoeffs_L[d][i] = 0.f; } } } @@ -2485,11 +3094,11 @@ void ImProcFunctions::finalContAllL (float ** WavCoeffs_L, float * WavCoeffs_L0, } -void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * labco, float ** varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, - int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili) +void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * labco, float ** varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, + int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili) { - assert (level >= 0); - assert (maxlvl > level); + assert(level >= 0); + assert(maxlvl > level); static const float scales[10] = {1.f, 2.f, 4.f, 8.f, 16.f, 32.f, 64.f, 128.f, 256.f, 512.f}; float scaleskip[10]; @@ -2498,20 +3107,65 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit scaleskip[sc] = scales[sc] / skip; } - float t_r = 40.f; - float t_l = 10.f; - float b_r = 75.f; - float edd = 3.f; - float eddstrength = 1.3f; - float aedstr = (eddstrength - 1.f) / 90.f; - float bedstr = 1.f - 10.f * aedstr; + if (settings->verbose) { + printf("level=%i mean=%f sigma=%f maxp=%f\n", level, mean[level], sigma[level], MaxP[level]); + } + + constexpr float t_r = 40.f; + constexpr float t_l = 10.f; + constexpr float b_r = 75.f; + constexpr float edd = 3.f; + constexpr float eddstrength = 1.3f; + constexpr float aedstr = (eddstrength - 1.f) / 90.f; + constexpr float bedstr = 1.f - 10.f * aedstr; + + float mea[10]; + float beta = 1.f; + + if (cp.eff < 2.5f) { + float effect = cp.eff; + float offs = 1.f; + + calceffect(level, mean, sigma, mea, effect, offs); + + for (int co = 0; co < H_L * W_L; co++) { + float WavCL = std::fabs(WavCoeffs_L[dir][co]); + + if (WavCL < mea[0]) { + beta = 0.05f; + } else if (WavCL < mea[1]) { + beta = 0.2f; + } else if (WavCL < mea[2]) { + beta = 0.7f; + } else if (WavCL < mea[3]) { + beta = 1.f; //standard + } else if (WavCL < mea[4]) { + beta = 1.f; + } else if (WavCL < mea[5]) { + beta = 0.8f; //+sigma + } else if (WavCL < mea[6]) { + beta = 0.6f; + } else if (WavCL < mea[7]) { + beta = 0.4f; + } else if (WavCL < mea[8]) { + beta = 0.2f; // + 2 sigma + } else if (WavCL < mea[9]) { + beta = 0.1f; + } else { + beta = 0.0f; + } + + } + } + if (cp.val > 0 && cp.edgeena) { + + float * koe = nullptr; float maxkoe = 0.f; if (!lipschitz) { - koe = new float [H_L * W_L]; for (int i = 0; i < W_L * H_L; i++) { @@ -2534,9 +3188,9 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit for (int j = 1; j < W_L - 1; j++) { //edge detection wavelet TMC Canny // also possible to detect noise with 5x5 instead of 3x3 - tmC[i][j] = (4.f * WavCoeffs_L[dir][i * W_L + j] + 2.f * WavCoeffs_L[dir][ (i - 1) * W_L + j] + 2.f * WavCoeffs_L[dir][ (i + 1) * W_L + j] - + 2.f * WavCoeffs_L[dir][i * W_L + j + 1] + 2.f * WavCoeffs_L[dir][i * W_L + j - 1] + WavCoeffs_L[dir][ (i - 1) * W_L + j - 1] - + WavCoeffs_L[dir][ (i - 1) * W_L + j + 1] + WavCoeffs_L[dir][ (i + 1) * W_L + j - 1] + WavCoeffs_L[dir][ (i + 1) * W_L + j + 1]) / 16.f; + tmC[i][j] = (4.f * WavCoeffs_L[dir][i * W_L + j] + 2.f * WavCoeffs_L[dir][(i - 1) * W_L + j] + 2.f * WavCoeffs_L[dir][(i + 1) * W_L + j] + + 2.f * WavCoeffs_L[dir][i * W_L + j + 1] + 2.f * WavCoeffs_L[dir][i * W_L + j - 1] + WavCoeffs_L[dir][(i - 1) * W_L + j - 1] + + WavCoeffs_L[dir][(i - 1) * W_L + j + 1] + WavCoeffs_L[dir][(i + 1) * W_L + j - 1] + WavCoeffs_L[dir][(i + 1) * W_L + j + 1]) / 16.f; // apply to each direction Wavelet level : horizontal / vertiacle / diagonal } @@ -2546,7 +3200,7 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit - for (int i = borderL; i < H_L - borderL; i++ ) { + for (int i = borderL; i < H_L - borderL; i++) { for (int j = borderL; j < W_L - borderL; j++) { // my own algo : probably a little false, but simpler as Lipschitz ! float thr = 40.f; //avoid artifact eg. noise...to test @@ -2562,11 +3216,9 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit temp = -thr; } - koe[i * W_L + j] = min (thr2, fabs (tmC[i][j] / temp)); + koe[i * W_L + j] = rtengine::min(thr2, std::fabs(tmC[i][j] / temp)); - if (koe[i * W_L + j] > maxkoe) { - maxkoe = koe[i * W_L + j]; - } + maxkoe = rtengine::max(maxkoe, koe[i * W_L + j]); float diff = maxkoe - koe[i * W_L + j]; diff *= (cp.eddet / 100.f); @@ -2599,23 +3251,20 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit value *= (atten01234 * scaleskip[1]); //for zoom < 100% reduce strength...I choose level 1...but!! } + value *= beta; float edge = 1.f; float lim0 = 20.f; //arbitrary limit for low radius and level between 2 or 3 to 30 maxi float lev = float (level); float repart = (float)cp.til; - float brepart; - if (cp.reinforce == 1) { - brepart = 3.f; - } - - if (cp.reinforce == 3) { - brepart = 0.5f; //arbitrary value to increase / decrease repart, between 1 and 0 - } - - float arepart = - (brepart - 1.f) / (lim0 / 60.f); if (cp.reinforce != 2) { + const float brepart = + cp.reinforce == 1 + ? 3.f + : 0.5f; + const float arepart = -(brepart - 1.f) / (lim0 / 60.f); + if (rad < lim0 / 60.f) { repart *= (arepart * rad + brepart); //linear repartition of repart } @@ -2624,14 +3273,14 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit float al0 = 1.f + (repart) / 50.f; float al10 = 1.0f; //arbitrary value ==> less = take into account high levels // float ak =-(al0-al10)/10.f;//10 = maximum levels - float ak = - (al0 - al10) / 10.f; //10 = maximum levels + float ak = -(al0 - al10) / 10.f; //10 = maximum levels float bk = al0; float koef = ak * level + bk; //modulate for levels : more levels high, more koef low ==> concentrated action on low levels, without or near for high levels - float expkoef = -pow (fabs (rad - lev), koef); //reduce effect for high levels + float expkoef = -std::pow(std::fabs(rad - lev), koef); //reduce effect for high levels if (cp.reinforce == 3) { if (rad < lim0 / 60.f && level == 0) { - expkoef *= abs (repart); //reduce effect for low values of rad and level=0==> quasi only level 1 is effective + expkoef *= abs(repart); //reduce effect for low values of rad and level=0==> quasi only level 1 is effective } } @@ -2642,7 +3291,7 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit } //take into account local contrast - float refin = value * exp (expkoef); + float refin = value * exp(expkoef); if (cp.link && cp.noiseena) { //combi { @@ -2666,13 +3315,13 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit float edgePrecalc = 1.f + refin; //estimate edge "pseudo variance" - if(cp.EDmet == 2 && MaxP[level] > 0.f) { //curve + if (cp.EDmet == 2 && MaxP[level] > 0.f) { //curve // if(exa) {//curve float insigma = 0.666f; //SD - float logmax = log (MaxP[level]); //log Max + float logmax = log(MaxP[level]); //log Max float rapX = (mean[level] + sigma[level]) / MaxP[level]; //rapport between sD / max - float inx = log (insigma); - float iny = log (rapX); + float inx = log(insigma); + float iny = log(rapX); float rap = inx / iny; //koef float asig = 0.166f / sigma[level]; float bsig = 0.5f - asig * mean[level]; @@ -2682,7 +3331,7 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit float kmul; int borderL = 1; - for (int i = borderL; i < H_L - borderL; i++ ) { + for (int i = borderL; i < H_L - borderL; i++) { for (int j = borderL; j < W_L - borderL; j++) { int k = i * W_L + j; @@ -2707,16 +3356,16 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit } if (cp.edgcurv) { - if (fabs (WavCoeffs_L[dir][k]) >= (mean[level] + sigma[level])) { //for max - float valcour = log (fabs (WavCoeffs_L[dir][k])); + if (std::fabs(WavCoeffs_L[dir][k]) >= (mean[level] + sigma[level])) { //for max + float valcour = xlogf(std::fabs(WavCoeffs_L[dir][k])); float valc = valcour - logmax; float vald = valc * rap; - absciss = exp (vald); + absciss = exp(vald); - } else if (fabs (WavCoeffs_L[dir][k]) >= mean[level] && fabs (WavCoeffs_L[dir][k]) < (mean[level] + sigma[level])) { - absciss = asig * fabs (WavCoeffs_L[dir][k]) + bsig; - } else if (fabs (WavCoeffs_L[dir][k]) < mean[level]) { - absciss = amean * fabs (WavCoeffs_L[dir][k]); + } else if (std::fabs(WavCoeffs_L[dir][k]) >= mean[level] && std::fabs(WavCoeffs_L[dir][k]) < (mean[level] + sigma[level])) { + absciss = asig * std::fabs(WavCoeffs_L[dir][k]) + bsig; + } else if (std::fabs(WavCoeffs_L[dir][k]) < mean[level]) { + absciss = amean * std::fabs(WavCoeffs_L[dir][k]); } // Threshold adjuster settings==> approximative for curve @@ -2726,33 +3375,32 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit // kmul about max ==> 9 // we can change these values // result is different not best or bad than threshold slider...but similar - float abssd = 4.f; //amplification reference - float bbssd = 2.f; //mini ampli - float maxamp = 2.5f; //maxi ampli at end - float maxampd = 10.f; //maxi ampli at end - float a_abssd = (maxamp - abssd) / 0.333f; - float b_abssd = maxamp - a_abssd; - float da_abssd = (maxampd - abssd) / 0.333f; - float db_abssd = maxampd - da_abssd; - float am = (abssd - bbssd) / 0.666f; + constexpr float abssd = 4.f; //amplification reference + constexpr float bbssd = 2.f; //mini ampli float kmuld = 0.f; if (absciss > 0.666f && absciss < 1.f) { + constexpr float maxamp = 2.5f; //maxi ampli at end + constexpr float maxampd = 10.f; //maxi ampli at end + constexpr float a_abssd = (maxamp - abssd) / 0.333f; + constexpr float b_abssd = maxamp - a_abssd; + constexpr float da_abssd = (maxampd - abssd) / 0.333f; + constexpr float db_abssd = maxampd - da_abssd; kmul = a_abssd * absciss + b_abssd; //about max ==> kinterm kmuld = da_abssd * absciss + db_abssd; } else { + constexpr float am = (abssd - bbssd) / 0.666f; kmul = kmuld = absciss * am + bbssd; } - kinterm = 1.f; - float kc = kmul * (wavCLVCcurve[absciss * 500.f] - 0.5f); - float kcd = kmuld * (wavCLVCcurve[absciss * 500.f] - 0.5f); + const float kc = kmul * (wavCLVCcurve[absciss * 500.f] - 0.5f); if (kc >= 0.f) { float reduceeffect = 0.6f; kinterm = 1.f + reduceeffect * kmul * (wavCLVCcurve[absciss * 500.f] - 0.5f); //about 1 to 3 general and big amplification for max (under 0) } else { - kinterm = 1.f - (SQR (kcd)) / 10.f; + const float kcd = kmuld * (wavCLVCcurve[absciss * 500.f] - 0.5f); + kinterm = 1.f - (SQR(kcd)) / 10.f; } if (kinterm < 0.f) { @@ -2760,39 +3408,36 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit } edge *= kinterm; - - if (edge < 1.f) { - edge = 1.f; - } + edge = rtengine::max(edge, 1.f); } WavCoeffs_L[dir][k] *= edge; } } } else if (cp.EDmet == 1) { //threshold adjuster - float MaxPCompare = MaxP[level] * SQR (cp.edg_max / 100.f); //100 instead of b_r...case if b_r < 100 + float MaxPCompare = MaxP[level] * SQR(cp.edg_max / 100.f); //100 instead of b_r...case if b_r < 100 float MaxNCompare = MaxN[level] * SQR(cp.edg_max / 100.f); //always reduce a little edge for near max values float edgeSdCompare = (mean[level] + 1.5f * sigma[level]) * SQR(cp.edg_sd / t_r); // 1.5 standard deviation #80% range between mean 50% and 80% - float edgeMeanCompare = mean[level] * SQR (cp.edg_mean / t_l); - float edgeLowCompare = (5.f + SQR (cp.edg_low)); - float edgeMeanFactor = cbrt (cp.edg_mean / t_l); + float edgeMeanCompare = mean[level] * SQR(cp.edg_mean / t_l); + float edgeLowCompare = (5.f + SQR(cp.edg_low)); + float edgeMeanFactor = cbrt(cp.edg_mean / t_l); float interm; if (cp.edg_low < 10.f) { - interm = cbrt ((5.f + cp.edg_low) / 5.f); + interm = cbrt((5.f + cp.edg_low) / 5.f); } else { interm = 1.437f; //cbrt(3); } float edgeLowFactor = interm; float edgeSdFactor = cp.edg_sd / t_r; - float edgeMaxFactor = SQR (cp.edg_max / b_r); + float edgeMaxFactor = SQR(cp.edg_max / b_r); float edgMaxFsup = (cp.edg_max / b_r); //reduce increase of effect for high values contrast..if slider > b_r //for (int i=0; i 0) by evaluate2(), eval2(), aver() , sigma() - if (b_r < 100.f && cp.edg_max / b_r > 1.f) { //in case of b_r < 100 and slider move to right +// if (b_r < 100.f && cp.edg_max / b_r > 1.f) { //in case of b_r < 100 and slider move to right + if (cp.edg_max / b_r > 1.f) { //in case of b_r < 100 and slider move to right if (WavCoeffs_L[dir][k] > MaxPCompare * cp.edg_max / b_r) { edge *= edgMaxFsup; @@ -2857,8 +3503,8 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit } } - if (fabs (WavCoeffs_L[dir][k]) >= edgeMeanCompare && fabs (WavCoeffs_L[dir][k]) < edgeSdCompare) { - //if (fabs(WavCoeffs_L[dir][i]) > edgeSdCompare) { + if (std::fabs(WavCoeffs_L[dir][k]) >= edgeMeanCompare && std::fabs(WavCoeffs_L[dir][k]) < edgeSdCompare) { + //if (std::fabs(WavCoeffs_L[dir][i]) > edgeSdCompare) { edge *= edgeSdFactor; if (edge < 1.f) { @@ -2866,7 +3512,7 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit } }//modify effect if sd change - if (fabs (WavCoeffs_L[dir][k]) < edgeMeanCompare) { + if (std::fabs(WavCoeffs_L[dir][k]) < edgeMeanCompare) { edge *= edgeMeanFactor; if (edge < 1.f) { @@ -2874,7 +3520,7 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit } } // modify effect if mean change - if (fabs (WavCoeffs_L[dir][k]) < edgeLowCompare) { + if (std::fabs(WavCoeffs_L[dir][k]) < edgeLowCompare) { edge *= edgeLowFactor; if (edge < 1.f) { @@ -2925,52 +3571,50 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit const float skinprot = params->wavelet.skinprotect; const float skinprotneg = -skinprot; const float factorHard = (1.f - skinprotneg / 100.f); - - //to adjust increase contrast with local contrast - - //for each pixel and each level + const float offs = params->wavelet.offset; + const float lowthr = params->wavelet.lowthr; + float mea[10]; + float effect = cp.sigm; float beta; - float mea[9]; - mea[0] = mean[level] / 6.f; - mea[1] = mean[level] / 2.f; - mea[2] = mean[level]; // 50% data - mea[3] = mean[level] + sigma[level] / 2.f; - mea[4] = mean[level] + sigma[level]; //66% - mea[5] = mean[level] + 1.2f * sigma[level]; - mea[6] = mean[level] + 1.5f * sigma[level]; // - mea[7] = mean[level] + 2.f * sigma[level]; //95% - mea[8] = mean[level] + 2.5f * sigma[level]; //99% + + calceffect(level, mean, sigma, mea, effect, offs); bool useChromAndHue = (skinprot != 0.f || cp.HSmet); float modchro; + float red0 = 0.005f * (110.f - lowthr); + float red1 = 0.008f * (110.f - lowthr); + float red2 = 0.011f * (110.f - lowthr); + for (int i = 0; i < W_L * H_L; i++) { float kLlev = 1.f; if (cpMul < 0.f) { beta = 1.f; // disabled for negatives values "less contrast" } else { - float WavCL = fabsf (WavCoeffs_L[dir][i]); + float WavCL = std::fabs(WavCoeffs_L[dir][i]); //reduction amplification: max action between mean / 2 and mean + sigma // arbitrary coefficient, we can add a slider !! if (WavCL < mea[0]) { - beta = 0.6f; //preserve very low contrast (sky...) + beta = 0.4f * red0;//preserve very low contrast (sky...) } else if (WavCL < mea[1]) { - beta = 0.8f; + beta = 0.5f * red1; } else if (WavCL < mea[2]) { - beta = 1.f; //standard + beta = 0.7f * red2; } else if (WavCL < mea[3]) { - beta = 1.f; + beta = 1.f; //standard } else if (WavCL < mea[4]) { - beta = 0.8f; //+sigma + beta = 1.f; } else if (WavCL < mea[5]) { - beta = 0.6f; + beta = 0.8f; //+sigma } else if (WavCL < mea[6]) { - beta = 0.4f; + beta = 0.6f; } else if (WavCL < mea[7]) { - beta = 0.2f; // + 2 sigma + beta = 0.4f; } else if (WavCL < mea[8]) { + beta = 0.2f; // + 2 sigma + } else if (WavCL < mea[9]) { beta = 0.1f; } else { beta = 0.0f; @@ -2987,7 +3631,7 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit float LL = labco->L[ii * 2][jj * 2]; LL100 = LL100init = LL / 327.68f; LL100res = WavCoeffs_L0[i] / 327.68f; - float delta = fabs (LL100init - LL100res) / (maxlvl / 2); + float delta = std::fabs(LL100init - LL100res) / (maxlvl / 2); for (int ml = 0; ml < maxlvl; ml++) { if (ml < maxlvl / 2) { @@ -3005,9 +3649,9 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit scale = 1.f; if (skinprot > 0.f) { - Color::SkinSatCbdl2 (LL100, modhue, modchro, skinprot, scale, true, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 0); //0 for skin and extand + Color::SkinSatCbdl2(LL100, modhue, modchro, skinprot, scale, true, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 0); //0 for skin and extand } else if (skinprot < 0.f) { - Color::SkinSatCbdl2 (LL100, modhue, modchro, skinprotneg, scale, false, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 0); + Color::SkinSatCbdl2(LL100, modhue, modchro, skinprotneg, scale, false, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 0); if (scale == 1.f) { scale = factorHard; @@ -3021,9 +3665,8 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit if (Chutili) { int i_i = i / W_L; int j_j = i - i_i * W_L; - double lr; 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(ChCurve->getVal(Color::huelab_to_huehsv2(modhue2))) - 0.5f; //get valparam=f(H) if (valparam > 0.f) { scale2 = 1.f + 3.f * valparam; //arbitrary value @@ -3152,10 +3795,10 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit float k1 = 600.f; float k2 = 300.f; float LL100 = labco->L[ii * 2][jj * 2] / 327.68f; - float aa = 4970.f; - float bb = -397000.f; - float b0 = 100000.f; - float a0 = -4970.f; + constexpr float aa = 4970.f; + constexpr float bb = -397000.f; + constexpr float b0 = 100000.f; + constexpr float a0 = -4970.f; if (LL100 > 80.f) { k1 = aa * LL100 + bb; @@ -3187,12 +3830,12 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit } // to see each level of wavelet ...level from 0 to 8 - int choicelevel = params->wavelet.Lmethod - 1; - choicelevel = choicelevel == -1 ? 4 : choicelevel; +// int choicelevel = params->wavelet.Lmethod - 1; +// choicelevel = choicelevel == -1 ? 4 : choicelevel; } -void ImProcFunctions::ContAllAB (LabImage * labco, int maxlvl, float ** varhue, float **varchrom, float ** WavCoeffs_ab, float * WavCoeffs_ab0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, - int W_ab, int H_ab, const bool useChannelA) +void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, float **varchrom, float ** WavCoeffs_ab, float * WavCoeffs_ab0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, + int W_ab, int H_ab, const bool useChannelA) { float cpMul = cp.mul[level]; @@ -3217,9 +3860,9 @@ void ImProcFunctions::ContAllAB (LabImage * labco, int maxlvl, float ** varhue, float scale = 1.f; if (skinprot > 0.f) { - Color::SkinSatCbdl2 (LL100, modhue, modchro, skinprot, scale, true, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 0); //0 for skin and extand + Color::SkinSatCbdl2(LL100, modhue, modchro, skinprot, scale, true, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 0); //0 for skin and extand } else if (skinprot < 0.f) { - Color::SkinSatCbdl2 (LL100, modhue, modchro, skinprotneg, scale, false, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 0); + Color::SkinSatCbdl2(LL100, modhue, modchro, skinprotneg, scale, false, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 0); scale = (scale == 1.f) ? factorHard : 1.f; } @@ -3235,7 +3878,7 @@ void ImProcFunctions::ContAllAB (LabImage * labco, int maxlvl, float ** varhue, float cpMulC = cp.mulC[level]; // if( (cp.curv || cp.CHSLmet==1) && cp.CHmet!=2 && level < 9 && cpMulC != 0.f) { // cpMulC == 0.f means all will be multiplied by 1.f, so we can skip - if ( cp.CHmet != 2 && level < 9 && cpMulC != 0.f && cp.chromena) { // cpMulC == 0.f means all will be multiplied by 1.f, so we can skip + if (cp.CHmet != 2 && level < 9 && cpMulC != 0.f && cp.chromena) { // cpMulC == 0.f means all will be multiplied by 1.f, so we can skip const float skinprot = params->wavelet.skinprotect; const float skinprotneg = -skinprot; const float factorHard = (1.f - skinprotneg / 100.f); @@ -3254,9 +3897,9 @@ void ImProcFunctions::ContAllAB (LabImage * labco, int maxlvl, float ** varhue, float modhue = varhue[ii][jj]; if (skinprot > 0.f) { - Color::SkinSatCbdl2 (LL100, modhue, modchro, skinprot, scale, true, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 1); //1 for curve + Color::SkinSatCbdl2(LL100, modhue, modchro, skinprot, scale, true, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 1); //1 for curve } else if (skinprot < 0.f) { - Color::SkinSatCbdl2 (LL100, modhue, modchro, skinprotneg, scale, false, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 1); + Color::SkinSatCbdl2(LL100, modhue, modchro, skinprotneg, scale, false, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 1); scale = (scale == 1.f) ? factorHard : 1.f; } } @@ -3314,12 +3957,14 @@ void ImProcFunctions::ContAllAB (LabImage * labco, int maxlvl, float ** varhue, if (useChannelA) { useOpacity = cp.opaRG; - if(level < 9) { + + if (level < 9) { mulOpacity = cp.mulopaRG[level]; } } else { useOpacity = cp.opaBY; - if(level < 9) { + + if (level < 9) { mulOpacity = cp.mulopaBY[level]; } } @@ -3409,10 +4054,10 @@ void ImProcFunctions::ContAllAB (LabImage * labco, int maxlvl, float ** varhue, float k1 = 600.f; float k2 = 300.f; float LL100 = labco->L[ii * 2][jj * 2] / 327.68f; - float aa = 4970.f; - float bb = -397000.f; - float b0 = 100000.f; - float a0 = -4970.f; + constexpr float aa = 4970.f; + constexpr float bb = -397000.f; + constexpr float b0 = 100000.f; + constexpr float a0 = -4970.f; if (LL100 > 80.f) { k1 = aa * LL100 + bb; @@ -3486,17 +4131,17 @@ void ImProcFunctions::ContAllAB (LabImage * labco, int maxlvl, float ** varhue, if (choiceClevel == 0) { // Only one level if (choiceDir == 0) { // All directions if (level != choicelevel) { // zero all for the levels != choicelevel - for (int dir = 1; dir < 4; dir++) { + for (int d = 1; d < 4; d++) { for (int i = 0; i < W_ab * H_ab; i++) { - WavCoeffs_ab[dir][i] = 0.f; + WavCoeffs_ab[d][i] = 0.f; } } } } else { // zero the unwanted directions for level == choicelevel if (choicelevel >= cp.maxilev) { - for (int dir = 1; dir < 4; dir++) { + for (int d = 1; d < 4; d++) { for (int i = 0; i < W_ab * H_ab; i++) { - WavCoeffs_ab[dir][i] = 0.f; + WavCoeffs_ab[d][i] = 0.f; } } } else if (level != choicelevel) { // zero all for the levels != choicelevel @@ -3508,9 +4153,9 @@ void ImProcFunctions::ContAllAB (LabImage * labco, int maxlvl, float ** varhue, } else if (choiceClevel == 1) { // Only below level if (choiceDir == 0) { // All directions if (level > choicelevel) { - for (int dir = 1; dir < 4; dir++) { + for (int d = 1; d < 4; d++) { for (int i = 0; i < W_ab * H_ab; i++) { - WavCoeffs_ab[dir][i] = 0.f; + WavCoeffs_ab[d][i] = 0.f; } } } @@ -3524,17 +4169,17 @@ void ImProcFunctions::ContAllAB (LabImage * labco, int maxlvl, float ** varhue, } else if (choiceClevel == 2) { // Only above level if (choiceDir == 0) { // All directions if (level <= choicelevel) { - for (int dir = 1; dir < 4; dir++) { + for (int d = 1; d < 4; d++) { for (int i = 0; i < W_ab * H_ab; i++) { - WavCoeffs_ab[dir][i] = 0.f; + WavCoeffs_ab[d][i] = 0.f; } } } } else { // zero the unwanted directions for level >= choicelevel if (choicelevel >= cp.maxilev) { - for (int dir = 1; dir < 4; dir++) { + for (int d = 1; d < 4; d++) { for (int i = 0; i < W_ab * H_ab; i++) { - WavCoeffs_ab[dir][i] = 0.f; + WavCoeffs_ab[d][i] = 0.f; } } } else if (level <= choicelevel) { @@ -3545,4 +4190,192 @@ void ImProcFunctions::ContAllAB (LabImage * labco, int maxlvl, float ** varhue, } } } + +void ImProcFunctions::softproc2(const LabImage* bufcolorig, const LabImage* bufcolfin, float rad, int bfh, int bfw, double epsilmax, double epsilmin, float thres, int sk, bool multiThread, int flag) +{ + if (flag == 0) { + if (rad > 0.f) { + array2D ble(bfw, bfh); + array2D guid(bfw, bfh); + Imagefloat *tmpImage = nullptr; + tmpImage = new Imagefloat(bfw, bfh); + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + + float X, Y, Z; + float L = bufcolorig->L[ir][jr]; + float a = bufcolorig->a[ir][jr]; + float b = bufcolorig->b[ir][jr]; + Color::Lab2XYZ(L, a, b, X, Y, Z); + + guid[ir][jr] = Y / 32768.f; + float La = bufcolfin->L[ir][jr]; + float aa = bufcolfin->a[ir][jr]; + float ba = bufcolfin->b[ir][jr]; + Color::Lab2XYZ(La, aa, ba, X, Y, Z); + tmpImage->r(ir, jr) = X; + tmpImage->g(ir, jr) = Y; + tmpImage->b(ir, jr) = Z; + + ble[ir][jr] = Y / 32768.f; + } + + double aepsil = (epsilmax - epsilmin) / 90.f; + double bepsil = epsilmax - 100.f * aepsil; + double epsil = aepsil * 0.1 * rad + bepsil; + + float blur = 10.f / sk * (thres + 0.8f * rad); + rtengine::guidedFilter(guid, ble, ble, blur, epsil, multiThread, 4); + + + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + float X = tmpImage->r(ir, jr); + float Y = 32768.f * ble[ir][jr]; + float Z = tmpImage->b(ir, jr); + float L, a, b; + Color::XYZ2Lab(X, Y, Z, L, a, b); + bufcolfin->L[ir][jr] = L; + } + + delete tmpImage; + } + } else if (flag == 1) { + if (rad > 0.f) { + array2D ble(bfw, bfh); + array2D blechro(bfw, bfh); + array2D hue(bfw, bfh); + array2D guid(bfw, bfh); + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { +// hue[ir][jr] = xatan2f(bufcolfin->b[ir][jr], bufcolfin->a[ir][jr]); +// float chromah = sqrt(SQR(bufcolfin->b[ir][jr]) + SQR(bufcolfin->a[ir][jr])); + + ble[ir][jr] = (bufcolfin->L[ir][jr]) / 32768.f; +// blechro[ir][jr] = chromah / 32768.f; + guid[ir][jr] = bufcolorig->L[ir][jr] / 32768.f; + } + + double aepsil = (epsilmax - epsilmin) / 90.f; + double bepsil = epsilmax - 100.f * aepsil; + double epsil = aepsil * 0.1 * rad + bepsil; + + if (rad != 0.f) { + float blur = rad; + blur = blur < 0.f ? -1.f / blur : 1.f + blur; + // int r1 = max(int(4 / sk * blur + 0.5), 1); + int r2 = max(int(25 / sk * blur + 0.5), 1); + + if (rad < 0.f) { + epsil = 0.0001; + } + + rtengine::guidedFilter(guid, ble, ble, r2, epsil, multiThread); +// rtengine::guidedFilter(guid, blechro, blechro, r1, 0.5 * epsil, multiThread); + } + + + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + // float2 sincosval = xsincosf(hue[ir][jr]); + + bufcolfin->L[ir][jr] = 32768.f * ble[ir][jr]; + // bufcolfin->a[ir][jr] = 32768.f * sincosval.y * blechro[ir][jr]; + // bufcolfin->b[ir][jr] = 32768.f * sincosval.x * blechro[ir][jr]; + } + } + + } +} + + +void ImProcFunctions::Compresslevels2(float **Source, int W_L, int H_L, float compression, float detailattenuator, float thres, float mean, float maxp, float meanN, float maxN, float madL) +{ + //J.Desmis 12-2019 + + float exponent; + + if (detailattenuator > 0.f && detailattenuator < 0.05f) { + float betemp = expf(-(2.f - detailattenuator + 0.693147f)) - 1.f; //0.69315 = log(2) + exponent = 1.2f * xlogf(-betemp); + exponent /= 20.f; + } else if (detailattenuator >= 0.05f && detailattenuator < 0.25f) { + float betemp = expf(-(2.f - detailattenuator + 0.693147f)) - 1.f; + exponent = 1.2f * xlogf(-betemp); + exponent /= (-75.f * detailattenuator + 23.75f); + } else if (detailattenuator >= 0.25f) { + float betemp = expf(-(2.f - detailattenuator + 0.693147f)) - 1.f; + exponent = 1.2f * xlogf(-betemp); + exponent /= (-2.f * detailattenuator + 5.5f); + } else { + exponent = (compression - 1.0f) / 20.f; + } + + exponent += 1.f; + + + float ap = (thres - 1.f) / (maxp - mean); + float bp = 1.f - ap * mean; + + float a0 = (1.33f * thres - 1.f) / (1.f - mean); + float b0 = 1.f - a0 * mean; + + float apn = (thres - 1.f) / (maxN - meanN); + float bpn = 1.f - apn * meanN; + + float a0n = (1.33f * thres - 1.f) / (1.f - meanN); + float b0n = 1.f - a0n * meanN; + + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int y = 0; y < H_L; y++) { + for (int x = 0; x < W_L; x++) { + float expone = 1.f; + + if (Source[y][x] >= 0.f) { + + if (Source[y][x] > mean) { + expone = 1.f + (exponent - 1.f) * (ap * Source[y][x] + bp); + } else { + expone = 1.f + (exponent - 1.f) * (a0 * Source[y][x] + b0); + } + + Source[y][x] = xexpf(xlogf(Source[y][x] + 0.05f * madL) * expone); + } else if (Source[y][x] < 0.f) { + if (-Source[y][x] > mean) { + expone = 1.f + (exponent - 1.f) * (apn * -Source[y][x] + bpn); + } else { + expone = 1.f + (exponent - 1.f) * (a0n * -Source[y][x] + b0n); + } + + Source[y][x] = -xexpf(xlogf(-Source[y][x] + 0.05f * madL) * expone); + } + } + } + +} + } diff --git a/rtengine/lcp.cc b/rtengine/lcp.cc index c80a126f5..1826101e7 100644 --- a/rtengine/lcp.cc +++ b/rtengine/lcp.cc @@ -42,7 +42,6 @@ class rtengine::LCPProfile::LCPPersModel public: LCPPersModel(); bool hasModeData(LCPCorrectionMode mode) const; - void print() const; float focLen; float focDist; @@ -82,27 +81,18 @@ bool rtengine::LCPModelCommon::empty() const && 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 void rtengine::LCPModelCommon::merge(const LCPModelCommon& a, const LCPModelCommon& b, float facA) { - const float facB = 1.0f - facA; - - foc_len_x = facA * a.foc_len_x + facB * b.foc_len_x; - foc_len_y = facA * a.foc_len_y + facB * b.foc_len_y; - img_center_x = facA * a.img_center_x + facB * b.img_center_x; - img_center_y = facA * a.img_center_y + facB * b.img_center_y; - scale_factor = facA * a.scale_factor + facB * b.scale_factor; - mean_error = facA * a.mean_error + facB * b.mean_error; + foc_len_x = rtengine::intp(facA, a.foc_len_x, b.foc_len_x); + foc_len_y = rtengine::intp(facA, a.foc_len_y, b.foc_len_y); + img_center_x = rtengine::intp(facA, a.img_center_x, b.img_center_x); + img_center_y = rtengine::intp(facA, a.img_center_y, b.img_center_y); + scale_factor = rtengine::intp(facA, a.scale_factor, b.scale_factor); + mean_error = rtengine::intp(facA, a.mean_error, b.mean_error); for (int i = 0; i < 5; ++i) { - param[i] = facA * a.param[i] + facB * b.param[i]; + param[i] = rtengine::intp(facA, a.param[i], b.param[i]); } const float param0Sqr = param[0] * param[0]; @@ -152,7 +142,6 @@ void rtengine::LCPModelCommon::prepareParams( rfx = 1.0f / fx; 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() : @@ -188,35 +177,6 @@ bool rtengine::LCPProfile::LCPPersModel::hasModeData(LCPCorrectionMode mode) con 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) : isFisheye(false), sensorFormatFactor(1.f), @@ -522,7 +482,7 @@ void rtengine::LCPProfile::calcParams( ) { // Mix in 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 ( mode != LCPCorrectionMode::VIGNETTE @@ -532,7 +492,7 @@ void rtengine::LCPProfile::calcParams( ) { // 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)); - facLow = focLenOnSpot ? facDistLow : (0.8 * facLow + 0.2 * facDistLow); + facLow = focLenOnSpot ? facDistLow : (0.8f * facLow + 0.2f * facDistLow); } switch (mode) { @@ -555,7 +515,16 @@ void rtengine::LCPProfile::calcParams( } 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(focusDist), + static_cast(pLow->aperture), + static_cast(pHigh->aperture), + static_cast(pLow->focLen), + static_cast(pHigh->focLen), + static_cast(pLow->focDist), + static_cast(pHigh->focDist), + static_cast(facLow)); } } else { 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 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) { - 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 mirrorY = (rot == 180 || rot == 270); 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(focalLength), swapXY, mirrorX, mirrorY, rot, rawRotationDeg); } 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) { const double u = x * scale; const double v = y * scale; - const double u0 = mc.x0 * scale; - const double v0 = mc.y0 * scale; + const double u0 = static_cast(mc.x0) * scale; + const double v0 = static_cast(mc.y0) * scale; const double du = (u - u0); const double dv = (v - v0); const double fx = mc.fx; @@ -1059,22 +1019,22 @@ void rtengine::LCPMapper::correctDistortion(double &x, double &y, int cx, int cy } else { x *= scale; y *= scale; - const double x0 = mc.x0 * scale; - const double y0 = mc.y0 * scale; - const double xd = (x - x0) / mc.fx, yd = (y - y0) / mc.fy; + const double x0 = static_cast(mc.x0) * scale; + const double y0 = static_cast(mc.y0) * scale; + const double xd = (x - x0) / static_cast(mc.fx), yd = (y - y0) / static_cast(mc.fy); - const LCPModelCommon::Param aDist = mc.param; + const auto& aDist = mc.param; const double rsqr = xd * xd + yd * yd; - const double xfac = aDist[swapXY ? 3 : 4], yfac = aDist[swapXY ? 4 : 3]; + const double xfac = static_cast(aDist[swapXY ? 3 : 4]), yfac = static_cast(aDist[swapXY ? 4 : 3]); - const double commonFac = (((aDist[2] * rsqr + aDist[1]) * rsqr + aDist[0]) * rsqr + 1.) + const double commonFac = (((static_cast(aDist[2]) * rsqr + static_cast(aDist[1])) * rsqr + static_cast(aDist[0])) * rsqr + 1.) + 2. * (yfac * yd + xfac * xd); const double xnew = xd * commonFac + xfac * rsqr; const double ynew = yd * commonFac + yfac * rsqr; - x = xnew * mc.fx + x0; - y = ynew * mc.fy + y0; + x = xnew * static_cast(mc.fx) + x0; + y = ynew * static_cast(mc.fy) + y0; } 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 // the other are just deviations from it - double xd = (x - chrom[1].x0) / chrom[1].fx; - double yd = (y - chrom[1].y0) / chrom[1].fy; + double xd = (x - static_cast(chrom[1].x0)) / static_cast(chrom[1].fx); + double yd = (y - static_cast(chrom[1].y0)) / static_cast(chrom[1].fy); // Green contains main distortion, just like base if (useCADist) { - const LCPModelCommon::Param aDist = chrom[1].param; - double rsqr = xd * xd + yd * yd; - double xfac = aDist[swapXY ? 3 : 4], yfac = aDist[swapXY ? 4 : 3]; + const auto& aDist = chrom[1].param; + double rsqr = xd * xd + yd * yd; + double xfac = static_cast(aDist[swapXY ? 3 : 4]), yfac = static_cast(aDist[swapXY ? 4 : 3]); - double commonFac = (((aDist[2] * rsqr + aDist[1]) * rsqr + aDist[0]) * rsqr + 1.) + double commonFac = (((static_cast(aDist[2]) * rsqr + static_cast(aDist[1])) * rsqr + static_cast(aDist[0])) * rsqr + 1.) + 2. * (yfac * yd + xfac * xd); - xgreen = xd * commonFac + aDist[4] * rsqr; - ygreen = yd * commonFac + aDist[3] * rsqr; + xgreen = xd * commonFac + static_cast(aDist[4]) * rsqr; + ygreen = yd * commonFac + static_cast(aDist[3]) * rsqr; } else { xgreen = xd; ygreen = yd; @@ -1115,20 +1075,20 @@ void rtengine::LCPMapper::correctCA(double& x, double& y, int cx, int cy, int ch if (channel == 1) { // green goes directly - x = xgreen * chrom[1].fx + chrom[1].x0; - y = ygreen * chrom[1].fy + chrom[1].y0; + x = xgreen * static_cast(chrom[1].fx) + static_cast(chrom[1].x0); + y = ygreen * static_cast(chrom[1].fy) + static_cast(chrom[1].y0); } else { // others are diffs from green xd = xgreen; yd = ygreen; const double rsqr = xd * xd + yd * yd; - const LCPModelCommon::Param aCA = chrom[channel].param; - const double xfac = aCA[swapXY ? 3 : 4], yfac = aCA[swapXY ? 4 : 3]; - const double commonSum = 1. + rsqr * (aCA[0] + rsqr * (aCA[1] + aCA[2] * rsqr)) + 2. * (yfac * yd + xfac * xd); + const auto& aCA = chrom[channel].param; + const double xfac = static_cast(aCA[swapXY ? 3 : 4]), yfac = static_cast(aCA[swapXY ? 4 : 3]); + const double commonSum = 1. + rsqr * (static_cast(aCA[0]) + rsqr * (static_cast(aCA[1]) + static_cast(aCA[2] )* rsqr)) + 2. * (yfac * yd + xfac * xd); - x = (chrom[channel].scale_factor * ( xd * commonSum + xfac * rsqr )) * chrom[channel].fx + chrom[channel].x0; - y = (chrom[channel].scale_factor * ( yd * commonSum + yfac * rsqr )) * chrom[channel].fy + chrom[channel].y0; + x = (static_cast(chrom[channel].scale_factor) * ( xd * commonSum + xfac * rsqr )) * static_cast(chrom[channel].fx) + static_cast(chrom[channel].x0); + y = (static_cast(chrom[channel].scale_factor) * ( yd * commonSum + yfac * rsqr )) * static_cast(chrom[channel].fy) + static_cast(chrom[channel].y0); } x -= cx; diff --git a/rtengine/lcp.h b/rtengine/lcp.h index 2e36fe113..4c1e09865 100644 --- a/rtengine/lcp.h +++ b/rtengine/lcp.h @@ -54,7 +54,6 @@ public: LCPModelCommon(); bool empty() const; // is it empty - void print() const; // printf all values void merge(const LCPModelCommon& a, const LCPModelCommon& b, float facA); void prepareParams( int fullWidth, @@ -106,7 +105,6 @@ public: LCPModelCommon *pCorr3 ) const; // Interpolates between the persModels frames - void print() const; //private: // Common data diff --git a/rtengine/lmmse_demosaic.cc b/rtengine/lmmse_demosaic.cc index f4af1b801..5c4ddffed 100644 --- a/rtengine/lmmse_demosaic.cc +++ b/rtengine/lmmse_demosaic.cc @@ -334,7 +334,7 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, const array2D +* +* RawTherapee is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* RawTherapee is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with RawTherapee. If not, see . +*/ + +#include "color.h" + +using namespace std; + +namespace rtengine +{ + +/* + * MunsellLch correction + * Copyright (c) 2012 Jacques Desmis + * Copyright (c) 2020 Ingo Weyrich + * + * Find the right LUT and calculate the correction + */ +void Color::MunsellLch (float lum, float hue, float chrom, float memChprov, float &correction, int zone, float &lbe, bool &correctL) +{ + + const int x = memChprov; + int y = chrom; + + //begin PB correction + sky + if (zone == 1) { + if (lum > 5.f) { + if (lum < 15.f) { + if (x <= 45 && (hue >= (_15PB10[x] - 0.035f)) && (hue < (_15PB10[x] + 0.052f))) { + if (y > 49) { + y = 49; + } + correction = _15PB10[y] - _15PB10[x] ; + lbe = _15PB10[y]; + correctL = true; + } else if (x <= 85 && (hue >= ( _3PB10[x] - 0.052f)) && (hue < (_45PB10[x] + _3PB10[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _3PB10[y] - _3PB10[x]; + lbe = _3PB10[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_45PB10[x] + _3PB10[x]) * 0.5f) && (hue < (_45PB10[x] + 0.052f))) { + if (y > 89) { + y = 89; + } + correction = _45PB10[y] - _45PB10[x] ; + lbe = _45PB10[y]; + correctL = true; + } else if ((hue >= (_6PB10[x] - 0.052f) && (hue < (_6PB10[x] + _75PB10[x]) * 0.5f))) { + correction = _6PB10[y] - _6PB10[x] ; + lbe = _6PB10[y]; + correctL = true; + } else if ((hue >= (_6PB10[x] + _75PB10[x]) * 0.5f) && (hue < (_9PB10[x] + _75PB10[x]) * 0.5f)) { + correction = _75PB10[y] - _75PB10[x] ; + lbe = _75PB10[y]; + correctL = true; + } else if ((hue >= (_9PB10[x] + _75PB10[x]) * 0.5f) && (hue < (_9PB10[x] + _10PB10[x]) * 0.5f)) { + correction = _9PB10[y] - _9PB10[x] ; + lbe = _9PB10[y]; + correctL = true; + } else if ((hue >= (_10PB10[x] + _9PB10[x]) * 0.5f) && (hue < (_1P10[x] + _10PB10[x]) * 0.5f)) { + correction = _10PB10[y] - _10PB10[x] ; + lbe = _10PB10[y]; + correctL = true; + } else if ((hue >= (_10PB10[x] + _1P10[x]) * 0.5f) && (hue < (_1P10[x] + _4P10[x]) * 0.5f)) { + correction = _1P10[y] - _1P10[x]; + lbe = _1P10[y]; + correctL = true; + } else if ((hue >= (_1P10[x] + _4P10[x]) * 0.5f) && (hue < (0.035f + _4P10[x]) * 0.5f)) { + correction = _4P10[y] - _4P10[x] ; + lbe = _4P10[y]; + correctL = true; + } + } else if (lum < 25.f) { + if (x <= 85 && (hue >= (_15PB20[x] - 0.035f)) && (hue < (_15PB20[x] + _3PB20[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _15PB20[y] - _15PB20[x] ; + lbe = _15PB20[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_15PB20[x] + _3PB20[x]) * 0.5f) && (hue < (_45PB20[x] + _3PB20[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _3PB20[y] - _3PB20[x] ; + lbe = _3PB20[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_45PB20[x] + _3PB20[x]) * 0.5f) && (hue < ( _45PB20[x] + 0.052f))) { + if (y > 89) { + y = 89; + } + correction = _45PB20[y] - _45PB20[x] ; + lbe = _45PB20[y]; + correctL = true; + } else if ((hue >= (_45PB20[x] + 0.052f)) && (hue < (_6PB20[x] + _75PB20[x]) * 0.5f)) { + correction = _6PB20[y] - _6PB20[x]; + lbe = _6PB20[y]; + correctL = true; + } else if ((hue >= (_6PB20[x] + _75PB20[x]) * 0.5f) && (hue < (_9PB20[x] + _75PB20[x]) * 0.5f)) { + correction = _75PB20[y] - _75PB20[x] ; + lbe = _75PB20[y]; + correctL = true; + } else if ((hue >= (_9PB20[x] + _75PB20[x]) * 0.5f) && (hue < (_9PB20[x] + _10PB20[x]) * 0.5f)) { + correction = _9PB20[y] - _9PB20[x] ; + lbe = _9PB20[y]; + correctL = true; + } else if ((hue >= (_10PB20[x] + _9PB20[x]) * 0.5f) && (hue < (_1P20[x] + _10PB20[x]) * 0.5f)) { + correction = _10PB20[y] - _10PB20[x] ; + lbe = _10PB20[y]; + correctL = true; + } else if ((hue >= (_10PB20[x] + _1P20[x]) * 0.5f) && (hue < (_1P20[x] + _4P20[x]) * 0.5f)) { + correction = _1P20[y] - _1P20[x] ; + lbe = _1P20[y]; + correctL = true; + } else if ((hue >= (_1P20[x] + _4P20[x]) * 0.5f) && (hue < (0.035f + _4P20[x]) * 0.5f)) { + correction = _4P20[y] - _4P20[x] ; + lbe = _4P20[y]; + correctL = true; + } + } else if (lum < 35.f) { + if (x <= 85 && (hue >= (_15PB30[x] - 0.035f)) && (hue < (_15PB30[x] + _3PB30[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _15PB30[y] - _15PB30[x] ; + lbe = _15PB30[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_15PB30[x] + _3PB30[x]) * 0.5f) && (hue < (_45PB30[x] + _3PB30[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _3PB30[y] - _3PB30[x] ; + lbe = _3PB30[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_45PB30[x] + _3PB30[x]) * 0.5f) && (hue < (_45PB30[x] + 0.052f))) { + if (y > 89) { + y = 89; + } + correction = _45PB30[y] - _45PB30[x] ; + lbe = _45PB30[y]; + correctL = true; + } else if ((hue >= ( _45PB30[x] + 0.052f)) && (hue < (_6PB30[x] + _75PB30[x]) * 0.5f)) { + correction = _6PB30[y] - _6PB30[x] ; + lbe = _6PB30[y]; + correctL = true; + } else if ((hue >= (_6PB30[x] + _75PB30[x]) * 0.5f) && (hue < (_9PB30[x] + _75PB30[x]) * 0.5f)) { + correction = _75PB30[y] - _75PB30[x] ; + lbe = _75PB30[y] ; + correctL = true; + } else if ((hue >= (_9PB30[x] + _75PB30[x]) * 0.5f) && (hue < (_9PB30[x] + _10PB30[x]) * 0.5f)) { + correction = _9PB30[y] - _9PB30[x] ; + lbe = _9PB30[y]; + correctL = true; + } else if ((hue >= (_10PB30[x] + _9PB30[x]) * 0.5f) && (hue < (_1P30[x] + _10PB30[x]) * 0.5f)) { + correction = _10PB30[y] - _10PB30[x] ; + lbe = _10PB30[y]; + correctL = true; + } else if ((hue >= (_10PB30[x] + _1P30[x]) * 0.5f) && (hue < (_1P30[x] + _4P30[x]) * 0.5f)) { + correction = _1P30[y] - _1P30[x] ; + lbe = _1P30[y]; + correctL = true; + } else if ((hue >= (_1P30[x] + _4P30[x]) * 0.5f) && (hue < (0.035f + _4P30[x]) * 0.5f)) { + correction = _4P30[y] - _4P30[x] ; + lbe = _4P30[y]; + correctL = true; + } + } else if (lum < 45.f) { + if (x < 75 && (hue <= (_05PB40[x] + _15PB40[x]) * 0.5f) && (hue > (_05PB40[x] + _10B40[x]) * 0.5f)) { + if (y > 75) { + y = 75; + } + correction = _05PB40[y] - _05PB40[x] ; + lbe = _05PB40[y]; + correctL = true; + } else if (x < 70 && (hue <= (_05PB40[x] + _10B40[x]) * 0.5f) && (hue > (_10B40[x] + _9B40[x]) * 0.5f)) { + if (y > 70) { + y = 70; + } + correction = _10B40[y] - _10B40[x] ; + lbe = _10B40[y]; + correctL = true; + } else if (x < 70 && (hue <= (_10B40[x] + _9B40[x]) * 0.5f) && (hue > (_9B40[x] + _7B40[x]) * 0.5f)) { + if (y > 70) { + y = 70; + } + correction = _9B40[y] - _9B40[x] ; + lbe = _9B40[y]; + correctL = true; + } else if (x < 70 && (hue <= (_9B40[x] + _7B40[x]) * 0.5f) && (hue > (_5B40[x] + _7B40[x]) * 0.5f)) { + if (y > 70) { + y = 70; + } + correction = _7B40[y] - _7B40[x] ; + lbe = _7B40[y]; + correctL = true; + } else if (x < 70 && (hue <= (_5B40[x] + _7B40[x]) * 0.5f) && (hue > (_5B40[x] - 0.035f))) { + if (y > 70) { + y = 70; // + } + correction = _5B40[y] - _5B40[x] ; + lbe = _5B40[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_15PB40[x] - 0.035f)) && (hue < (_15PB40[x] + _3PB40[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _15PB40[y] - _15PB40[x] ; + lbe = _15PB40[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_15PB40[x] + _3PB40[x]) * 0.5f) && (hue < (_45PB40[x] + _3PB40[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _3PB40[y] - _3PB40[x] ; + lbe = _3PB40[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_45PB40[x] + _3PB40[x]) * 0.5f) && (hue < (_45PB40[x] + 0.052f))) { + if (y > 89) { + y = 89; + } + correction = _45PB40[y] - _45PB40[x] ; + lbe = _45PB40[y] ; + correctL = true; + } else if ((hue >= (_45PB40[x] + 0.052f)) && (hue < (_6PB40[x] + _75PB40[x]) * 0.5f)) { + correction = _6PB40[y] - _6PB40[x] ; + lbe = _6PB40[y]; + correctL = true; + } else if ((hue >= (_6PB40[x] + _75PB40[x]) * 0.5f) && (hue < (_9PB40[x] + _75PB40[x]) * 0.5f)) { + correction = _75PB40[y] - _75PB40[x] ; + lbe = _75PB40[y]; + correctL = true; + } else if ((hue >= (_9PB40[x] + _75PB40[x]) * 0.5f) && (hue < (_9PB40[x] + _10PB40[x]) * 0.5f)) { + correction = _9PB40[y] - _9PB40[x] ; + lbe = _9PB40[y]; + correctL = true; + } else if ((hue >= (_10PB40[x] + _9PB40[x]) * 0.5f) && (hue < (_1P40[x] + _10PB40[x]) * 0.5f)) { + correction = _10PB40[y] - _10PB40[x] ; + lbe = _10PB40[y]; + correctL = true; + } else if ((hue >= (_10PB40[x] + _1P40[x]) * 0.5f) && (hue < (_1P40[x] + _4P40[x]) * 0.5f)) { + correction = _1P40[y] - _1P40[x] ; + lbe = _1P40[y]; + correctL = true; + } else if ((hue >= (_1P40[x] + _4P40[x]) * 0.5f) && (hue < (0.035f + _4P40[x]) * 0.5f)) { + correction = _4P40[y] - _4P40[x] ; + lbe = _4P40[y]; + correctL = true; + } + } else if (lum < 55.f) { + if (x < 79 && (hue <= (_05PB50[x] + _15PB50[x]) * 0.5f) && (hue > (_05PB50[x] + _10B50[x]) * 0.5f)) { + if (y > 79) { + y = 79; + } + correction = _05PB50[y] - _05PB50[x] ; + lbe = _05PB50[y]; + correctL = true; + } else if (x < 79 && (hue <= (_05PB50[x] + _10B50[x]) * 0.5f) && (hue > (_10B50[x] + _9B50[x]) * 0.5f)) { + if (y > 79) { + y = 79; + } + correction = _10B50[y] - _10B50[x] ; + lbe = _10B50[y]; + correctL = true; + } else if (x < 79 && (hue <= (_10B50[x] + _9B50[x]) * 0.5f) && (hue > (_9B50[x] + _7B50[x]) * 0.5f)) { + if (y > 79) { + y = 79; + } + correction = _9B50[y] - _9B50[x] ; + lbe = _9B50[y]; + correctL = true; + } else if (x < 79 && (hue <= (_9B50[x] + _7B50[x]) * 0.5f) && (hue > (_5B50[x] + _7B50[x]) * 0.5f)) { + if (y > 79) { + y = 79; + } + correction = _7B50[y] - _7B50[x] ; + lbe = _7B50[y]; + correctL = true; + } else if (x < 79 && (hue <= (_5B50[x] + _7B50[x]) * 0.5f) && (hue > (_5B50[x] - 0.035f))) { + if (y > 79) { + y = 79; // + } + correction = _5B50[y] - _5B50[x] ; + lbe = _5B50[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_15PB50[x] - 0.035f)) && (hue < (_15PB50[x] + _3PB50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _15PB50[y] - _15PB50[x] ; + lbe = _15PB50[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_15PB50[x] + _3PB50[x]) * 0.5f) && (hue < (_45PB50[x] + _3PB50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _3PB50[y] - _3PB50[x] ; + lbe = _3PB50[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_45PB50[x] + _3PB50[x]) * 0.5f) && (hue < (_6PB50[x] + _45PB50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _45PB50[y] - _45PB50[x] ; + lbe = _45PB50[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_6PB50[x] + _45PB50[x]) * 0.5f) && (hue < (_6PB50[x] + _75PB50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _6PB50[y] - _6PB50[x] ; + lbe = _6PB50[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_6PB50[x] + _75PB50[x]) * 0.5f) && (hue < (_9PB50[x] + _75PB50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _75PB50[y] - _75PB50[x] ; + lbe = _75PB50[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_9PB50[x] + _75PB50[x]) * 0.5f) && (hue < (_9PB50[x] + _10PB50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _9PB50[y] - _9PB50[x] ; + lbe = _9PB50[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_10PB50[x] + _9PB50[x]) * 0.5f) && (hue < (_1P50[x] + _10PB50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _10PB50[y] - _10PB50[x] ; + lbe = _10PB50[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_10PB50[x] + _1P50[x]) * 0.5f) && (hue < (_1P50[x] + _4P50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _1P50[y] - _1P50[x] ; + lbe = _1P50[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_1P50[x] + _4P50[x]) * 0.5f) && (hue < (0.035f + _4P50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _4P50[y] - _4P50[x] ; + lbe = _4P50[y]; + correctL = true; + } + } else if (lum < 65.f) { + if (x < 79 && (hue <= (_05PB60[x] + _15PB60[x]) * 0.5f) && (hue > (_05PB60[x] + _10B60[x]) * 0.5f)) { + if (y > 79) { + y = 79; + } + correction = _05PB60[y] - _05PB60[x] ; + lbe = _05PB60[y]; + correctL = true; + } else if (x < 79 && (hue <= (_05PB60[x] + _10B60[x]) * 0.5f) && (hue > (_10B60[x] + _9B60[x]) * 0.5f)) { + if (y > 79) { + y = 79; + } + correction = _10B60[y] - _10B60[x] ; + lbe = _10B60[y]; + correctL = true; + } else if (x < 79 && (hue <= (_10B60[x] + _9B60[x]) * 0.5f) && (hue > (_9B60[x] + _7B60[x]) * 0.5f)) { + if (y > 79) { + y = 79; + } + correction = _9B60[y] - _9B60[x] ; + lbe = _9B60[y]; + correctL = true; + } else if (x < 79 && (hue <= (_9B60[x] + _7B60[x]) * 0.5f) && (hue > (_5B60[x] + _7B60[x]) * 0.5f)) { + if (y > 79) { + y = 79; + } + correction = _7B60[y] - _7B60[x] ; + lbe = _7B60[y]; + correctL = true; + } else if (x < 79 && (hue <= (_5B60[x] + _7B60[x]) * 0.5f) && (hue > (_5B60[x] - 0.035f))) { + if (y > 79) { + y = 79; // + } + correction = _5B60[y] - _5B60[x] ; + lbe = _5B60[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_15PB60[x] - 0.035f)) && (hue < (_15PB60[x] + _3PB60[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _15PB60[y] - _15PB60[x] ; + lbe = _15PB60[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_15PB60[x] + _3PB60[x]) * 0.5f) && (hue < (_45PB60[x] + _3PB60[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _3PB60[y] - _3PB60[x] ; + lbe = _3PB60[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_45PB60[x] + _3PB60[x]) * 0.5f) && (hue < (_6PB60[x] + _45PB60[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _45PB60[y] - _45PB60[x] ; + lbe = _45PB60[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_6PB60[x] + _45PB60[x]) * 0.5f) && (hue < (_6PB60[x] + _75PB60[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _6PB60[y] - _6PB60[x] ; + lbe = _6PB60[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_6PB60[x] + _75PB60[x]) * 0.5f) && (hue < (_9PB60[x] + _75PB60[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _75PB60[y] - _75PB60[x] ; + lbe = _75PB60[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_9PB60[x] + _75PB60[x]) * 0.5f) && (hue < (_9PB60[x] + _10PB60[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _9PB60[y] - _9PB60[x] ; + lbe = _9PB60[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_10PB60[x] + _9PB60[x]) * 0.5f) && (hue < (_1P60[x] + _10PB60[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _10PB60[y] - _10PB60[x] ; + lbe = _10PB60[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_10PB60[x] + _1P60[x]) * 0.5f) && (hue < (_1P60[x] + _4P60[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _1P60[y] - _1P60[x] ; + lbe = _1P60[y]; + correctL = true; + } else if (x <= 85 && (hue >= (_1P60[x] + _4P60[x]) * 0.5f) && (hue < (0.035f + _4P60[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _4P60[y] - _4P60[x] ; + lbe = _4P60[y]; + correctL = true; + } + } else if (lum < 75.f) { + if (x < 50 && (hue <= (_05PB70[x] + _15PB70[x]) * 0.5f) && (hue > (_05PB70[x] + _10B70[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _05PB70[y] - _05PB70[x] ; + lbe = _05PB70[y]; + correctL = true; + } else if (x < 50 && (hue <= (_05PB70[x] + _10B70[x]) * 0.5f) && (hue > (_10B70[x] + _9B70[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _10B70[y] - _10B70[x] ; + lbe = _10B70[y]; + correctL = true; + } else if (x < 50 && (hue <= (_10B70[x] + _9B70[x]) * 0.5f) && (hue > (_9B70[x] + _7B70[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _9B70[y] - _9B70[x] ; + lbe = _9B70[y]; + correctL = true; + } else if (x < 50 && (hue <= (_9B70[x] + _7B70[x]) * 0.5f) && (hue > (_5B70[x] + _7B70[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _7B70[y] - _7B70[x] ; + lbe = _7B70[y]; + correctL = true; + } else if (x < 50 && (hue <= (_5B70[x] + _7B70[x]) * 0.5f) && (hue > (_5B70[x] - 0.035f))) { + if (y > 49) { + y = 49; // + } + correction = _5B70[y] - _5B70[x] ; + lbe = _5B70[y]; + correctL = true; + } else if (x < 50 && (hue >= (_15PB70[x] - 0.035f)) && (hue < (_15PB70[x] + _3PB70[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _15PB70[y] - _15PB70[x] ; + lbe = _15PB70[y]; + correctL = true; + } else if (x < 50 && (hue >= (_45PB70[x] + _3PB70[x]) * 0.5f) && (hue < (_6PB70[x] + _45PB70[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _45PB70[y] - _45PB70[x] ; + lbe = _45PB70[y]; + correctL = true; + } else if (x < 50 && (hue >= (_6PB70[x] + _45PB70[x]) * 0.5f) && (hue < (_6PB70[x] + _75PB70[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _6PB70[y] - _6PB70[x] ; + lbe = _6PB70[y]; + correctL = true; + } else if (x < 50 && (hue >= (_6PB70[x] + _75PB70[x]) * 0.5f) && (hue < (_9PB70[x] + _75PB70[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _75PB70[y] - _75PB70[x] ; + lbe = _75PB70[y]; + correctL = true; + } else if (x < 50 && (hue >= (_9PB70[x] + _75PB70[x]) * 0.5f) && (hue < (_9PB70[x] + 0.035f))) { + if (y > 49) { + y = 49; + } + correction = _9PB70[y] - _9PB70[x] ; + lbe = _9PB70[y]; + correctL = true; + } + } else if (lum < 85.f) { + if (x < 40 && (hue <= (_05PB80[x] + _15PB80[x]) * 0.5f) && (hue > (_05PB80[x] + _10B80[x]) * 0.5f)) { + if (y > 39) { + y = 39; + } + correction = _05PB80[y] - _05PB80[x] ; + lbe = _05PB80[y] ; + correctL = true; + } else if (x < 40 && (hue <= (_05PB80[x] + _10B80[x]) * 0.5f) && (hue > (_10B80[x] + _9B80[x]) * 0.5f)) { + if (y > 39) { + y = 39; + } + correction = _10B80[y] - _10B80[x] ; + lbe = _10B80[y]; + correctL = true; + } else if (x < 40 && (hue <= (_10B80[x] + _9B80[x]) * 0.5f) && (hue > (_9B80[x] + _7B80[x]) * 0.5f)) { + if (y > 39) { + y = 39; + } + correction = _9B80[y] - _9B80[x] ; + lbe = _9B80[y]; + correctL = true; + } else if (x < 50 &&(hue <= (_9B80[x] + _7B80[x]) * 0.5f) && (hue > (_5B80[x] + _7B80[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _7B80[y] - _7B80[x] ; + lbe = _7B80[y]; + correctL = true; + } else if (x < 50 && (hue <= (_5B80[x] + _7B80[x]) * 0.5f) && (hue > (_5B80[x] - 0.035f))) { + if (y > 49) { + y = 49; // + } + correction = _5B80[y] - _5B80[x] ; + lbe = _5B80[y]; + correctL = true; + } else if (x < 50 && (hue >= (_15PB80[x] - 0.035f)) && (hue < (_15PB80[x] + _3PB80[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _15PB80[y] - _15PB80[x] ; + lbe = _15PB80[y]; + correctL = true; + } else if (x < 50 && (hue >= (_45PB80[x] + _3PB80[x]) * 0.5f) && (hue < (_6PB80[x] + _45PB80[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _45PB80[y] - _45PB80[x] ; + lbe = _45PB80[y]; + correctL = true; + } else if (x < 50 && (hue >= (_6PB80[x] + _45PB80[x]) * 0.5f) && (hue < (_6PB80[x] + _75PB80[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _6PB80[y] - _6PB80[x] ; + lbe = _6PB80[y]; + correctL = true; + } else if (x < 50 && (hue >= (_6PB80[x] + _75PB80[x]) * 0.5f) && (hue < (_9PB80[x] + _75PB80[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _75PB80[y] - _75PB80[x] ; + lbe = _75PB80[y]; + correctL = true; + } else if (x < 50 && (hue >= (_9PB80[x] + _75PB80[x]) * 0.5f) && (hue < (_9PB80[x] + 0.035f))) { + if (y > 49) { + y = 49; + } + correction = _9PB80[y] - _9PB80[x] ; + lbe = _9PB80[y]; + correctL = true; + } + } + } + } else if (zone == 2) { //red yellow correction + if (lum > 15.f) { + if (lum < 25.f) { + if (x <= 45 && (hue <= (_10YR20[x] + 0.035f)) && (hue > (_10YR20[x] + _85YR20[x]) * 0.5f)) { + if (y > 49) { + y = 49; + } + correction = _10YR20[y] - _10YR20[x] ; + lbe = _10YR20[y]; + correctL = true; + } else if (x <= 45 && (hue <= (_85YR20[x] + _10YR20[x]) * 0.5f) && (hue > (_85YR20[x] + 0.035f))) { + if (y > 49) { + y = 49; + } + correction = _85YR20[y] - _85YR20[x] ; + lbe = _85YR20[y]; + correctL = true; + } + } else if (lum < 35.f) { + if (x < 85 && (hue <= (_10YR30[x] + 0.035f)) && (hue > (_10YR30[x] + _85YR30[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _10YR30[y] - _10YR30[x] ; + lbe = _10YR30[y]; + correctL = true; + } else if (x < 85 && (hue <= (_10YR30[x] + _85YR30[x]) * 0.5f) && (hue > (_85YR30[x] + _7YR30[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _85YR30[y] - _85YR30[x] ; + lbe = _85YR30[y]; + correctL = true; + } else if (x < 85 && (hue <= (_85YR30[x] + _7YR30[x]) * 0.5f) && (hue > (_7YR30[x] + _55YR30[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _7YR30[y] - _7YR30[x] ; + lbe = _7YR30[y]; + correctL = true; + } else if (x < 85 && (hue <= (_7YR30[x] + _55YR30[x]) * 0.5f) && (hue > (_55YR30[x] + _4YR30[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _55YR30[y] - _55YR30[x] ; + lbe = _55YR30[y]; + correctL = true; + } else if (x < 85 && (hue <= (_55YR30[x] + _4YR30[x]) * 0.5f) && (hue > (_4YR30[x] + _25YR30[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _4YR30[y] - _4YR30[x] ; + lbe = _4YR30[y]; + correctL = true; + } else if (x < 85 && (hue <= (_4YR30[x] + _25YR30[x]) * 0.5f) && (hue > (_25YR30[x] + _10R30[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _25YR30[y] - _25YR30[x] ; + lbe = _25YR30[y]; + correctL = true; + } else if (x < 85 && (hue <= (_25YR30[x] + _10R30[x]) * 0.5f) && (hue > (_10R30[x] + _9R30[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _10R30[y] - _10R30[x] ; + lbe = _10R30[y]; + correctL = true; + } else if (x < 85 && (hue <= (_10R30[x] + _9R30[x]) * 0.5f) && (hue > (_9R30[x] + _7R30[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _9R30[y] - _9R30[x] ; + lbe = _9R30[y]; + correctL = true; + } else if (x < 85 && (hue <= (_9R30[x] + _7R30[x]) * 0.5f) && (hue > (_7R30[x] - 0.035f))) { + if (y > 89) { + y = 89; + } + + correction = _7R30[y] - _7R30[x] ; + lbe = _7R30[y] ; + correctL = true; + } + } else if (lum < 45.f) { + if (x < 85 && (hue <= (_10YR40[x] + 0.035f)) && (hue > (_10YR40[x] + _85YR40[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _10YR40[y] - _10YR40[x] ; + lbe = _10YR40[y]; + correctL = true; + } else if (x < 85 && (hue <= (_10YR40[x] + _85YR40[x]) * 0.5f) && (hue > (_85YR40[x] + _7YR40[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _85YR40[y] - _85YR40[x] ; + lbe = _85YR40[y]; + correctL = true; + } else if (x < 85 && (hue <= (_85YR40[x] + _7YR40[x]) * 0.5f) && (hue > (_7YR40[x] + _55YR40[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _7YR40[y] - _7YR40[x] ; + lbe = _7YR40[y]; + correctL = true; + } else if (x < 85 && (hue <= (_7YR40[x] + _55YR40[x]) * 0.5f) && (hue > (_55YR40[x] + _4YR40[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _55YR40[y] - _55YR40[x] ; + lbe = _55YR40[y]; + correctL = true; + } else if (x < 85 && (hue <= (_55YR40[x] + _4YR40[x]) * 0.5f) && (hue > (_4YR40[x] + _25YR40[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _4YR40[y] - _4YR40[x] ; + lbe = _4YR40[y]; + correctL = true; + } else if (x < 85 && (hue <= (_4YR40[x] + _25YR40[x]) * 0.5f) && (hue > (_25YR40[x] + _10R40[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _25YR40[y] - _25YR40[x] ; + lbe = _25YR40[y] ; + correctL = true; + } else if (x < 85 && (hue <= (_25YR40[x] + _10R40[x]) * 0.5f) && (hue > (_10R40[x] + _9R40[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _10R40[y] - _10R40[x] ; + lbe = _10R40[y]; + correctL = true; + } else if (x < 85 && (hue <= (_10R40[x] + _9R40[x]) * 0.5f) && (hue > (_9R40[x] + _7R40[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _9R40[y] - _9R40[x] ; + lbe = _9R40[y]; + correctL = true; + } else if (x < 85 && (hue <= (_9R40[x] + _7R40[x]) * 0.5f) && (hue > (_7R40[x] - 0.035f))) { + if (y > 89) { + y = 89; + } + correction = _7R40[y] - _7R40[x] ; + lbe = _7R40[y]; + correctL = true; + } + } else if (lum < 55.f) { + if (x < 85 && (hue <= (_10YR50[x] + 0.035f)) && (hue > (_10YR50[x] + _85YR50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _10YR50[y] - _10YR50[x] ; + lbe = _10YR50[y]; + correctL = true; + } else if (x < 85 && (hue <= (_10YR50[x] + _85YR50[x]) * 0.5f) && (hue > (_85YR50[x] + _7YR50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _85YR50[y] - _85YR50[x] ; + lbe = _85YR50[y]; + correctL = true; + } else if (x < 85 && (hue <= (_85YR50[x] + _7YR50[x]) * 0.5f) && (hue > (_7YR50[x] + _55YR50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _7YR50[y] - _7YR50[x] ; + lbe = _7YR50[y]; + correctL = true; + } else if (x < 85 && (hue <= (_7YR50[x] + _55YR50[x]) * 0.5f) && (hue > (_55YR50[x] + _4YR50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _55YR50[y] - _55YR50[x] ; + lbe = _55YR50[y]; + correctL = true; + } else if (x < 85 && (hue <= (_55YR50[x] + _4YR50[x]) * 0.5f) && (hue > (_4YR50[x] + _25YR50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _4YR50[y] - _4YR50[x] ; + lbe = _4YR50[y]; + correctL = true; + } else if (x < 85 && (hue <= (_4YR50[x] + _25YR50[x]) * 0.5f) && (hue > (_25YR50[x] + _10R50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _25YR50[y] - _25YR50[x] ; + lbe = _25YR50[y]; + correctL = true; + } else if (x < 85 && (hue <= (_25YR50[x] + _10R50[x]) * 0.5f) && (hue > (_10R50[x] + _9R50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _10R50[y] - _10R50[x] ; + lbe = _10R50[y]; + correctL = true; + } else if (x < 85 && (hue <= (_10R50[x] + _9R50[x]) * 0.5f) && (hue > (_9R50[x] + _7R50[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _9R50[y] - _9R50[x] ; + lbe = _9R50[y]; + correctL = true; + } else if (x < 85 && (hue <= (_9R50[x] + _7R50[x]) * 0.5f) && (hue > (_7R50[x] - 0.035f))) { + if (y > 89) { + y = 89; + } + correction = _7R50[y] - _7R50[x] ; + lbe = _7R50[y]; + correctL = true; + } + } else if (lum < 65.f) { + if ((hue <= (_10YR60[x] + 0.035f)) && (hue > (_10YR60[x] + _85YR60[x]) * 0.5f)) { + correction = _10YR60[y] - _10YR60[x] ; + lbe = _10YR60[y]; + correctL = true; + } else if ((hue <= (_10YR60[x] + _85YR60[x]) * 0.5f) && (hue > (_85YR60[x] + _7YR60[x]) * 0.5f)) { + correction = _85YR60[y] - _85YR60[x] ; + lbe = _85YR60[y]; + correctL = true; + } else if ((hue <= (_85YR60[x] + _7YR60[x]) * 0.5f) && (hue > (_7YR60[x] + _55YR60[x]) * 0.5f)) { + correction = _7YR60[y] - _7YR60[x] ; + lbe = _7YR60[y]; + correctL = true; + } else if ((hue <= (_7YR60[x] + _55YR60[x]) * 0.5f) && (hue > (_55YR60[x] + _4YR60[x]) * 0.5f)) { + correction = _55YR60[y] - _55YR60[x] ; + lbe = _55YR60[y]; + correctL = true; + } else if ((hue <= (_55YR60[x] + _4YR60[x]) * 0.5f) && (hue > (_4YR60[x] + _25YR60[x]) * 0.5f)) { + correction = _4YR60[y] - _4YR60[x] ; + lbe = _4YR60[y]; + correctL = true; + } else if (x < 85 && (hue <= (_4YR60[x] + _25YR60[x]) * 0.5f) && (hue > (_25YR60[x] + _10R60[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _25YR60[y] - _25YR60[x] ; + lbe = _25YR60[y]; + correctL = true; + } else if (x < 85 && (hue <= (_25YR60[x] + _10R60[x]) * 0.5f) && (hue > (_10R60[x] + _9R60[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _10R60[y] - _10R60[x] ; + lbe = _10R60[y]; + correctL = true; + } else if (x < 85 && (hue <= (_10R60[x] + _9R60[x]) * 0.5f) && (hue > (_9R60[x] + _7R60[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _9R60[y] - _9R60[x] ; + lbe = _9R60[y]; + correctL = true; + } else if (x < 85 && (hue <= (_9R60[x] + _7R60[x]) * 0.5f) && (hue > (_7R60[x] - 0.035f))) { + if (y > 89) { + y = 89; + } + correction = _7R60[y] - _7R60[x] ; + lbe = _7R60[y]; + correctL = true; + } + } else if (lum < 75.f) { + if ((hue <= (_10YR70[x] + 0.035f)) && (hue > (_10YR70[x] + _85YR70[x]) * 0.5f)) { + correction = _10YR70[y] - _10YR70[x] ; + lbe = _10YR70[y]; + correctL = true; + } else if ((hue <= (_10YR70[x] + _85YR70[x]) * 0.5f) && (hue > (_85YR70[x] + _7YR70[x]) * 0.5f)) { + correction = _85YR70[y] - _85YR70[x] ; + lbe = _85YR70[y]; + correctL = true; + } else if ((hue <= (_85YR70[x] + _7YR70[x]) * 0.5f) && (hue > (_7YR70[x] + _55YR70[x]) * 0.5f)) { + correction = _7YR70[y] - _7YR70[x] ; + lbe = _7YR70[y]; + correctL = true; + } else if ((hue <= (_7YR70[x] + _55YR70[x]) * 0.5f) && (hue > (_55YR70[x] + _4YR70[x]) * 0.5f)) { + correction = _55YR70[y] - _55YR70[x] ; + lbe = _55YR70[y]; + correctL = true; + } else if ((hue <= (_55YR70[x] + _4YR70[x]) * 0.5f) && (hue > (_4YR70[x] + _25YR70[x]) * 0.5f)) { + correction = _4YR70[y] - _4YR70[x] ; + lbe = _4YR70[y]; + correctL = true; + } else if (x < 85 && (hue <= (_4YR70[x] + _25YR70[x]) * 0.5f) && (hue > (_25YR70[x] + _10R70[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _25YR70[y] - _25YR70[x] ; + lbe = _25YR70[y]; + correctL = true; + } else if (x < 85 && (hue <= (_25YR70[x] + _10R70[x]) * 0.5f) && (hue > (_10R70[x] + _9R70[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _10R70[y] - _10R70[x] ; + lbe = _10R70[y]; + correctL = true; + } else if (x < 85 && (hue <= (_10R70[x] + _9R70[x]) * 0.5f) && (hue > (_9R70[x] + _7R70[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _9R70[y] - _9R70[x] ; + lbe = _9R70[y] ; + correctL = true; + } else if (x < 85 && (hue <= (_9R70[x] + _7R70[x]) * 0.5f) && (hue > (_7R70[x] - 0.035f))) { + if (y > 89) { + y = 89; + } + correction = _7R70[y] - _7R70[x] ; + lbe = _7R70[y]; + correctL = true; + } + } else if (lum < 85.f) { + if ((hue <= (_10YR80[x] + 0.035f)) && (hue > (_10YR80[x] + _85YR80[x]) * 0.5f)) { + correction = _10YR80[y] - _10YR80[x] ; + lbe = _10YR80[y]; + correctL = true; + } else if ((hue <= (_10YR80[x] + _85YR80[x]) * 0.5f) && (hue > (_85YR80[x] + _7YR80[x]) * 0.5f)) { + correction = _85YR80[y] - _85YR80[x] ; + lbe = _85YR80[y]; + } else if (x < 85 && (hue <= (_85YR80[x] + _7YR80[x]) * 0.5f) && (hue > (_7YR80[x] + _55YR80[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _7YR80[y] - _7YR80[x] ; + lbe = _7YR80[y]; + correctL = true; + } else if (x < 45 && (hue <= (_7YR80[x] + _55YR80[x]) * 0.5f) && (hue > (_55YR80[x] + _4YR80[x]) * 0.5f)) { + correction = _55YR80[y] - _55YR80[x] ; + lbe = _55YR80[y]; + correctL = true; + } else if (x < 45 && (hue <= (_55YR80[x] + _4YR80[x]) * 0.5f) && (hue > (_4YR80[x] - 0.035f))) { + if (y > 49) { + y = 49; + } + correction = _4YR80[y] - _4YR80[x] ; + lbe = _4YR80[y] ; + correctL = true; + } + } else if (lum < 95.f) { + if (x < 85 && (hue <= (_10YR90[x] + 0.035f)) && (hue > (_10YR90[x] - 0.035f))) { + if (y > 89) { + y = 89; + } + correction = _10YR90[y] - _10YR90[x] ; + lbe = _10YR90[y]; + correctL = true; + } else if (x < 85 && hue <= (_85YR90[x] + 0.035f) && hue > (_85YR90[x] - 0.035f)) { + if (y > 89) { + y = 89; + } + correction = _85YR90[y] - _85YR90[x] ; + lbe = _85YR90[y]; + correctL = true; + } else if (x < 45 && (hue <= (_55YR90[x] + 0.035f) && (hue > (_55YR90[x] - 0.035f)))) { + if (y > 49) { + y = 49; + } + correction = _55YR90[y] - _55YR90[x] ; + lbe = _55YR90[y]; + correctL = true; + } + } + } + } else if (zone == 3) { // //Green yellow correction + if (lum >= 25.f) { + if (lum < 35.f) { + if ((hue <= (_7G30[x] + 0.035f)) && (hue > (_7G30[x] + _5G30[x]) * 0.5f)) { + correction = _7G30[y] - _7G30[x] ; + lbe = _7G30[y]; + correctL = true; + } else if ((hue <= (_7G30[x] + _5G30[x]) * 0.5f) && (hue > (_5G30[x] + _25G30[x]) * 0.5f)) { + correction = _5G30[y] - _5G30[x] ; + lbe = _5G30[y]; + correctL = true; + } else if ((hue <= (_25G30[x] + _5G30[x]) * 0.5f) && (hue > (_25G30[x] + _1G30[x]) * 0.5f)) { + correction = _25G30[y] - _25G30[x] ; + lbe = _25G30[y]; + correctL = true; + } else if ((hue <= (_1G30[x] + _25G30[x]) * 0.5f) && (hue > (_1G30[x] + _10GY30[x]) * 0.5f)) { + correction = _1G30[y] - _1G30[x] ; + lbe = _1G30[y]; + correctL = true; + } else if (x < 85 && (hue <= (_1G30[x] + _10GY30[x]) * 0.5f) && (hue > (_10GY30[x] + _75GY30[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _10GY30[y] - _10GY30[x] ; + lbe = _10GY30[y]; + correctL = true; + } else if (x < 85 && (hue <= (_10GY30[x] + _75GY30[x]) * 0.5f) && (hue > (_75GY30[x] + _5GY30[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _75GY30[y] - _75GY30[x] ; + lbe = _75GY30[y]; + correctL = true; + } else if (x < 85 && (hue <= (_5GY30[x] + _75GY30[x]) * 0.5f) && (hue > (_5GY30[x] - 0.035f))) { + if (y > 89) { + y = 89; + } + correction = _5GY30[y] - _5GY30[x] ; + lbe = _5GY30[y] ; + correctL = true; + } + } else if (lum < 45.f) { + if ((hue <= (_7G40[x] + 0.035f)) && (hue > (_7G40[x] + _5G40[x]) * 0.5f)) { + correction = _7G40[y] - _7G40[x] ; + lbe = _7G40[y]; + correctL = true; + } else if ((hue <= (_7G40[x] + _5G40[x]) * 0.5f) && (hue > (_5G40[x] + _25G40[x]) * 0.5f)) { + correction = _5G40[y] - _5G40[x] ; + lbe = _5G40[y]; + correctL = true; + } else if ((hue <= (_25G40[x] + _5G40[x]) * 0.5f) && (hue > (_25G40[x] + _1G40[x]) * 0.5f)) { + correction = _25G40[y] - _25G40[x] ; + lbe = _25G40[y]; + correctL = true; + } else if ((hue <= (_1G40[x] + _25G40[x]) * 0.5f) && (hue > (_1G40[x] + _10GY40[x]) * 0.5f)) { + correction = _1G40[y] - _1G40[x] ; + lbe = _1G40[y]; + correctL = true; + } else if (x < 85 && (hue <= (_1G40[x] + _10GY40[x]) * 0.5f) && (hue > (_10GY40[x] + _75GY40[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _10GY40[y] - _10GY40[x] ; + lbe = _10GY40[y]; + correctL = true; + } else if (x < 85 && (hue <= (_10GY40[x] + _75GY40[x]) * 0.5f) && (hue > (_75GY40[x] + _5GY40[x]) * 0.5f)) { + if (y > 89) { + y = 89; + } + correction = _75GY40[y] - _75GY40[x] ; + lbe = _75GY40[y]; + correctL = true; + } else if (x < 85 && (hue <= (_5GY40[x] + _75GY40[x]) * 0.5f) && (hue > (_5GY40[x] - 0.035f))) { + if (y > 89) { + y = 89; // + } + correction = _5GY40[y] - _5GY40[x] ; + lbe = _5GY40[y]; + correctL = true; + } + } else if (lum < 55.f) { + if ((hue <= (_7G50[x] + 0.035f)) && (hue > (_7G50[x] + _5G50[x]) * 0.5f)) { + correction = _7G50[y] - _7G50[x] ; + lbe = _7G50[y]; + correctL = true; + } else if ((hue <= (_7G50[x] + _5G50[x]) * 0.5f) && (hue > (_5G50[x] + _25G50[x]) * 0.5f)) { + correction = _5G50[y] - _5G50[x] ; + lbe = _5G50[y]; + correctL = true; + } else if ((hue <= (_25G50[x] + _5G50[x]) * 0.5f) && (hue > (_25G50[x] + _1G50[x]) * 0.5f)) { + correction = _25G50[y] - _25G50[x] ; + lbe = _25G50[y]; + correctL = true; + } else if ((hue <= (_1G50[x] + _25G50[x]) * 0.5f) && (hue > (_1G50[x] + _10GY50[x]) * 0.5f)) { + correction = _1G50[y] - _1G50[x] ; + lbe = _1G50[y]; + correctL = true; + } else if ((hue <= (_1G50[x] + _10GY50[x]) * 0.5f) && (hue > (_10GY50[x] + _75GY50[x]) * 0.5f)) { + correction = _10GY50[y] - _10GY50[x] ; + lbe = _10GY50[y]; + correctL = true; + } else if ((hue <= (_10GY50[x] + _75GY50[x]) * 0.5f) && (hue > (_75GY50[x] + _5GY50[x]) * 0.5f)) { + correction = _75GY50[y] - _75GY50[x] ; + lbe = _75GY50[y]; + correctL = true; + } else if ((hue <= (_5GY50[x] + _75GY50[x]) * 0.5f) && (hue > (_5GY50[x] - 0.035f))) { + correction = _5GY50[y] - _5GY50[x] ; + lbe = _5GY50[y]; + correctL = true; + } + } else if (lum < 65.f) { + if ((hue <= (_7G60[x] + 0.035f)) && (hue > (_7G60[x] + _5G60[x]) * 0.5f)) { + correction = _7G60[y] - _7G60[x] ; + lbe = _7G60[y]; + correctL = true; + } else if ((hue <= (_7G60[x] + _5G60[x]) * 0.5f) && (hue > (_5G60[x] + _25G60[x]) * 0.5f)) { + correction = _5G60[y] - _5G60[x] ; + lbe = _5G60[y]; + correctL = true; + } else if ((hue <= (_25G60[x] + _5G60[x]) * 0.5f) && (hue > (_25G60[x] + _1G60[x]) * 0.5f)) { + correction = _25G60[y] - _25G60[x] ; + lbe = _25G60[y]; + correctL = true; + } else if ((hue <= (_1G60[x] + _25G60[x]) * 0.5f) && (hue > (_1G60[x] + _10GY60[x]) * 0.5f)) { + correction = _1G60[y] - _1G60[x] ; + lbe = _1G60[y]; + correctL = true; + } else if ((hue <= (_1G60[x] + _10GY60[x]) * 0.5f) && (hue > (_10GY60[x] + _75GY60[x]) * 0.5f)) { + correction = _10GY60[y] - _10GY60[x] ; + lbe = _10GY60[y]; + correctL = true; + } else if ((hue <= (_10GY60[x] + _75GY60[x]) * 0.5f) && (hue > (_75GY60[x] + _5GY60[x]) * 0.5f)) { + correction = _75GY60[y] - _75GY60[x] ; + lbe = _75GY60[y] ; + correctL = true; + } else if ((hue <= (_5GY60[x] + _75GY60[x]) * 0.5f) && (hue > (_5GY60[x] - 0.035f))) { + correction = _5GY60[y] - _5GY60[x] ; + lbe = _5GY60[y]; + correctL = true; + } + } else if (lum < 75.f) { + if ((hue <= (_7G70[x] + 0.035f)) && (hue > (_7G70[x] + _5G70[x]) * 0.5f)) { + correction = _7G70[y] - _7G70[x] ; + lbe = _7G70[y]; + correctL = true; + } else if ((hue <= (_7G70[x] + _5G70[x]) * 0.5f) && (hue > (_5G70[x] + _25G70[x]) * 0.5f)) { + correction = _5G70[y] - _5G70[x] ; + lbe = _5G70[y]; + correctL = true; + } else if ((hue <= (_25G70[x] + _5G70[x]) * 0.5f) && (hue > (_25G70[x] + _1G70[x]) * 0.5f)) { + correction = _25G70[y] - _25G70[x] ; + lbe = _25G70[y]; + correctL = true; + } else if ((hue <= (_1G70[x] + _25G70[x]) * 0.5f) && (hue > (_1G70[x] + _10GY70[x]) * 0.5f)) { + correction = _1G70[y] - _1G70[x] ; + lbe = _1G70[y] ; + correctL = true; + } else if ((hue <= (_1G70[x] + _10GY70[x]) * 0.5f) && (hue > (_10GY70[x] + _75GY70[x]) * 0.5f)) { + correction = _10GY70[y] - _10GY70[x] ; + lbe = _10GY70[y]; + correctL = true; + } else if ((hue <= (_10GY70[x] + _75GY70[x]) * 0.5f) && (hue > (_75GY70[x] + _5GY70[x]) * 0.5f)) { + correction = _75GY70[y] - _75GY70[x] ; + lbe = _75GY70[y]; + correctL = true; + } else if ((hue <= (_5GY70[x] + _75GY70[x]) * 0.5f) && (hue > (_5GY70[x] - 0.035f))) { + correction = _5GY70[y] - _5GY70[x] ; + lbe = _5GY70[y]; + correctL = true; + } + } else if (lum < 85.f) { + if ((hue <= (_7G80[x] + 0.035f)) && (hue > (_7G80[x] + _5G80[x]) * 0.5f)) { + correction = _7G80[y] - _7G80[x] ; + lbe = _7G80[y]; + correctL = true; + } else if ((hue <= (_7G80[x] + _5G80[x]) * 0.5f) && (hue > (_5G80[x] + _25G80[x]) * 0.5f)) { + correction = _5G80[y] - _5G80[x] ; + lbe = _5G80[y]; + correctL = true; + } else if ((hue <= (_25G80[x] + _5G80[x]) * 0.5f) && (hue > (_25G80[x] + _1G80[x]) * 0.5f)) { + correction = _25G80[y] - _25G80[x] ; + lbe = _25G80[y]; + correctL = true; + } else if ((hue <= (_1G80[x] + _25G80[x]) * 0.5f) && (hue > (_1G80[x] + _10GY80[x]) * 0.5f)) { + correction = _1G80[y] - _1G80[x] ; + lbe = _1G80[y]; + correctL = true; + } else if ((hue <= (_1G80[x] + _10GY80[x]) * 0.5f) && (hue > (_10GY80[x] + _75GY80[x]) * 0.5f)) { + correction = _10GY80[y] - _10GY80[x] ; + lbe = _10GY80[y]; + correctL = true; + } else if ((hue <= (_10GY80[x] + _75GY80[x]) * 0.5f) && (hue > (_75GY80[x] + _5GY80[x]) * 0.5f)) { + correction = _75GY80[y] - _75GY80[x] ; + lbe = _75GY80[y]; + correctL = true; + } else if ((hue <= (_5GY80[x] + _75GY80[x]) * 0.5f) && (hue > (_5GY80[x] - 0.035f))) { + correction = _5GY80[y] - _5GY80[x] ; + lbe = _5GY80[y]; + correctL = true; + } + } + } + } else if (zone == 4) { //Red purple correction : only for L < 30 + if (lum > 5.f) { + if (lum < 15.f && x < 45) { + y = std::min(y, 44); + if ((hue <= (_5R10[x] + 0.035f)) && (hue > (_5R10[x] - 0.043f))) { + correction = _5R10[y] - _5R10[x] ; + lbe = _5R10[y]; + correctL = true; + } else if ((hue <= (_25R10[x] + 0.043f)) && (hue > (_25R10[x] + _10RP10[x]) * 0.5f)) { + correction = _25R10[y] - _25R10[x] ; + lbe = _25R10[y]; + correctL = true; + } else if ((hue <= (_25R10[x] + _10RP10[x]) * 0.5f) && (hue > (_10RP10[x] - 0.035f))) { + correction = _10RP10[y] - _10RP10[x] ; + lbe = _10RP10[y]; + correctL = true; + } + } else if (lum < 25.f && x < 70) { + y = std::min(y, 70); + if ((hue <= (_5R20[x] + 0.035f)) && (hue > (_5R20[x] + _25R20[x]) * 0.5f)) { + correction = _5R20[y] - _5R20[x] ; + lbe = _5R20[y]; + correctL = true; + } else if ((hue <= (_5R20[x] + _25R20[x]) * 0.5f) && (hue > (_10RP20[x] + _25R20[x]) * 0.5f)) { + correction = _25R20[y] - _25R20[x] ; + lbe = _25R20[y]; + correctL = true; + } else if ( (hue <= (_10RP20[x] + _25R20[x]) * 0.5f) && (hue > (_10RP20[x] - 0.035f))) { + correction = _10RP20[y] - _10RP20[x] ; + lbe = _10RP20[y]; + correctL = true; + } + } else if (lum < 35.f && x < 85) { + y = rtengine::min(y, 85); + if ((hue <= (_5R30[x] + 0.035f)) && (hue > (_5R30[x] + _25R30[x]) * 0.5f)) { + correction = _5R30[y] - _5R30[x] ; + lbe = _5R30[y]; + correctL = true; + } else if ((hue <= (_5R30[x] + _25R30[x]) * 0.5f) && (hue > (_10RP30[x] + _25R30[x]) * 0.5f)) { + correction = _25R30[y] - _25R30[x] ; + lbe = _25R30[y]; + correctL = true; + } else if ((hue <= (_10RP30[x] + _25R30[x]) * 0.5f) && (hue > (_10RP30[x] - 0.035f))) { + correction = _10RP30[y] - _10RP30[x] ; + lbe = _10RP30[y]; + correctL = true; + } + } + } + } + //end red purple +} +} diff --git a/rtengine/pdaflinesfilter.cc b/rtengine/pdaflinesfilter.cc index 1eddbc1ea..b5c72f7f4 100644 --- a/rtengine/pdaflinesfilter.cc +++ b/rtengine/pdaflinesfilter.cc @@ -177,7 +177,7 @@ PDAFLinesFilter::PDAFLinesFilter(RawImage *ri): gthresh_ = new PDAFGreenEqulibrateThreshold(W_, H_); CameraConstantsStore* ccs = CameraConstantsStore::getInstance(); - CameraConst *cc = ccs->get(ri_->get_maker().c_str(), ri_->get_model().c_str()); + const CameraConst *cc = ccs->get(ri_->get_maker().c_str(), ri_->get_model().c_str()); if (cc) { pattern_ = cc->get_pdafPattern(); diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 925d90bcc..e41177c29 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1305,9 +1305,12 @@ bool WBParams::operator !=(const WBParams& other) const const std::vector& WBParams::getWbEntries() { + + static const std::vector wb_entries = { {"Camera", WBEntry::Type::CAMERA, M("TP_WBALANCE_CAMERA"), 0, 1.f, 1.f, 0.f}, - {"Auto", WBEntry::Type::AUTO, M("TP_WBALANCE_AUTO"), 0, 1.f, 1.f, 0.f}, + {"autitcgreen", WBEntry::Type::AUTO, M("TP_WBALANCE_AUTOITCGREEN"), 0, 1.f, 1.f, 0.f}, + {"autold", WBEntry::Type::AUTO, M("TP_WBALANCE_AUTOOLD"), 0, 1.f, 1.f, 0.f}, {"Daylight", WBEntry::Type::DAYLIGHT, M("TP_WBALANCE_DAYLIGHT"), 5300, 1.f, 1.f, 0.f}, {"Cloudy", WBEntry::Type::CLOUDY, M("TP_WBALANCE_CLOUDY"), 6200, 1.f, 1.f, 0.f}, {"Shade", WBEntry::Type::SHADE, M("TP_WBALANCE_SHADE"), 7600, 1.f, 1.f, 0.f}, @@ -1341,7 +1344,6 @@ const std::vector& WBParams::getWbEntries() // Should remain the last one {"Custom", WBEntry::Type::CUSTOM, M("TP_WBALANCE_CUSTOM"), 0, 1.f, 1.f, 0.f} }; - return wb_entries; } @@ -1372,6 +1374,7 @@ ColorAppearanceParams::ColorAppearanceParams() : adaplum(16), badpixsl(0), wbmodel("RawT"), + illum("i50"), algo("No"), contrast(0.0), qcontrast(0.0), @@ -1387,10 +1390,12 @@ ColorAppearanceParams::ColorAppearanceParams() : datacie(false), tonecie(false), tempout(5000), + autotempout(true), ybout(18), greenout(1.0), - tempsc(5000), - greensc(1.0) + tempsc(5003), + greensc(1.0), + presetcat02(false) { } @@ -1417,6 +1422,7 @@ bool ColorAppearanceParams::operator ==(const ColorAppearanceParams& other) cons && adaplum == other.adaplum && badpixsl == other.badpixsl && wbmodel == other.wbmodel + && illum == other.illum && algo == other.algo && contrast == other.contrast && qcontrast == other.qcontrast @@ -1432,10 +1438,12 @@ bool ColorAppearanceParams::operator ==(const ColorAppearanceParams& other) cons && datacie == other.datacie && tonecie == other.tonecie && tempout == other.tempout + && autotempout == other.autotempout && ybout == other.ybout && greenout == other.greenout && tempsc == other.tempsc - && greensc == other.greensc; + && greensc == other.greensc + && presetcat02 == other.presetcat02; } bool ColorAppearanceParams::operator !=(const ColorAppearanceParams& other) const @@ -2156,6 +2164,18 @@ WaveletParams::WaveletParams() : 0.35, 0.35 }, + blcurve{ + static_cast(FCT_MinMaxCPoints), +0.0, 0.0, 0.0, 0.35, 0.5, 0., 0.35, 0.35, 1.0, 0.0, 0.35, 0.35 +/* 0.0, + 0.75, + 0.35, + 0.35, + 1.0, + 0.75, + 0.35, + 0.35*/ + }, opacityCurveRG{ static_cast(FCT_MinMaxCPoints), 0.0, @@ -2228,8 +2248,18 @@ WaveletParams::WaveletParams() : bluemed(0), greenhigh(0), bluehigh(0), + ballum(7.), + balchrom(0.), + chromfi(0.), + chromco(0.), + mergeL(40.), + mergeC(20.), + softrad(0.), + softradend(0.), lipst(false), avoid(false), + showmask(false), + oldsh(true), tmr(false), strength(100), balance(0), @@ -2239,10 +2269,12 @@ WaveletParams::WaveletParams() : c{}, ch{}, expedge(false), + expbl(false), expresid(false), expfinal(false), exptoning(false), expnoise(false), + expclari(false), Lmethod(4), CLmethod("all"), Backmethod("grey"), @@ -2250,6 +2282,7 @@ WaveletParams::WaveletParams() : daubcoeffmethod("4_"), CHmethod("without"), Medgreinf("less"), + ushamethod("clari"), CHSLmethod("SL"), EDmethod("CU"), NPmethod("none"), @@ -2257,10 +2290,17 @@ WaveletParams::WaveletParams() : TMmethod("cont"), Dirmethod("all"), HSmethod("with"), + sigma(1.0), + offset(1.0), + lowthr(40.0), rescon(0), resconH(0), reschro(0), + resblur(0), + resblurc(0), tmrs(0), + edgs(1.4), + scale(1.), gamma(1), sup(0), sky(0.0), @@ -2276,11 +2316,15 @@ WaveletParams::WaveletParams() : edgeampli(10), contrast(0), edgrad(15), + edgeffect(1.0), edgval(0), edgthresh(10), - thr(35), - thrH(65), + thr(30), + thrH(70), + radius(40), skinprotect(0.0), + chrwav(0.), + bluwav(1.0), hueskin(-5, 25, 170, 120, false), hueskin2(-260, -250, -130, -140, false), hllev(50, 75, 100, 98, false), @@ -2299,6 +2343,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const { return ccwcurve == other.ccwcurve + && blcurve == other.blcurve && opacityCurveRG == other.opacityCurveRG && opacityCurveBY == other.opacityCurveBY && opacityCurveW == other.opacityCurveW @@ -2317,8 +2362,18 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && bluemed == other.bluemed && greenhigh == other.greenhigh && bluehigh == other.bluehigh + && ballum == other.ballum + && balchrom == other.balchrom + && chromfi == other.chromfi + && chromco == other.chromco + && mergeL == other.mergeL + && mergeC == other.mergeC + && softrad == other.softrad + && softradend == other.softradend && lipst == other.lipst && avoid == other.avoid + && showmask == other.showmask + && oldsh == other.oldsh && tmr == other.tmr && strength == other.strength && balance == other.balance @@ -2336,8 +2391,10 @@ bool WaveletParams::operator ==(const WaveletParams& other) const return true; }() && expedge == other.expedge + && expbl == other.expbl && expresid == other.expresid && expfinal == other.expfinal + && expclari == other.expclari && exptoning == other.exptoning && expnoise == other.expnoise && Lmethod == other.Lmethod @@ -2347,6 +2404,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && daubcoeffmethod == other.daubcoeffmethod && CHmethod == other.CHmethod && Medgreinf == other.Medgreinf + && ushamethod == other.ushamethod && CHSLmethod == other.CHSLmethod && EDmethod == other.EDmethod && NPmethod == other.NPmethod @@ -2354,10 +2412,17 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && TMmethod == other.TMmethod && Dirmethod == other.Dirmethod && HSmethod == other.HSmethod + && sigma == other.sigma + && offset == other.offset + && lowthr == other.lowthr && rescon == other.rescon && resconH == other.resconH && reschro == other.reschro + && resblur == other.resblur + && resblurc == other.resblurc && tmrs == other.tmrs + && edgs == other.edgs + && scale == other.scale && gamma == other.gamma && sup == other.sup && sky == other.sky @@ -2373,11 +2438,15 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && edgeampli == other.edgeampli && contrast == other.contrast && edgrad == other.edgrad + && edgeffect == other.edgeffect && edgval == other.edgval && edgthresh == other.edgthresh && thr == other.thr && thrH == other.thrH + && radius == other.radius && skinprotect == other.skinprotect + && chrwav == other.chrwav + && bluwav == other.bluwav && hueskin == other.hueskin && hueskin2 == other.hueskin2 && hllev == other.hllev @@ -2398,6 +2467,7 @@ bool WaveletParams::operator !=(const WaveletParams& other) const void WaveletParams::getCurves( WavCurve& cCurve, + Wavblcurve& tCurve, WavOpacityCurveRG& opacityCurveLUTRG, WavOpacityCurveBY& opacityCurveLUTBY, WavOpacityCurveW& opacityCurveLUTW, @@ -2405,6 +2475,7 @@ void WaveletParams::getCurves( ) const { cCurve.Set(this->ccwcurve); + tCurve.Set(this->blcurve); opacityCurveLUTRG.Set(this->opacityCurveRG); opacityCurveLUTBY.Set(this->opacityCurveBY); opacityCurveLUTW.Set(this->opacityCurveW); @@ -3731,7 +3802,10 @@ FilmNegativeParams::FilmNegativeParams() : enabled(false), redRatio(1.36), greenExp(1.5), - blueRatio(0.86) + blueRatio(0.86), + redBase(0), + greenBase(0), + blueBase(0) { } @@ -3739,9 +3813,12 @@ bool FilmNegativeParams::operator ==(const FilmNegativeParams& other) const { return enabled == other.enabled - && redRatio == other.redRatio + && redRatio == other.redRatio && greenExp == other.greenExp - && blueRatio == other.blueRatio; + && blueRatio == other.blueRatio + && redBase == other.redBase + && greenBase == other.greenBase + && blueBase == other.blueBase; } bool FilmNegativeParams::operator !=(const FilmNegativeParams& other) const @@ -4099,6 +4176,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->colorappearance.adaplum, "Color appearance", "AdaptLum", colorappearance.adaplum, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.badpixsl, "Color appearance", "Badpixsl", colorappearance.badpixsl, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.wbmodel, "Color appearance", "Model", colorappearance.wbmodel, keyFile); + saveToKeyfile(!pedited || pedited->colorappearance.illum, "Color appearance", "Illum", colorappearance.illum, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.algo, "Color appearance", "Algorithm", colorappearance.algo, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.jlight, "Color appearance", "J-Light", colorappearance.jlight, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.qbright, "Color appearance", "Q-Bright", colorappearance.qbright, keyFile); @@ -4116,12 +4194,14 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->colorappearance.surrsource, "Color appearance", "SurrSource", colorappearance.surrsource, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.gamut, "Color appearance", "Gamut", colorappearance.gamut, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.tempout, "Color appearance", "Tempout", colorappearance.tempout, keyFile); + saveToKeyfile(!pedited || pedited->colorappearance.autotempout, "Color appearance", "Autotempout", colorappearance.autotempout, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.greenout, "Color appearance", "Greenout", colorappearance.greenout, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.tempsc, "Color appearance", "Tempsc", colorappearance.tempsc, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.greensc, "Color appearance", "Greensc", colorappearance.greensc, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.ybout, "Color appearance", "Ybout", colorappearance.ybout, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.datacie, "Color appearance", "Datacie", colorappearance.datacie, keyFile); saveToKeyfile(!pedited || pedited->colorappearance.tonecie, "Color appearance", "Tonecie", colorappearance.tonecie, keyFile); + saveToKeyfile(!pedited || pedited->colorappearance.presetcat02, "Color appearance", "Presetcat02", colorappearance.presetcat02, keyFile); const std::map ca_mapping = { {ColorAppearanceParams::TcMode::LIGHT, "Lightness"}, @@ -4820,13 +4900,23 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.bluehigh, "Wavelet", "CBbluehigh", wavelet.bluehigh, keyFile); saveToKeyfile(!pedited || pedited->wavelet.bluemed, "Wavelet", "CBbluemed", wavelet.bluemed, keyFile); saveToKeyfile(!pedited || pedited->wavelet.bluelow, "Wavelet", "CBbluelow", wavelet.bluelow, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.ballum, "Wavelet", "Ballum", wavelet.ballum, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.balchrom, "Wavelet", "Balchrom", wavelet.balchrom, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.chromfi, "Wavelet", "Chromfine", wavelet.chromfi, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.chromco, "Wavelet", "Chromcoarse", wavelet.chromco, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.mergeL, "Wavelet", "MergeL", wavelet.mergeL, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.mergeC, "Wavelet", "MergeC", wavelet.mergeC, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.softrad, "Wavelet", "Softrad", wavelet.softrad, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.softradend, "Wavelet", "Softradend", wavelet.softradend, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expcontrast, "Wavelet", "Expcontrast", wavelet.expcontrast, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expchroma, "Wavelet", "Expchroma", wavelet.expchroma, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expedge, "Wavelet", "Expedge", wavelet.expedge, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.expbl, "Wavelet", "expbl", wavelet.expbl, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expresid, "Wavelet", "Expresid", wavelet.expresid, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expfinal, "Wavelet", "Expfinal", wavelet.expfinal, keyFile); saveToKeyfile(!pedited || pedited->wavelet.exptoning, "Wavelet", "Exptoning", wavelet.exptoning, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expnoise, "Wavelet", "Expnoise", wavelet.expnoise, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.expclari, "Wavelet", "Expclari", wavelet.expclari, keyFile); for (int i = 0; i < 9; i++) { std::stringstream ss; @@ -4861,6 +4951,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.chroma, "Wavelet", "ThresholdChroma", wavelet.chroma, keyFile); saveToKeyfile(!pedited || pedited->wavelet.CHmethod, "Wavelet", "CHromaMethod", wavelet.CHmethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.Medgreinf, "Wavelet", "Medgreinf", wavelet.Medgreinf, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.ushamethod, "Wavelet", "Ushamethod", wavelet.ushamethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.CHSLmethod, "Wavelet", "CHSLromaMethod", wavelet.CHSLmethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.EDmethod, "Wavelet", "EDMethod", wavelet.EDmethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.NPmethod, "Wavelet", "NPMethod", wavelet.NPmethod, keyFile); @@ -4868,6 +4959,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.TMmethod, "Wavelet", "TMMethod", wavelet.TMmethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.chro, "Wavelet", "ChromaLink", wavelet.chro, keyFile); saveToKeyfile(!pedited || pedited->wavelet.ccwcurve, "Wavelet", "ContrastCurve", wavelet.ccwcurve, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.blcurve, "Wavelet", "blcurve", wavelet.blcurve, keyFile); saveToKeyfile(!pedited || pedited->wavelet.pastlev, "Wavelet", "Pastlev", wavelet.pastlev.toVector(), keyFile); saveToKeyfile(!pedited || pedited->wavelet.satlev, "Wavelet", "Satlev", wavelet.satlev.toVector(), keyFile); saveToKeyfile(!pedited || pedited->wavelet.opacityCurveRG, "Wavelet", "OpacityCurveRG", wavelet.opacityCurveRG, keyFile); @@ -4883,18 +4975,31 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.cbenab, "Wavelet", "CBenab", wavelet.cbenab, keyFile); saveToKeyfile(!pedited || pedited->wavelet.lipst, "Wavelet", "Lipst", wavelet.lipst, keyFile); saveToKeyfile(!pedited || pedited->wavelet.skinprotect, "Wavelet", "Skinprotect", wavelet.skinprotect, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.chrwav, "Wavelet", "chrwav", wavelet.chrwav, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.bluwav, "Wavelet", "bluwav", wavelet.bluwav, keyFile); saveToKeyfile(!pedited || pedited->wavelet.hueskin, "Wavelet", "Hueskin", wavelet.hueskin.toVector(), keyFile); saveToKeyfile(!pedited || pedited->wavelet.edgrad, "Wavelet", "Edgrad", wavelet.edgrad, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.edgeffect, "Wavelet", "Edgeffect", wavelet.edgeffect, keyFile); saveToKeyfile(!pedited || pedited->wavelet.edgval, "Wavelet", "Edgval", wavelet.edgval, keyFile); saveToKeyfile(!pedited || pedited->wavelet.edgthresh, "Wavelet", "ThrEdg", wavelet.edgthresh, keyFile); saveToKeyfile(!pedited || pedited->wavelet.avoid, "Wavelet", "AvoidColorShift", wavelet.avoid, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.showmask, "Wavelet", "Showmask", wavelet.showmask, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.oldsh, "Wavelet", "Oldsh", wavelet.oldsh, keyFile); saveToKeyfile(!pedited || pedited->wavelet.tmr, "Wavelet", "TMr", wavelet.tmr, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.sigma, "Wavelet", "Sigma", wavelet.sigma, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.offset, "Wavelet", "Offset", wavelet.offset, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.lowthr, "Wavelet", "Lowthr", wavelet.lowthr, keyFile); saveToKeyfile(!pedited || pedited->wavelet.rescon, "Wavelet", "ResidualcontShadow", wavelet.rescon, keyFile); saveToKeyfile(!pedited || pedited->wavelet.resconH, "Wavelet", "ResidualcontHighlight", wavelet.resconH, keyFile); saveToKeyfile(!pedited || pedited->wavelet.thr, "Wavelet", "ThresholdResidShadow", wavelet.thr, keyFile); saveToKeyfile(!pedited || pedited->wavelet.thrH, "Wavelet", "ThresholdResidHighLight", wavelet.thrH, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.radius, "Wavelet", "Residualradius", wavelet.radius, keyFile); saveToKeyfile(!pedited || pedited->wavelet.reschro, "Wavelet", "Residualchroma", wavelet.reschro, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.resblur, "Wavelet", "Residualblur", wavelet.resblur, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.resblurc, "Wavelet", "Residualblurc", wavelet.resblurc, keyFile); saveToKeyfile(!pedited || pedited->wavelet.tmrs, "Wavelet", "ResidualTM", wavelet.tmrs, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.edgs, "Wavelet", "ResidualEDGS", wavelet.edgs, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.scale, "Wavelet", "ResidualSCALE", wavelet.scale, keyFile); saveToKeyfile(!pedited || pedited->wavelet.gamma, "Wavelet", "Residualgamma", wavelet.gamma, keyFile); saveToKeyfile(!pedited || pedited->wavelet.sky, "Wavelet", "HueRangeResidual", wavelet.sky, keyFile); saveToKeyfile(!pedited || pedited->wavelet.hueskin2, "Wavelet", "HueRange", wavelet.hueskin2.toVector(), keyFile); @@ -5056,6 +5161,9 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->filmNegative.redRatio, "Film Negative", "RedRatio", filmNegative.redRatio, keyFile); saveToKeyfile(!pedited || pedited->filmNegative.greenExp, "Film Negative", "GreenExponent", filmNegative.greenExp, keyFile); saveToKeyfile(!pedited || pedited->filmNegative.blueRatio, "Film Negative", "BlueRatio", filmNegative.blueRatio, keyFile); + saveToKeyfile(!pedited || pedited->filmNegative.baseValues, "Film Negative", "RedBase", filmNegative.redBase, keyFile); + saveToKeyfile(!pedited || pedited->filmNegative.baseValues, "Film Negative", "GreenBase", filmNegative.greenBase, keyFile); + saveToKeyfile(!pedited || pedited->filmNegative.baseValues, "Film Negative", "BlueBase", filmNegative.blueBase, keyFile); // EXIF change list if (!pedited || pedited->exif) { @@ -5492,10 +5600,12 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Vibrance", "PastSatTog", pedited, vibrance.pastsattog, pedited->vibrance.pastsattog); assignFromKeyfile(keyFile, "Vibrance", "SkinTonesCurve", pedited, vibrance.skintonescurve, pedited->vibrance.skintonescurve); } - if (keyFile.has_group("White Balance")) { assignFromKeyfile(keyFile, "White Balance", "Enabled", pedited, wb.enabled, pedited->wb.enabled); assignFromKeyfile(keyFile, "White Balance", "Setting", pedited, wb.method, pedited->wb.method); + if (wb.method == "Auto") { + wb.method = "autold"; + } assignFromKeyfile(keyFile, "White Balance", "Temperature", pedited, wb.temperature, pedited->wb.temperature); assignFromKeyfile(keyFile, "White Balance", "Green", pedited, wb.green, pedited->wb.green); assignFromKeyfile(keyFile, "White Balance", "Equal", pedited, wb.equal, pedited->wb.equal); @@ -5534,6 +5644,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Color appearance", "AdaptLum", pedited, colorappearance.adaplum, pedited->colorappearance.adaplum); assignFromKeyfile(keyFile, "Color appearance", "Badpixsl", pedited, colorappearance.badpixsl, pedited->colorappearance.badpixsl); assignFromKeyfile(keyFile, "Color appearance", "Model", pedited, colorappearance.wbmodel, pedited->colorappearance.wbmodel); + assignFromKeyfile(keyFile, "Color appearance", "Illum", pedited, colorappearance.illum, pedited->colorappearance.illum); assignFromKeyfile(keyFile, "Color appearance", "Algorithm", pedited, colorappearance.algo, pedited->colorappearance.algo); assignFromKeyfile(keyFile, "Color appearance", "J-Light", pedited, colorappearance.jlight, pedited->colorappearance.jlight); assignFromKeyfile(keyFile, "Color appearance", "Q-Bright", pedited, colorappearance.qbright, pedited->colorappearance.qbright); @@ -5551,12 +5662,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Color appearance", "SurrSource", pedited, colorappearance.surrsource, pedited->colorappearance.surrsource); assignFromKeyfile(keyFile, "Color appearance", "Gamut", pedited, colorappearance.gamut, pedited->colorappearance.gamut); assignFromKeyfile(keyFile, "Color appearance", "Tempout", pedited, colorappearance.tempout, pedited->colorappearance.tempout); + assignFromKeyfile(keyFile, "Color appearance", "Autotempout", pedited, colorappearance.autotempout, pedited->colorappearance.autotempout); assignFromKeyfile(keyFile, "Color appearance", "Greenout", pedited, colorappearance.greenout, pedited->colorappearance.greenout); assignFromKeyfile(keyFile, "Color appearance", "Tempsc", pedited, colorappearance.tempsc, pedited->colorappearance.tempsc); assignFromKeyfile(keyFile, "Color appearance", "Greensc", pedited, colorappearance.greensc, pedited->colorappearance.greensc); assignFromKeyfile(keyFile, "Color appearance", "Ybout", pedited, colorappearance.ybout, pedited->colorappearance.ybout); assignFromKeyfile(keyFile, "Color appearance", "Datacie", pedited, colorappearance.datacie, pedited->colorappearance.datacie); assignFromKeyfile(keyFile, "Color appearance", "Tonecie", pedited, colorappearance.tonecie, pedited->colorappearance.tonecie); + assignFromKeyfile(keyFile, "Color appearance", "Presetcat02", pedited, colorappearance.presetcat02, pedited->colorappearance.presetcat02); const std::map tc_mapping = { {"Lightness", ColorAppearanceParams::TcMode::LIGHT}, @@ -5657,7 +5770,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_key("Shadows & Highlights", "LocalContrast") && ppVersion < 329) { int lc = keyFile.get_integer("Shadows & Highlights", "LocalContrast"); - localContrast.amount = float(lc) / 30.; + localContrast.amount = float(lc) / 30.f; if (pedited) { pedited->localContrast.amount = true; @@ -6516,16 +6629,27 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "CBbluehigh", pedited, wavelet.bluehigh, pedited->wavelet.bluehigh); assignFromKeyfile(keyFile, "Wavelet", "CBbluemed", pedited, wavelet.bluemed, pedited->wavelet.bluemed); assignFromKeyfile(keyFile, "Wavelet", "CBbluelow", pedited, wavelet.bluelow, pedited->wavelet.bluelow); + assignFromKeyfile(keyFile, "Wavelet", "Ballum", pedited, wavelet.ballum, pedited->wavelet.ballum); + assignFromKeyfile(keyFile, "Wavelet", "Balchrom", pedited, wavelet.balchrom, pedited->wavelet.balchrom); + assignFromKeyfile(keyFile, "Wavelet", "Chromfine", pedited, wavelet.chromfi, pedited->wavelet.chromfi); + assignFromKeyfile(keyFile, "Wavelet", "Chromcoarse", pedited, wavelet.chromco, pedited->wavelet.chromco); + assignFromKeyfile(keyFile, "Wavelet", "MergeL", pedited, wavelet.mergeL, pedited->wavelet.mergeL); + assignFromKeyfile(keyFile, "Wavelet", "MergeC", pedited, wavelet.mergeC, pedited->wavelet.mergeC); + assignFromKeyfile(keyFile, "Wavelet", "Softrad", pedited, wavelet.softrad, pedited->wavelet.softrad); + assignFromKeyfile(keyFile, "Wavelet", "Softradend", pedited, wavelet.softradend, pedited->wavelet.softradend); assignFromKeyfile(keyFile, "Wavelet", "Lipst", pedited, wavelet.lipst, pedited->wavelet.lipst); assignFromKeyfile(keyFile, "Wavelet", "AvoidColorShift", pedited, wavelet.avoid, pedited->wavelet.avoid); + assignFromKeyfile(keyFile, "Wavelet", "Showmask", pedited, wavelet.showmask, pedited->wavelet.showmask); + assignFromKeyfile(keyFile, "Wavelet", "Oldsh", pedited, wavelet.oldsh, pedited->wavelet.oldsh); assignFromKeyfile(keyFile, "Wavelet", "TMr", pedited, wavelet.tmr, pedited->wavelet.tmr); if (ppVersion < 331) { // wavelet.Lmethod was a string before version 331 Glib::ustring temp; assignFromKeyfile(keyFile, "Wavelet", "LevMethod", pedited, temp, pedited->wavelet.Lmethod); - if (!temp.empty()) { + try { wavelet.Lmethod = std::stoi(temp); + } catch (...) { } } else { assignFromKeyfile(keyFile, "Wavelet", "LevMethod", pedited, wavelet.Lmethod, pedited->wavelet.Lmethod); @@ -6537,6 +6661,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "DaubMethod", pedited, wavelet.daubcoeffmethod, pedited->wavelet.daubcoeffmethod); assignFromKeyfile(keyFile, "Wavelet", "CHromaMethod", pedited, wavelet.CHmethod, pedited->wavelet.CHmethod); assignFromKeyfile(keyFile, "Wavelet", "Medgreinf", pedited, wavelet.Medgreinf, pedited->wavelet.Medgreinf); + assignFromKeyfile(keyFile, "Wavelet", "Ushamethod", pedited, wavelet.ushamethod, pedited->wavelet.ushamethod); assignFromKeyfile(keyFile, "Wavelet", "CHSLromaMethod", pedited, wavelet.CHSLmethod, pedited->wavelet.CHSLmethod); assignFromKeyfile(keyFile, "Wavelet", "EDMethod", pedited, wavelet.EDmethod, pedited->wavelet.EDmethod); assignFromKeyfile(keyFile, "Wavelet", "NPMethod", pedited, wavelet.NPmethod, pedited->wavelet.NPmethod); @@ -6544,10 +6669,17 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "TMMethod", pedited, wavelet.TMmethod, pedited->wavelet.TMmethod); assignFromKeyfile(keyFile, "Wavelet", "HSMethod", pedited, wavelet.HSmethod, pedited->wavelet.HSmethod); assignFromKeyfile(keyFile, "Wavelet", "DirMethod", pedited, wavelet.Dirmethod, pedited->wavelet.Dirmethod); + assignFromKeyfile(keyFile, "Wavelet", "Sigma", pedited, wavelet.sigma, pedited->wavelet.sigma); + assignFromKeyfile(keyFile, "Wavelet", "Offset", pedited, wavelet.offset, pedited->wavelet.offset); + assignFromKeyfile(keyFile, "Wavelet", "Lowthr", pedited, wavelet.lowthr, pedited->wavelet.lowthr); assignFromKeyfile(keyFile, "Wavelet", "ResidualcontShadow", pedited, wavelet.rescon, pedited->wavelet.rescon); assignFromKeyfile(keyFile, "Wavelet", "ResidualcontHighlight", pedited, wavelet.resconH, pedited->wavelet.resconH); assignFromKeyfile(keyFile, "Wavelet", "Residualchroma", pedited, wavelet.reschro, pedited->wavelet.reschro); + assignFromKeyfile(keyFile, "Wavelet", "Residualblur", pedited, wavelet.resblur, pedited->wavelet.resblur); + assignFromKeyfile(keyFile, "Wavelet", "Residualblurc", pedited, wavelet.resblurc, pedited->wavelet.resblurc); assignFromKeyfile(keyFile, "Wavelet", "ResidualTM", pedited, wavelet.tmrs, pedited->wavelet.tmrs); + assignFromKeyfile(keyFile, "Wavelet", "ResidualEDGS", pedited, wavelet.edgs, pedited->wavelet.edgs); + assignFromKeyfile(keyFile, "Wavelet", "ResidualSCALE", pedited, wavelet.scale, pedited->wavelet.scale); assignFromKeyfile(keyFile, "Wavelet", "Residualgamma", pedited, wavelet.gamma, pedited->wavelet.gamma); assignFromKeyfile(keyFile, "Wavelet", "ContExtra", pedited, wavelet.sup, pedited->wavelet.sup); assignFromKeyfile(keyFile, "Wavelet", "HueRangeResidual", pedited, wavelet.sky, pedited->wavelet.sky); @@ -6563,11 +6695,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "ChromaLink", pedited, wavelet.chro, pedited->wavelet.chro); assignFromKeyfile(keyFile, "Wavelet", "Contrast", pedited, wavelet.contrast, pedited->wavelet.contrast); assignFromKeyfile(keyFile, "Wavelet", "Edgrad", pedited, wavelet.edgrad, pedited->wavelet.edgrad); + assignFromKeyfile(keyFile, "Wavelet", "Edgeffect", pedited, wavelet.edgeffect, pedited->wavelet.edgeffect); assignFromKeyfile(keyFile, "Wavelet", "Edgval", pedited, wavelet.edgval, pedited->wavelet.edgval); assignFromKeyfile(keyFile, "Wavelet", "ThrEdg", pedited, wavelet.edgthresh, pedited->wavelet.edgthresh); assignFromKeyfile(keyFile, "Wavelet", "ThresholdResidShadow", pedited, wavelet.thr, pedited->wavelet.thr); assignFromKeyfile(keyFile, "Wavelet", "ThresholdResidHighLight", pedited, wavelet.thrH, pedited->wavelet.thrH); + assignFromKeyfile(keyFile, "Wavelet", "Residualradius", pedited, wavelet.radius, pedited->wavelet.radius); assignFromKeyfile(keyFile, "Wavelet", "ContrastCurve", pedited, wavelet.ccwcurve, pedited->wavelet.ccwcurve); + assignFromKeyfile(keyFile, "Wavelet", "blcurve", pedited, wavelet.blcurve, pedited->wavelet.blcurve); assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveRG", pedited, wavelet.opacityCurveRG, pedited->wavelet.opacityCurveRG); assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveBY", pedited, wavelet.opacityCurveBY, pedited->wavelet.opacityCurveBY); assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveW", pedited, wavelet.opacityCurveW, pedited->wavelet.opacityCurveW); @@ -6709,6 +6844,8 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } assignFromKeyfile(keyFile, "Wavelet", "Skinprotect", pedited, wavelet.skinprotect, pedited->wavelet.skinprotect); + assignFromKeyfile(keyFile, "Wavelet", "chrwav", pedited, wavelet.chrwav, pedited->wavelet.chrwav); + assignFromKeyfile(keyFile, "Wavelet", "bluwav", pedited, wavelet.bluwav, pedited->wavelet.bluwav); assignFromKeyfile(keyFile, "Wavelet", "Expcontrast", pedited, wavelet.expcontrast, pedited->wavelet.expcontrast); assignFromKeyfile(keyFile, "Wavelet", "Expchroma", pedited, wavelet.expchroma, pedited->wavelet.expchroma); @@ -6739,10 +6876,12 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } assignFromKeyfile(keyFile, "Wavelet", "Expedge", pedited, wavelet.expedge, pedited->wavelet.expedge); + assignFromKeyfile(keyFile, "Wavelet", "expbl", pedited, wavelet.expbl, pedited->wavelet.expbl); assignFromKeyfile(keyFile, "Wavelet", "Expresid", pedited, wavelet.expresid, pedited->wavelet.expresid); assignFromKeyfile(keyFile, "Wavelet", "Expfinal", pedited, wavelet.expfinal, pedited->wavelet.expfinal); assignFromKeyfile(keyFile, "Wavelet", "Exptoning", pedited, wavelet.exptoning, pedited->wavelet.exptoning); assignFromKeyfile(keyFile, "Wavelet", "Expnoise", pedited, wavelet.expnoise, pedited->wavelet.expnoise); + assignFromKeyfile(keyFile, "Wavelet", "Expclari", pedited, wavelet.expclari, pedited->wavelet.expclari); } if (keyFile.has_group("Directional Pyramid Equalizer")) { @@ -7178,6 +7317,24 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Film Negative", "RedRatio", pedited, filmNegative.redRatio, pedited->filmNegative.redRatio); assignFromKeyfile(keyFile, "Film Negative", "GreenExponent", pedited, filmNegative.greenExp, pedited->filmNegative.greenExp); assignFromKeyfile(keyFile, "Film Negative", "BlueRatio", pedited, filmNegative.blueRatio, pedited->filmNegative.blueRatio); + if (ppVersion >= 347) { + bool r, g, b; + assignFromKeyfile(keyFile, "Film Negative", "RedBase", pedited, filmNegative.redBase, r); + assignFromKeyfile(keyFile, "Film Negative", "GreenBase", pedited, filmNegative.greenBase, g); + assignFromKeyfile(keyFile, "Film Negative", "BlueBase", pedited, filmNegative.blueBase, b); + if (pedited) { + pedited->filmNegative.baseValues = r || g || b; + } + } else { + // Backwards compatibility with film negative in RT 5.7: use special film base value -1, + // to signal that the old channel scaling method should be used. + filmNegative.redBase = -1.f; + filmNegative.greenBase = -1.f; + filmNegative.blueBase = -1.f; + if (pedited) { + pedited->filmNegative.baseValues = true; + } + } } if (keyFile.has_group("MetaData")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 5a61eb2d0..f0f285c71 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -40,6 +40,7 @@ class OpacityCurve; class RetinexgaintransmissionCurve; class RetinextransmissionCurve; class WavCurve; +class Wavblcurve; class WavOpacityCurveBY; class WavOpacityCurveRG; class WavOpacityCurveW; @@ -680,6 +681,7 @@ struct ColorAppearanceParams { double adaplum; int badpixsl; Glib::ustring wbmodel; + Glib::ustring illum; Glib::ustring algo; double contrast; double qcontrast; @@ -695,10 +697,12 @@ struct ColorAppearanceParams { bool datacie; bool tonecie; int tempout; + bool autotempout; int ybout; double greenout; int tempsc; double greensc; + bool presetcat02; ColorAppearanceParams(); @@ -1654,6 +1658,7 @@ private: struct WaveletParams { std::vector ccwcurve; + std::vector blcurve; std::vector opacityCurveRG; std::vector opacityCurveBY; std::vector opacityCurveW; @@ -1672,9 +1677,19 @@ struct WaveletParams { int bluemed; int greenhigh; int bluehigh; + double ballum; + double balchrom; + double chromfi; + double chromco; + double mergeL; + double mergeC; + double softrad; + double softradend; bool lipst; bool avoid; + bool showmask; + bool oldsh; bool tmr; int strength; int balance; @@ -1684,10 +1699,12 @@ struct WaveletParams { int c[9]; int ch[9]; bool expedge; + bool expbl; bool expresid; bool expfinal; bool exptoning; bool expnoise; + bool expclari; int Lmethod; Glib::ustring CLmethod; @@ -1696,6 +1713,7 @@ struct WaveletParams { Glib::ustring daubcoeffmethod; Glib::ustring CHmethod; Glib::ustring Medgreinf; + Glib::ustring ushamethod; Glib::ustring CHSLmethod; Glib::ustring EDmethod; Glib::ustring NPmethod; @@ -1703,10 +1721,17 @@ struct WaveletParams { Glib::ustring TMmethod; Glib::ustring Dirmethod; Glib::ustring HSmethod; + double sigma; + double offset; + double lowthr; int rescon; int resconH; int reschro; + int resblur; + int resblurc; double tmrs; + double edgs; + double scale; double gamma; int sup; double sky; @@ -1722,11 +1747,15 @@ struct WaveletParams { int edgeampli; int contrast; int edgrad; + double edgeffect; int edgval; int edgthresh; int thr; int thrH; + int radius; double skinprotect; + double chrwav; + double bluwav; Threshold hueskin; Threshold hueskin2; Threshold hllev; @@ -1746,6 +1775,7 @@ struct WaveletParams { void getCurves( WavCurve& cCurve, + Wavblcurve& tCurve, WavOpacityCurveRG& opacityCurveLUTRG, WavOpacityCurveBY& opacityCurveLUTBY, @@ -2001,6 +2031,10 @@ struct FilmNegativeParams { double greenExp; double blueRatio; + double redBase; + double greenBase; + double blueBase; + FilmNegativeParams(); bool operator ==(const FilmNegativeParams& other) const; diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index dc44307aa..cad0d7f4f 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -173,7 +173,7 @@ void RawImage::get_colorsCoeff(float *pre_mul_, float *scale_mul_, float *cblack } for (int c = 0; c < 4; c++) { - dsumthr[c] += sum[c]; + dsumthr[c] += static_cast(sum[c]); } skip_block2: @@ -197,7 +197,7 @@ skip_block2: } for (int c = 0; c < 4; c++) { - dsum[c] -= cblack_[c] * dsum[c + 4]; + dsum[c] -= static_cast(cblack_[c]) * dsum[c + 4]; } } else if (isXtrans()) { @@ -243,7 +243,7 @@ skip_block2: } for (int c = 0; c < 8; c++) { - dsumthr[c] += sum[c]; + dsumthr[c] += static_cast(sum[c]); } skip_block3: @@ -366,18 +366,14 @@ skip_block: } for (dmin = DBL_MAX, dmax = c = 0; c < 4; c++) { - if (dmin > pre_mul_[c]) { - dmin = pre_mul_[c]; - } - - if (dmax < pre_mul_[c]) { - dmax = pre_mul_[c]; - } + dmin = rtengine::min(dmin, pre_mul_[c]); + dmax = rtengine::max(dmax, pre_mul_[c]); } for (c = 0; c < 4; c++) { int sat = this->get_white(c) - cblack_[c]; - scale_mul_[c] = (pre_mul_[c] /= dmax) * 65535.0 / sat; + pre_mul_[c] /= static_cast(dmax); + scale_mul_[c] = pre_mul_[c] * 65535.f / sat; } if (settings->verbose) { @@ -388,25 +384,30 @@ skip_block: asn[c] = 0; } - if (asn[c] > dmax) { + if (asn[c] > static_cast(dmax)) { dmax = asn[c]; } } for (c = 0; c < 4; c++) { - asn[c] /= dmax; + asn[c] /= static_cast(dmax); } 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(cam_mul[0]), static_cast(cam_mul[1]), + static_cast(cam_mul[2]), static_cast(cam_mul[3]), + static_cast(asn[0]), static_cast(asn[1]), static_cast(asn[2]), static_cast(asn[3])); 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], - scale_mul_[0], scale_mul_[1], scale_mul_[2], scale_mul_[3], - cblack_[0], cblack_[1], cblack_[2], cblack_[3]); + static_cast(pre_mul_[0]), static_cast(pre_mul_[1]), + static_cast(pre_mul_[2]), static_cast(pre_mul_[3]), + static_cast(scale_mul_[0]), static_cast(scale_mul_[1]), + static_cast(scale_mul_[2]), static_cast(scale_mul_[3]), + static_cast(cblack_[0]), static_cast(cblack_[1]), + static_cast(cblack_[2]), static_cast(cblack_[3])); 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], - rgb_cam[0][1], rgb_cam[1][1], rgb_cam[2][1], - rgb_cam[0][2], rgb_cam[1][2], rgb_cam[2][2], + static_cast(rgb_cam[0][0]), static_cast(rgb_cam[1][0]), static_cast(rgb_cam[2][0]), + static_cast(rgb_cam[0][1]), static_cast(rgb_cam[1][1]), static_cast(rgb_cam[2][1]), + static_cast(rgb_cam[0][2]), static_cast(rgb_cam[1][2]), static_cast(rgb_cam[2][2]), (!this->isBayer()) ? " (not bayer)" : ""); } @@ -524,7 +525,7 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog } CameraConstantsStore* ccs = CameraConstantsStore::getInstance(); - CameraConst *cc = ccs->get(make, model); + const CameraConst *cc = ccs->get(make, model); if (raw_image) { if (cc && cc->has_rawCrop()) { @@ -852,42 +853,18 @@ DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int is short trans[12]; // set first value to 0 for no change } table[] = { - { - "Canon EOS 5D Mark III", -1, 0x3a98, /* RT */ - { 6722, -635, -963, -4287, 12460, 2028, -908, 2162, 5668 } - }, { "Canon EOS 5D", -1, 0xe6c, /* RT */ { 6319, -793, -614, -5809, 13342, 2738, -1132, 1559, 7971 } }, - { - "Canon EOS 6D", -1, 0x3c82, - { 7034, -804, -1014, -4420, 12564, 2058, -851, 1994, 5758 } - }, - { - "Canon EOS 7D", -1, 0x3510, /* RT - Colin Walker */ - { 5962, -171, -732, -4189, 12307, 2099, -911, 1981, 6304 } - }, { "Canon EOS 20D", -1, 0xfff, /* RT */ { 7590, -1646, -673, -4697, 12411, 2568, -627, 1118, 7295 } }, - { - "Canon EOS 40D", -1, 0x3f60, /* RT */ - { 6070, -531, -883, -5763, 13647, 2315, -1533, 2582, 6801 } - }, - { - "Canon EOS 60D", -1, 0x2ff7, /* RT - Colin Walker */ - { 5678, -179, -718, -4389, 12381, 2243, -869, 1819, 6380 } - }, { "Canon EOS 450D", -1, 0x390d, /* RT */ { 6246, -1272, -523, -5075, 12357, 3075, -1035, 1825, 7333 } }, - { - "Canon EOS 550D", -1, 0x3dd7, /* RT - Lebedev*/ - { 6519, -772, -703, -4994, 12737, 2519, -1387, 2492, 6175 } - }, { "Canon EOS-1D Mark III", 0, 0x3bb0, /* RT */ { 7406, -1592, -646, -4856, 12457, 2698, -432, 726, 7921 } @@ -896,18 +873,10 @@ DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int is "Canon PowerShot G10", -1, -1, /* RT */ { 12535, -5030, -796, -2711, 10134, 3006, -413, 1605, 5264 } }, - { - "Canon PowerShot G12", -1, -1, /* RT */ - { 12222, -4097, -1380, -2876, 11016, 2130, -888, 1630, 4434 } - }, - - { "Fujifilm X100", -1, -1, /* RT - Colin Walker */ { 10841, -3288, -807, -4652, 12552, 2344, -642, 1355, 7206 } }, - - { "Nikon D200", -1, 0xfbc, /* RT */ { 8498, -2633, -295, -5423, 12869, 2860, -777, 1077, 8124 } @@ -920,32 +889,14 @@ DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int is "Nikon D3100", -1, -1, /* RT */ { 7729, -2212, -481, -5709, 13148, 2858, -1295, 1908, 8936 } }, - { - "Nikon D3S", -1, -1, /* RT */ - { 8792, -2663, -344, -5221, 12764, 2752, -1491, 2165, 8121 } - }, { "Nikon D5200", -1, -1, // color matrix copied from D5200 DNG D65 matrix { 8322, -3112, -1047, -6367, 14342, 2179, -988, 1638, 6394 } }, - { - "Nikon D7000", -1, -1, /* RT - Tanveer(tsk1979) */ - { 7530, -1942, -255, -4318, 11390, 3362, -926, 1694, 7649 } - }, { "Nikon D7100", -1, -1, // color matrix and WP copied from D7100 DNG D65 matrix { 8322, -3112, -1047, -6367, 14342, 2179, -988, 1638, 6394 } }, - { - "Nikon D700", -1, -1, /* RT */ - { 8364, -2503, -352, -6307, 14026, 2492, -1134, 1512, 8156 } - }, - { - "Nikon COOLPIX A", -1, 0x3e00, // color matrix and WP copied from "COOLPIX A" DNG D65 matrix - { 8198, -2239, -724, -4871, 12389, 2798, -1043, 205, 7181 } - }, - - { "Olympus E-30", -1, 0xfbc, /* RT - Colin Walker */ { 8510, -2355, -693, -4819, 12520, 2578, -1029, 2067, 7752 } @@ -986,69 +937,14 @@ DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int is "Olympus XZ-1", -1, -1, /* RT - Colin Walker */ { 8665, -2247, -762, -2424, 10372, 2382, -1011, 2286, 5189 } }, - - - /* since Dcraw_v9.21 Panasonic BlackLevel is read from exif (tags 0x001c BlackLevelRed, 0x001d BlackLevelGreen, 0x001e BlackLevelBlue - and we define here the needed offset of around 15. The total BL is BL + BLoffset (cblack + black) */ - - { - "Panasonic DMC-FZ150", 15, 0xfd2, /* RT */ - { 10435, -3208, -72, -2293, 10506, 2067, -486, 1725, 4682 } - }, - { - "Panasonic DMC-G10", 15, 0xf50, /* RT - Colin Walker - variable WL 3920 - 4080 */ - { 8310, -1811, -960, -4941, 12990, 2151, -1378, 2468, 6860 } - }, - { - "Panasonic DMC-G1", 15, 0xf50, /* RT - Colin Walker - variable WL 3920 - 4080 */ - { 7477, -1615, -651, -5016, 12769, 2506, -1380, 2475, 7240 } - }, - { - "Panasonic DMC-G2", 15, 0xf50, /* RT - Colin Walker - variable WL 3920 - 4080 */ - { 8310, -1811, -960, -4941, 12990, 2151, -1378, 2468, 6860 } - }, - { - "Panasonic DMC-G3", 15, 0xfdc, /* RT - Colin Walker - WL 4060 */ - { 6051, -1406, -671, -4015, 11505, 2868, -1654, 2667, 6219 } - }, - { - "Panasonic DMC-G5", 15, 0xfdc, /* RT - WL 4060 */ - { 7122, -2092, -419, -4643, 11769, 3283, -1363, 2413, 5944 } - }, - { - "Panasonic DMC-GF1", 15, 0xf50, /* RT - Colin Walker - Variable WL 3920 - 4080 */ - { 7863, -2080, -668, -4623, 12331, 2578, -1020, 2066, 7266 } - }, - { - "Panasonic DMC-GF2", 15, 0xfd2, /* RT - Colin Walker - WL 4050 */ - { 7694, -1791, -745, -4917, 12818, 2332, -1221, 2322, 7197 } - }, - { - "Panasonic DMC-GF3", 15, 0xfd2, /* RT - Colin Walker - WL 4050 */ - { 8074, -1846, -861, -5026, 12999, 2239, -1320, 2375, 7422 } - }, - { - "Panasonic DMC-GH1", 15, 0xf5a, /* RT - Colin Walker - variable WL 3930 - 4080 */ - { 6360, -1557, -375, -4201, 11504, 3086, -1378, 2518, 5843 } - }, - { - "Panasonic DMC-GH2", 15, 0xf5a, /* RT - Colin Walker - variable WL 3930 - 4080 */ -// { 6855,-1765,-456,-4223,11600,2996,-1450,2602,5761 } }, disabled due to problems with underwater WB - { 7780, -2410, -806, -3913, 11724, 2484, -1018, 2390, 5298 } - }, // dcraw original - { "Pentax K200D", -1, -1, /* RT */ { 10962, -4428, -542, -5486, 13023, 2748, -569, 842, 8390 } }, - - { "Leica Camera AG M9 Digital Camera", -1, -1, /* RT */ { 7181, -1706, -55, -3557, 11409, 2450, -621, 2072, 7533 } }, - - { "SONY NEX-3", 128 << dcraw_arw2_scaling_bugfix_shift, -1, /* RT - Colin Walker */ { 5145, -741, -123, -4915, 12310, 2945, -794, 1489, 6906 } @@ -1106,7 +1002,7 @@ DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int is { // test if we have any information in the camera constants store, if so we take that. rtengine::CameraConstantsStore* ccs = rtengine::CameraConstantsStore::getInstance(); - rtengine::CameraConst *cc = ccs->get(make, model); + const rtengine::CameraConst *cc = ccs->get(make, model); if (cc) { if (RT_blacklevel_from_constant == ThreeValBool::T) { diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index fa23fb9ca..75088a07c 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -17,6 +17,7 @@ * along with RawTherapee. If not, see . */ #include +#include #include #include "camconst.h" @@ -25,6 +26,7 @@ #include "dcp.h" #include "dfmanager.h" #include "ffmanager.h" +#include "iccmatrices.h" #include "iccstore.h" #include "imagefloat.h" #include "improcfun.h" @@ -41,7 +43,7 @@ #include "rtlensfun.h" #include "../rtgui/options.h" -//#define BENCHMARK +#define BENCHMARK #include "StopWatch.h" #ifdef _OPENMP @@ -53,9 +55,9 @@ namespace { -void rotateLine(const float* const line, rtengine::PlanarPtr &channel, const int tran, const int i, const int w, const int h) +void rotateLine (const float* const line, rtengine::PlanarPtr &channel, const int tran, const int i, const int w, const int h) { - switch (tran & TR_ROT) { + switch(tran & TR_ROT) { case TR_R180: for (int j = 0; j < w; j++) { channel(h - 1 - i, w - 1 - j) = line[j]; @@ -85,24 +87,24 @@ void rotateLine(const float* const line, rtengine::PlanarPtr &channel, co } } -void transLineStandard(const float* const red, const float* const green, const float* const blue, const int i, rtengine::Imagefloat* const image, const int tran, const int imwidth, const int imheight) +void transLineStandard (const float* const red, const float* const green, const float* const blue, const int i, rtengine::Imagefloat* const image, const int tran, const int imwidth, const int imheight) { // conventional CCD coarse rotation - rotateLine(red, image->r, tran, i, imwidth, imheight); - rotateLine(green, image->g, tran, i, imwidth, imheight); - rotateLine(blue, image->b, tran, i, imwidth, imheight); + rotateLine (red, image->r, tran, i, imwidth, imheight); + rotateLine (green, image->g, tran, i, imwidth, imheight); + rotateLine (blue, image->b, tran, i, imwidth, imheight); } -void transLineFuji(const float* const red, const float* const green, const float* const blue, const int i, rtengine::Imagefloat* const image, const int tran, const int imheight, const int fw) +void transLineFuji (const float* const red, const float* const green, const float* const blue, const int i, rtengine::Imagefloat* const image, const int tran, const int imheight, const int fw) { // Fuji SuperCCD rotation + coarse rotation - int start = ABS(fw - i); + int start = std::abs(fw - i); int w = fw * 2 + 1; int h = (imheight - fw) * 2 + 1; int end = min(h + fw - i, w - fw + i); - switch (tran & TR_ROT) { + switch(tran & TR_ROT) { case TR_R180: for (int j = start; j < end; j++) { int y = i + j - fw; @@ -167,7 +169,7 @@ void transLineD1x (const float* const red, const float* const green, const float // We have to do vertical interpolation for the 'missing' rows // We do that in combination with coarse rotation - switch (tran & TR_ROT) { + switch(tran & TR_ROT) { case TR_R180: // rotate 180 degree for (int j = 0; j < imwidth; j++) { image->r(2 * (imheight - 1 - i), imwidth - 1 - j) = red[j]; @@ -194,7 +196,7 @@ void transLineD1x (const float* const red, const float* const green, const float } if (i == 2 && oddHeight) { - int row = 2 * imheight; + row = 2 * imheight; for (int j = 0; j < imwidth; j++) { int col = imwidth - 1 - j; @@ -230,7 +232,7 @@ void transLineD1x (const float* const red, const float* const green, const float image->g(row, col) = MAX(0.f, -0.0625f * (green[j] + image->g(row + 3, col)) + 0.5625f * (image->g(row - 1, col) + image->g(row + 1, col))); image->b(row, col) = MAX(0.f, -0.0625f * (blue[j] + image->b(row + 3, col)) + 0.5625f * (image->b(row - 1, col) + image->b(row + 1, col))); - if(clip) { + if (clip) { image->r(row, col) = MIN(image->r(row, col), rtengine::MAXVALF); image->g(row, col) = MIN(image->g(row, col), rtengine::MAXVALF); image->b(row, col) = MIN(image->b(row, col), rtengine::MAXVALF); @@ -293,7 +295,7 @@ void transLineD1x (const float* const red, const float* const green, const float image->g(j, col) = MAX(0.f, -0.0625f * (green[j] + image->g(j, col + 3)) + 0.5625f * (image->g(j, col - 1) + image->g(j, col + 1))); image->b(j, col) = MAX(0.f, -0.0625f * (blue[j] + image->b(j, col + 3)) + 0.5625f * (image->b(j, col - 1) + image->b(j, col + 1))); - if(clip) { + if (clip) { image->r(j, col) = MIN(image->r(j, col), rtengine::MAXVALF); image->g(j, col) = MIN(image->g(j, col), rtengine::MAXVALF); image->b(j, col) = MIN(image->b(j, col), rtengine::MAXVALF); @@ -325,7 +327,7 @@ void transLineD1x (const float* const red, const float* const green, const float image->g(row, 2 * i - 3) = MAX(0.f, -0.0625f * (green[j] + image->g(row, 2 * i - 6)) + 0.5625f * (image->g(row, 2 * i - 2) + image->g(row, 2 * i - 4))); image->b(row, 2 * i - 3) = MAX(0.f, -0.0625f * (blue[j] + image->b(row, 2 * i - 6)) + 0.5625f * (image->b(row, 2 * i - 2) + image->b(row, 2 * i - 4))); - if(clip) { + if (clip) { image->r(row, 2 * i - 3) = MIN(image->r(row, 2 * i - 3), rtengine::MAXVALF); image->g(row, 2 * i - 3) = MIN(image->g(row, 2 * i - 3), rtengine::MAXVALF); image->b(row, 2 * i - 3) = MIN(image->b(row, 2 * i - 3), rtengine::MAXVALF); @@ -343,7 +345,7 @@ void transLineD1x (const float* const red, const float* const green, const float image->g(row, 2 * i - 1) = MAX(0.f, -0.0625f * (green[j] + image->g(row, 2 * i - 4)) + 0.5625f * (image->g(row, 2 * i) + image->g(row, 2 * i - 2))); image->b(row, 2 * i - 1) = MAX(0.f, -0.0625f * (blue[j] + image->b(row, 2 * i - 4)) + 0.5625f * (image->b(row, 2 * i) + image->b(row, 2 * i - 2))); - if(clip) { + if (clip) { image->r(j, 2 * i - 1) = MIN(image->r(j, 2 * i - 1), rtengine::MAXVALF); image->g(j, 2 * i - 1) = MIN(image->g(j, 2 * i - 1), rtengine::MAXVALF); image->b(j, 2 * i - 1) = MIN(image->b(j, 2 * i - 1), rtengine::MAXVALF); @@ -365,9 +367,9 @@ void transLineD1x (const float* const red, const float* const green, const float case TR_NONE: // no coarse rotation default: - rotateLine(red, image->r, tran, 2 * i, imwidth, imheight); - rotateLine(green, image->g, tran, 2 * i, imwidth, imheight); - rotateLine(blue, image->b, tran, 2 * i, imwidth, imheight); + rotateLine (red, image->r, tran, 2 * i, imwidth, imheight); + rotateLine (green, image->g, tran, 2 * i, imwidth, imheight); + rotateLine (blue, image->b, tran, 2 * i, imwidth, imheight); if (i == 1 || i == 2) { // linear interpolation for (int j = 0; j < imwidth; j++) { @@ -381,7 +383,7 @@ void transLineD1x (const float* const red, const float* const green, const float image->g(2 * i - 3, j) = MAX(0.f, -0.0625f * (green[j] + image->g(2 * i - 6, j)) + 0.5625f * (image->g(2 * i - 2, j) + image->g(2 * i - 4, j))); image->b(2 * i - 3, j) = MAX(0.f, -0.0625f * (blue[j] + image->b(2 * i - 6, j)) + 0.5625f * (image->b(2 * i - 2, j) + image->b(2 * i - 4, j))); - if(clip) { + if (clip) { image->r(2 * i - 3, j) = MIN(image->r(2 * i - 3, j), rtengine::MAXVALF); image->g(2 * i - 3, j) = MIN(image->g(2 * i - 3, j), rtengine::MAXVALF); image->b(2 * i - 3, j) = MIN(image->b(2 * i - 3, j), rtengine::MAXVALF); @@ -395,7 +397,7 @@ void transLineD1x (const float* const red, const float* const green, const float image->g(2 * i - 1, j) = MAX(0.f, -0.0625f * (green[j] + image->g(2 * i - 4, j)) + 0.5625f * (image->g(2 * i, j) + image->g(2 * i - 2, j))); image->b(2 * i - 1, j) = MAX(0.f, -0.0625f * (blue[j] + image->b(2 * i - 4, j)) + 0.5625f * (image->b(2 * i, j) + image->b(2 * i - 2, j))); - if(clip) { + if (clip) { image->r(2 * i - 1, j) = MIN(image->r(2 * i - 1, j), rtengine::MAXVALF); image->g(2 * i - 1, j) = MIN(image->g(2 * i - 1, j), rtengine::MAXVALF); image->b(2 * i - 1, j) = MIN(image->b(2 * i - 1, j), rtengine::MAXVALF); @@ -421,11 +423,7 @@ void transLineD1x (const float* const red, const float* const green, const float namespace rtengine { -#undef ABS - -#define ABS(a) ((a)<0?-(a):(a)) - -RawImageSource::RawImageSource() +RawImageSource::RawImageSource () : ImageSource() , W(0), H(0) , plistener(nullptr) @@ -450,21 +448,23 @@ RawImageSource::RawImageSource() , initialGain(0.0) , camInitialGain(0.0) , defGain(0.0) + , camProfile(nullptr) , ri(nullptr) , rawData(0, 0) , green(0, 0) + , greenloc(0, 0) , red(0, 0) + , redloc(0, 0) , blue(0, 0) + , blueloc(0, 0) , greenCache(nullptr) , redCache(nullptr) , blueCache(nullptr) , rawDirty(true) , histMatchingParams(new procparams::ColorManagementParams) { - camProfile = nullptr; embProfile = nullptr; rgbSourceModified = false; - for (int i = 0; i < 4; ++i) { psRedBrightness[i] = psGreenBrightness[i] = psBlueBrightness[i] = 1.f; } @@ -472,7 +472,7 @@ RawImageSource::RawImageSource() //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -RawImageSource::~RawImageSource() +RawImageSource::~RawImageSource () { delete idata; @@ -484,19 +484,16 @@ RawImageSource::~RawImageSource() delete riFrames[i]; } - for(size_t i = 0; i + 1 < numFrames; ++i) { + for (size_t i = 0; i + 1 < numFrames; ++i) { delete rawDataBuffer[i]; } - flushRGB(); - flushRawData(); - if (camProfile) { - cmsCloseProfile(camProfile); + cmsCloseProfile (camProfile); } if (embProfile) { - cmsCloseProfile(embProfile); + cmsCloseProfile (embProfile); } } @@ -522,7 +519,7 @@ int RawImageSource::getRotateDegree() const //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::transformRect(const PreviewProps &pp, int tran, int &ssx1, int &ssy1, int &width, int &height, int &fw) +void RawImageSource::transformRect (const PreviewProps &pp, int tran, int &ssx1, int &ssy1, int &width, int &height, int &fw) { int pp_x = pp.getX() + border; int pp_y = pp.getY() + border; @@ -600,13 +597,13 @@ void RawImageSource::transformRect(const PreviewProps &pp, int tran, int &ssx1, ssy1 = (sy1 - sx2) / 2 + ri->get_FujiWidth(); int ssx2 = (sx2 + sy2) / 2 + 1; int ssy2 = (sy2 - sx1) / 2 + ri->get_FujiWidth(); - fw = (sx2 - sx1) / 2 / pp.getSkip(); - width = (ssx2 - ssx1) / pp.getSkip() + ((ssx2 - ssx1) % pp.getSkip() > 0); + fw = (sx2 - sx1) / 2 / pp.getSkip(); + width = (ssx2 - ssx1) / pp.getSkip() + ((ssx2 - ssx1) % pp.getSkip() > 0); height = (ssy2 - ssy1) / pp.getSkip() + ((ssy2 - ssy1) % pp.getSkip() > 0); } else { ssx1 = sx1; ssy1 = sy1; - width = (sx2 + 1 - sx1) / pp.getSkip() + ((sx2 + 1 - sx1) % pp.getSkip() > 0); + width = (sx2 + 1 - sx1) / pp.getSkip() + ((sx2 + 1 - sx1) % pp.getSkip() > 0); height = (sy2 + 1 - sy1) / pp.getSkip() + ((sy2 + 1 - sy1) % pp.getSkip() > 0); } } @@ -615,7 +612,7 @@ float calculate_scale_mul(float scale_mul[4], const float pre_mul_[4], const flo { if (isMono || colors == 1) { 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 { float pre_mul[4]; @@ -631,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]); 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]); } } @@ -639,11 +636,11 @@ float calculate_scale_mul(float scale_mul[4], const float pre_mul_[4], const flo return gain; } -void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw) +void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw) { MyMutex::MyLock lock(getImageMutex); - tran = defTransform(tran); + tran = defTransform (tran); // compute channel multipliers double r, g, b; @@ -655,7 +652,7 @@ void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* imag gm = ri->get_pre_mul(1); bm = ri->get_pre_mul(2); } else { - ctemp.getMultipliers(r, g, b); + ctemp.getMultipliers (r, g, b); rm = imatrices.cam_rgb[0][0] * r + imatrices.cam_rgb[0][1] * g + imatrices.cam_rgb[0][2] * b; gm = imatrices.cam_rgb[1][0] * r + imatrices.cam_rgb[1][1] * g + imatrices.cam_rgb[1][2] * b; bm = imatrices.cam_rgb[2][0] * r + imatrices.cam_rgb[2][1] * g + imatrices.cam_rgb[2][2] * b; @@ -670,7 +667,7 @@ void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* imag || (ri->getSensorType() == ST_BAYER && raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)); 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(raw.expos) + cblacksom[i]; } float gain = calculate_scale_mul(new_scale_mul, new_pre_mul, c_white, cblacksom, isMono, ri->get_colors()); @@ -679,27 +676,27 @@ void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* imag 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)); } else { - // 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 - rm = refwb_red / rm; - gm = refwb_green / gm; - bm = refwb_blue / bm; - // normalize so larger multiplier becomes 1.0 - float minval = min(rm, gm, bm); - rm /= minval; - gm /= minval; - bm /= minval; - // multiply with reference gain, ie as-shot WB - rm *= camInitialGain; - gm *= camInitialGain; - bm *= camInitialGain; +// // 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 +// rm = refwb_red / rm; +// gm = refwb_green / gm; +// bm = refwb_blue / bm; +// // normalize so larger multiplier becomes 1.0 +// float minval = min(rm, gm, bm); +// rm /= minval; +// gm /= minval; +// bm /= minval; +// // multiply with reference gain, ie as-shot WB +// rm *= camInitialGain; +// gm *= camInitialGain; +// bm *= camInitialGain; } defGain = 0.0; // compute image area to render in order to provide the requested part of the image int sx1, sy1, imwidth, imheight, fw, d1xHeightOdd = 0; - transformRect(pp, tran, sx1, sy1, imwidth, imheight, fw); + transformRect (pp, tran, sx1, sy1, imwidth, imheight, fw); // check possible overflows int maximwidth, maximheight; @@ -841,15 +838,15 @@ void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* imag //process all highlight recovery other than "Color" if (doHr) { - hlRecovery(hrp.method, line_red, line_grn, line_blue, imwidth, hlmax); + hlRecovery (hrp.method, line_red, line_grn, line_blue, imwidth, hlmax); } if (d1x) { transLineD1x (line_red, line_grn, line_blue, ix, image, tran, imwidth, imheight, d1xHeightOdd, doClip); } else if (fuji) { - transLineFuji(line_red, line_grn, line_blue, ix, image, tran, imheight, fw); + transLineFuji (line_red, line_grn, line_blue, ix, image, tran, imheight, fw); } else { - transLineStandard(line_red, line_grn, line_blue, ix, image, tran, imwidth, imheight); + transLineStandard (line_red, line_grn, line_blue, ix, image, tran, imwidth, imheight); } } @@ -872,13 +869,13 @@ void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* imag for (int i = 1; i < image->getHeight() - 1; i++) { for (int j = 2 - (a + i + 1) % 2; j < image->getWidth() - 1; j += 2) { // 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; - 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; - double eh = 1.0 / (1.0 + dh); - double ev = 1.0 / (1.0 + 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->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->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)); + 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))); + 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))); + float eh = 1.f / (1.f + dh); + 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.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.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.f * (eh + ev)); } // first pixel @@ -897,9 +894,9 @@ void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* imag } // last row - int b = (a == 1 && image->getHeight() % 2) || (a == 0 && image->getHeight() % 2 == 0); + int offset = (a == 1 && image->getHeight() % 2) || (a == 0 && image->getHeight() % 2 == 0); - for (int j = 1 + b; j < image->getWidth() - 1; j += 2) { + for (int j = 1 + offset; j < image->getWidth() - 1; j += 2) { image->r(image->getHeight() - 1, j) = (image->r(image->getHeight() - 2, j) + image->r(image->getHeight() - 1, j + 1) + image->r(image->getHeight() - 1, j - 1)) / 3; image->g(image->getHeight() - 1, j) = (image->g(image->getHeight() - 2, j) + image->g(image->getHeight() - 1, j + 1) + image->g(image->getHeight() - 1, j - 1)) / 3; image->b(image->getHeight() - 1, j) = (image->b(image->getHeight() - 2, j) + image->b(image->getHeight() - 1, j + 1) + image->b(image->getHeight() - 1, j - 1)) / 3; @@ -908,22 +905,22 @@ void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* imag // Flip if needed if (tran & TR_HFLIP) { - hflip(image); + hflip (image); } if (tran & TR_VFLIP) { - vflip(image); + vflip (image); } // Colour correction (only when running on full resolution) if (pp.getSkip() == 1) { - switch (ri->getSensorType()) { + switch(ri->getSensorType()) { case ST_BAYER: - processFalseColorCorrection(image, raw.bayersensor.ccSteps); + processFalseColorCorrection (image, raw.bayersensor.ccSteps); break; case ST_FUJI_XTRANS: - processFalseColorCorrection(image, raw.xtranssensor.ccSteps); + processFalseColorCorrection (image, raw.xtranssensor.ccSteps); break; case ST_FOVEON: @@ -947,7 +944,6 @@ DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, DCPProfileA if (settings->verbose) { printf("Can't load DCP profile '%s'!\n", cmp.inputProfile.c_str()); } - return nullptr; } @@ -958,13 +954,13 @@ DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, DCPProfileA void RawImageSource::convertColorSpace(Imagefloat* image, const ColorManagementParams &cmp, const ColorTemp &wb) { double pre_mul[3] = { ri->get_pre_mul(0), ri->get_pre_mul(1), ri->get_pre_mul(2) }; - colorSpaceConversion(image, cmp, wb, pre_mul, embProfile, camProfile, imatrices.xyz_cam, (static_cast(getMetaData()))->getCamera()); + colorSpaceConversion (image, cmp, wb, pre_mul, embProfile, camProfile, imatrices.xyz_cam, (static_cast(getMetaData()))->getCamera()); } -void RawImageSource::getFullSize(int& w, int& h, int tr) +void RawImageSource::getFullSize (int& w, int& h, int tr) { - tr = defTransform(tr); + tr = defTransform (tr); if (fuji) { w = ri->get_FujiWidth() * 2 + 1; @@ -989,7 +985,7 @@ void RawImageSource::getFullSize(int& w, int& h, int tr) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::getSize(const PreviewProps &pp, int& w, int& h) +void RawImageSource::getSize (const PreviewProps &pp, int& w, int& h) { w = pp.getWidth() / pp.getSkip() + (pp.getWidth() % pp.getSkip() > 0); h = pp.getHeight() / pp.getSkip() + (pp.getHeight() % pp.getSkip() > 0); @@ -997,14 +993,14 @@ void RawImageSource::getSize(const PreviewProps &pp, int& w, int& h) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::hflip(Imagefloat* image) +void RawImageSource::hflip (Imagefloat* image) { image->hflip(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::vflip(Imagefloat* image) +void RawImageSource::vflip (Imagefloat* image) { image->vflip(); } @@ -1021,11 +1017,10 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) if (plistener) { plistener->setProgressStr ("PROGRESSBAR_DECODING"); - plistener->setProgress(0.0); + plistener->setProgress (0.0); } - ri = new RawImage(fname); - int errCode = ri->loadRaw(false, 0, false); + int errCode = ri->loadRaw (false, 0, false); if (errCode) { return errCode; @@ -1034,7 +1029,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) errCode = 0; - if(numFrames >= 7) { + if (numFrames >= 7) { // special case to avoid crash when loading Hasselblad H6D-100cMS pixelshift files // limit to 6 frames and skip first frame, as first frame is not bayer if (firstFrameOnly) { @@ -1050,8 +1045,8 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) #ifdef _OPENMP #pragma omp for nowait #endif - for(unsigned int i = 0; i < numFrames; ++i) { - if(i == 0) { + for (unsigned int i = 0; i < numFrames; ++i) { + if (i == 0) { riFrames[i] = ri; errCodeThr = riFrames[i]->loadRaw (true, i + 1, true, plistener, 0.8); } else { @@ -1066,7 +1061,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) errCode = errCodeThr ? errCodeThr : errCode; } } - } else if(numFrames > 1) { + } else if (numFrames > 1) { #ifdef _OPENMP #pragma omp parallel #endif @@ -1075,18 +1070,15 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) #ifdef _OPENMP #pragma omp for nowait #endif - - for (unsigned int i = 0; i < numFrames; ++i) - { + for (unsigned int i = 0; i < numFrames; ++i) { if (i == 0) { riFrames[i] = ri; - errCodeThr = riFrames[i]->loadRaw(true, i, true, plistener, 0.8); + errCodeThr = riFrames[i]->loadRaw (true, i, true, plistener, 0.8); } else { riFrames[i] = new RawImage(fname); - errCodeThr = riFrames[i]->loadRaw(true, i); + errCodeThr = riFrames[i]->loadRaw (true, i); } } - #ifdef _OPENMP #pragma omp critical #endif @@ -1096,7 +1088,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) } } else { riFrames[0] = ri; - errCode = riFrames[0]->loadRaw(true, 0, true, plistener, 0.8); + errCode = riFrames[0]->loadRaw (true, 0, true, plistener, 0.8); } if (!errCode) { @@ -1107,14 +1099,14 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) return errCode; } - if (numFrames > 1) { // this disables multi frame support for Fuji S5 until I found a solution to handle different dimensions + if (numFrames > 1) { // this disables multi frame support for Fuji S5 until I found a solution to handle different dimensions if (riFrames[0]->get_width() != riFrames[1]->get_width() || riFrames[0]->get_height() != riFrames[1]->get_height()) { numFrames = 1; } } if (plistener) { - plistener->setProgress(0.9); + plistener->setProgress (0.9); } /***** Copy once constant data extracted from raw *******/ @@ -1129,9 +1121,9 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) // compute inverse of the color transformation matrix // first arg is matrix, second arg is inverse - inverse33(imatrices.rgb_cam, imatrices.cam_rgb); + inverse33 (imatrices.rgb_cam, imatrices.cam_rgb); - d1x = ! ri->get_model().compare("D1X"); + d1x = ! ri->get_model().compare("D1X"); if (ri->getSensorType() == ST_FUJI_XTRANS) { border = 7; @@ -1140,11 +1132,11 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) } if (ri->get_profile()) { - embProfile = cmsOpenProfileFromMem(ri->get_profile(), ri->get_profileLen()); + embProfile = cmsOpenProfileFromMem (ri->get_profile(), ri->get_profileLen()); } // create profile - memset(imatrices.xyz_cam, 0, sizeof(imatrices.xyz_cam)); + memset (imatrices.xyz_cam, 0, sizeof(imatrices.xyz_cam)); for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) @@ -1152,13 +1144,13 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) imatrices.xyz_cam[i][j] += xyz_sRGB[i][k] * imatrices.rgb_cam[k][j]; } - camProfile = ICCStore::getInstance()->createFromMatrix(imatrices.xyz_cam, false, "Camera"); - inverse33(imatrices.xyz_cam, imatrices.cam_xyz); + camProfile = ICCStore::getInstance()->createFromMatrix (imatrices.xyz_cam, false, "Camera"); + inverse33 (imatrices.xyz_cam, imatrices.cam_xyz); // First we get the "as shot" ("Camera") white balance and store it float pre_mul[4]; // FIXME: get_colorsCoeff not so much used nowadays, when we have calculate_scale_mul() function here - ri->get_colorsCoeff(pre_mul, scale_mul, c_black, false); //modify for black level + ri->get_colorsCoeff(pre_mul, scale_mul, c_black, false);//modify for black level camInitialGain = max(scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]) / min(scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]); double camwb_red = ri->get_pre_mul(0) / pre_mul[0]; @@ -1167,7 +1159,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) double cam_r = imatrices.rgb_cam[0][0] * camwb_red + imatrices.rgb_cam[0][1] * camwb_green + imatrices.rgb_cam[0][2] * camwb_blue; double cam_g = imatrices.rgb_cam[1][0] * camwb_red + imatrices.rgb_cam[1][1] * camwb_green + imatrices.rgb_cam[1][2] * camwb_blue; double cam_b = imatrices.rgb_cam[2][0] * camwb_red + imatrices.rgb_cam[2][1] * camwb_green + imatrices.rgb_cam[2][2] * camwb_blue; - camera_wb = ColorTemp(cam_r, cam_g, cam_b, 1.); // as shot WB + camera_wb = ColorTemp (cam_r, cam_g, cam_b, 1.); // as shot WB ColorTemp ReferenceWB; double ref_r, ref_g, ref_b; @@ -1182,7 +1174,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) ref_r = imatrices.rgb_cam[0][0] * refwb_red + imatrices.rgb_cam[0][1] * refwb_green + imatrices.rgb_cam[0][2] * refwb_blue; ref_g = imatrices.rgb_cam[1][0] * refwb_red + imatrices.rgb_cam[1][1] * refwb_green + imatrices.rgb_cam[1][2] * refwb_blue; ref_b = imatrices.rgb_cam[2][0] * refwb_red + imatrices.rgb_cam[2][1] * refwb_green + imatrices.rgb_cam[2][2] * refwb_blue; - ReferenceWB = ColorTemp(ref_r, ref_g, ref_b, 1.); + ReferenceWB = ColorTemp (ref_r, ref_g, ref_b, 1.); } if (settings->verbose) { @@ -1195,9 +1187,9 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) ColorTemp d50wb = ColorTemp(5000.0, 1.0, 1.0, "Custom"); double rm,gm,bm,r,g,b; d50wb.getMultipliers(r, g, b); - camwb_red = imatrices.cam_rgb[0][0]*r + imatrices.cam_rgb[0][1]*g + imatrices.cam_rgb[0][2]*b; + camwb_red = imatrices.cam_rgb[0][0]*r + imatrices.cam_rgb[0][1]*g + imatrices.cam_rgb[0][2]*b; camwb_green = imatrices.cam_rgb[1][0]*r + imatrices.cam_rgb[1][1]*g + imatrices.cam_rgb[1][2]*b; - camwb_blue = imatrices.cam_rgb[2][0]*r + imatrices.cam_rgb[2][1]*g + imatrices.cam_rgb[2][2]*b; + camwb_blue = imatrices.cam_rgb[2][0]*r + imatrices.cam_rgb[2][1]*g + imatrices.cam_rgb[2][2]*b; double pre_mul[3], dmax = 0; pre_mul[0] = ri->get_pre_mul(0) / camwb_red; pre_mul[1] = ri->get_pre_mul(1) / camwb_green; @@ -1220,15 +1212,15 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) initialGain = 1.0 / min(pre_mul[0], pre_mul[1], pre_mul[2]); }*/ - for (unsigned int i = 0; i < numFrames; ++i) { + for (unsigned int i = 0;i < numFrames; ++i) { riFrames[i]->set_prefilters(); } // Load complete Exif information - std::unique_ptr rml(new RawMetaDataLocation(ri->get_exifBase(), ri->get_ciffBase(), ri->get_ciffLen())); - idata = new FramesData(fname, std::move(rml)); - idata->setDCRawFrameCount(numFrames); + std::unique_ptr rml(new RawMetaDataLocation (ri->get_exifBase(), ri->get_ciffBase(), ri->get_ciffLen())); + idata = new FramesData (fname, std::move(rml)); + idata->setDCRawFrameCount (numFrames); green(W, H); red(W, H); @@ -1236,7 +1228,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) //hpmap = allocArray(W, H); if (plistener) { - plistener->setProgress(1.0); + plistener->setProgress (1.0); } plistener = nullptr; // This must be reset, because only load() is called through progressConnector @@ -1251,7 +1243,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise) +void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise) { // BENCHFUN MyTime t1, t2; @@ -1305,23 +1297,21 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens if (numFrames == 4) { int bufferNumber = 0; - - for (unsigned int i = 0; i < 4; ++i) { - if (i == currFrame) { + for (unsigned int i=0; i<4; ++i) { + if (i==currFrame) { copyOriginalPixels(raw, ri, rid, rif, rawData); rawDataFrames[i] = &rawData; } else { if (!rawDataBuffer[bufferNumber]) { rawDataBuffer[bufferNumber] = new array2D; } - rawDataFrames[i] = rawDataBuffer[bufferNumber]; ++bufferNumber; copyOriginalPixels(raw, riFrames[i], rid, rif, *rawDataFrames[i]); } } } else if (numFrames == 2 && currFrame == 2) { // average the frames - if(!rawDataBuffer[0]) { + if (!rawDataBuffer[0]) { rawDataBuffer[0] = new array2D; } rawDataFrames[1] = rawDataBuffer[0]; @@ -1336,7 +1326,6 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens } else { copyOriginalPixels(raw, ri, rid, rif, rawData); } - //FLATFIELD end @@ -1377,17 +1366,16 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens } if (numFrames == 4) { - for (int i = 0; i < 4; ++i) { + for (int i=0; i<4; ++i) { scaleColors(0, 0, W, H, raw, *rawDataFrames[i]); } } else { - scaleColors(0, 0, W, H, raw, rawData); //+ + raw parameters for black level(raw.blackxx) + scaleColors(0, 0, W, H, raw, rawData); //+ + raw parameters for black level(raw.blackxx) } // Correct vignetting of lens profile if (!hasFlatField && lensProf.useVign && lensProf.lcMode != LensProfParams::LcMode::NONE) { std::unique_ptr pmap; - if (lensProf.useLensfun()) { pmap = LFDatabase::getInstance()->findModifier(lensProf, idata, W, H, coarse, -1); } else { @@ -1400,7 +1388,6 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens if (pmap) { LensCorrection &map = *pmap; - if (ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1) { if (numFrames == 4) { for (int i = 0; i < 4; ++i) { @@ -1420,14 +1407,14 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens if (ri->getSensorType() == ST_BAYER && (raw.hotPixelFilter > 0 || raw.deadPixelFilter > 0)) { if (plistener) { plistener->setProgressStr ("PROGRESSBAR_HOTDEADPIXELFILTER"); - plistener->setProgress(0.0); + plistener->setProgress (0.0); } if (!bitmapBads) { bitmapBads.reset(new PixelsMap(W, H)); } - int nFound = findHotDeadPixels(*(bitmapBads.get()), raw.hotdeadpix_thresh, raw.hotPixelFilter, raw.deadPixelFilter ); + int nFound = findHotDeadPixels(*(bitmapBads.get()), raw.hotdeadpix_thresh, raw.hotPixelFilter, raw.deadPixelFilter); totBP += nFound; if (settings->verbose && nFound > 0) { @@ -1466,11 +1453,11 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens [&]() -> bool { CameraConstantsStore *ccs = CameraConstantsStore::getInstance(); - CameraConst *cc = ccs->get(ri->get_maker().c_str(), ri->get_model().c_str()); + const CameraConst *cc = ccs->get(ri->get_maker().c_str(), ri->get_model().c_str()); return cc && cc->get_globalGreenEquilibration(); }; - if ( ri->getSensorType() == ST_BAYER && (raw.bayersensor.greenthresh || (globalGreenEq() && raw.bayersensor.method != RAWParams::BayerSensor::getMethodString( RAWParams::BayerSensor::Method::VNG4))) ) { + if (ri->getSensorType() == ST_BAYER && (raw.bayersensor.greenthresh || (globalGreenEq() && raw.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::VNG4)))) { if (settings->verbose) { printf("Performing global green equilibration...\n"); } @@ -1487,7 +1474,7 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens if (ri->getSensorType() == ST_BAYER && raw.bayersensor.greenthresh > 0) { if (plistener) { plistener->setProgressStr ("PROGRESSBAR_GREENEQUIL"); - plistener->setProgress(0.0); + plistener->setProgress (0.0); } GreenEqulibrateThreshold thresh(0.01 * raw.bayersensor.greenthresh); @@ -1521,7 +1508,7 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens if (ri->getSensorType() == ST_BAYER && raw.bayersensor.linenoise > 0) { if (plistener) { plistener->setProgressStr ("PROGRESSBAR_LINEDENOISE"); - plistener->setProgress(0.0); + plistener->setProgress (0.0); } std::unique_ptr line_denoise_rowblender; @@ -1535,16 +1522,15 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens cfa_linedn(0.00002 * (raw.bayersensor.linenoise), int(raw.bayersensor.linenoiseDirection) & int(RAWParams::BayerSensor::LineNoiseDirection::VERTICAL), int(raw.bayersensor.linenoiseDirection) & int(RAWParams::BayerSensor::LineNoiseDirection::HORIZONTAL), *line_denoise_rowblender); } - if ((raw.ca_autocorrect || fabs(raw.cared) > 0.001 || fabs(raw.cablue) > 0.001) && ri->getSensorType() == ST_BAYER) { // Auto CA correction disabled for X-Trans, for now... + if ((raw.ca_autocorrect || std::fabs(raw.cared) > 0.001 || std::fabs(raw.cablue) > 0.001) && ri->getSensorType() == ST_BAYER) { // Auto CA correction disabled for X-Trans, for now... if (plistener) { plistener->setProgressStr ("PROGRESSBAR_RAWCACORR"); - plistener->setProgress(0.0); + plistener->setProgress (0.0); } - if (numFrames == 4) { double fitParams[64]; float *buffer = CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[0], fitParams, false, true, nullptr, false, options.chunkSizeCA, options.measure); - for(int i = 1; i < 3; ++i) { + for (int i = 1; i < 3; ++i) { CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[i], fitParams, true, false, buffer, false, options.chunkSizeCA, options.measure); } CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[3], fitParams, true, false, buffer, true, options.chunkSizeCA, options.measure); @@ -1553,13 +1539,13 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens } } - if (prepareDenoise && dirpyrdenoiseExpComp == INFINITY) { + if (prepareDenoise && dirpyrdenoiseExpComp == RT_INFINITY) { LUTu aehist; int aehistcompr; double clip = 0; int brightness, contrast, black, hlcompr, hlcomprthresh; - getAutoExpHistogram(aehist, aehistcompr); - ImProcFunctions::getAutoExp(aehist, aehistcompr, clip, dirpyrdenoiseExpComp, brightness, contrast, black, hlcompr, hlcomprthresh); + getAutoExpHistogram (aehist, aehistcompr); + ImProcFunctions::getAutoExp (aehist, aehistcompr, clip, dirpyrdenoiseExpComp, brightness, contrast, black, hlcompr, hlcomprthresh); } t2.set(); @@ -1580,11 +1566,11 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c if (ri->getSensorType() == ST_BAYER) { if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::HPHD)) { - hphd_demosaic(); + hphd_demosaic (); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::VNG4)) { vng4_demosaic (rawData, red, green, blue); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AHD)) { - ahd_demosaic(); + ahd_demosaic (); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZE)) { amaze_demosaic_RT (0, 0, W, H, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) @@ -1601,7 +1587,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCB)) { dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::EAHD)) { - eahd_demosaic(); + eahd_demosaic (); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::IGV)) { igv_interpolate(W, H); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::LMMSE)) { @@ -1701,20 +1687,20 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c void RawImageSource::retinexPrepareBuffers(const ColorManagementParams& cmp, const RetinexParams &retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI) { bool useHsl = (retinexParams.retinexcolorspace == "HSLLOG" || retinexParams.retinexcolorspace == "HSLLIN"); - conversionBuffer[0](W - 2 * border, H - 2 * border); - conversionBuffer[1](W - 2 * border, H - 2 * border); - conversionBuffer[2](W - 2 * border, H - 2 * border); - conversionBuffer[3](W - 2 * border, H - 2 * border); + conversionBuffer[0] (W - 2 * border, H - 2 * border); + conversionBuffer[1] (W - 2 * border, H - 2 * border); + conversionBuffer[2] (W - 2 * border, H - 2 * border); + conversionBuffer[3] (W - 2 * border, H - 2 * border); LUTf *retinexgamtab = nullptr;//gamma before and after Retinex to restore tones LUTf lutTonereti; if (retinexParams.gammaretinex == "low") { - retinexgamtab = & (Color::gammatab_115_2); + retinexgamtab = &(Color::gammatab_115_2); } else if (retinexParams.gammaretinex == "mid") { - retinexgamtab = & (Color::gammatab_13_2); + retinexgamtab = &(Color::gammatab_13_2); } else if (retinexParams.gammaretinex == "hig") { - retinexgamtab = & (Color::gammatab_145_3); + retinexgamtab = &(Color::gammatab_145_3); } else if (retinexParams.gammaretinex == "fre") { GammaValues g_a; double pwr = 1.0 / retinexParams.gam; @@ -1750,12 +1736,12 @@ void RawImageSource::retinexPrepareBuffers(const ColorManagementParams& cmp, con double x; if (gamm2 < 1.) { - x = Color::igammareti(val, gamm, start, ts, mul, add); + x = Color::igammareti (val, gamm, start, ts, mul , add); } else { - x = Color::gammareti(val, gamm, start, ts, mul, add); + x = Color::gammareti (val, gamm, start, ts, mul , add); } - lutTonereti[i] = CLIP(x * 65535.); // CLIP avoid in some case extra values + lutTonereti[i] = CLIP(x * 65535.);// CLIP avoid in some case extra values } retinexgamtab = &lutTonereti; @@ -1778,15 +1764,15 @@ void RawImageSource::retinexPrepareBuffers(const ColorManagementParams& cmp, con printf("rr2=%f gg2=%f bb2=%f \n",rr,gg,bb); */ /* - if(retinexParams.highlig < 100 && retinexParams.retinexMethod == "highliplus") {//try to recover magenta...very difficult ! + if (retinexParams.highlig < 100 && retinexParams.retinexMethod == "highliplus") {//try to recover magenta...very difficult ! float hig = ((float)retinexParams.highlig)/100.f; float higgb = ((float)retinexParams.grbl)/100.f; #ifdef _OPENMP #pragma omp parallel for #endif - for (int i = border; i < H - border; i++ ) { - for (int j = border; j < W - border; j++ ) { + for (int i = border; i < H - border; i++) { + for (int j = border; j < W - border; j++) { float R_,G_,B_; R_=red[i][j]; G_=green[i][j]; @@ -1794,13 +1780,13 @@ void RawImageSource::retinexPrepareBuffers(const ColorManagementParams& cmp, con //empirical method to find highlight magenta with no conversion RGB and no white balance //red = master Gr and Bl default higgb=0.5 - // if(R_>65535.f*hig && G_ > 65535.f*higgb && B_ > 65535.f*higgb) conversionBuffer[3][i - border][j - border] = R_; + // if (R_>65535.f*hig && G_ > 65535.f*higgb && B_ > 65535.f*higgb) conversionBuffer[3][i - border][j - border] = R_; // else conversionBuffer[3][i - border][j - border] = 0.f; } } } */ - if (retinexParams.gammaretinex != "none" && retinexParams.str != 0 && retinexgamtab) { //gamma + if (retinexParams.gammaretinex != "none" && retinexParams.str != 0 && retinexgamtab) {//gamma #ifdef _OPENMP #pragma omp parallel for @@ -1857,7 +1843,7 @@ void RawImageSource::retinexPrepareBuffers(const ColorManagementParams& cmp, con if (lhist16RETI) { for (int p = 0; p < 4; p++) { - int pos = (conversionBuffer[2][i - border][j - border + p]); //histogram in curve HSL + int pos = (conversionBuffer[2][i - border][j - border + p]);//histogram in curve HSL lhist16RETIThr[pos]++; } } @@ -1928,7 +1914,7 @@ void RawImageSource::retinexPrepareBuffers(const ColorManagementParams& cmp, con conversionBuffer[2][i - border][j - border] = L; conversionBuffer[3][i - border][j - border] = xatan2f(bb, aa); -// if(R_>40000.f && G_ > 30000.f && B_ > 30000.f) conversionBuffer[3][i - border][j - border] = R_; +// if (R_>40000.f && G_ > 30000.f && B_ > 30000.f) conversionBuffer[3][i - border][j - border] = R_; // else conversionBuffer[3][i - border][j - border] = 0.f; if (lhist16RETI) { int pos = L; @@ -1957,9 +1943,9 @@ void RawImageSource::retinexPrepareCurves(const RetinexParams &retinexParams, LU useHsl = (retinexParams.retinexcolorspace == "HSLLOG" || retinexParams.retinexcolorspace == "HSLLIN"); if (useHsl) { - CurveFactory::curveDehaContL(retinexcontlutili, retinexParams.cdHcurve, cdcurve, 1, lhist16RETI, histLRETI); + CurveFactory::curveDehaContL (retinexcontlutili, retinexParams.cdHcurve, cdcurve, 1, lhist16RETI, histLRETI); } else { - CurveFactory::curveDehaContL(retinexcontlutili, retinexParams.cdcurve, cdcurve, 1, lhist16RETI, histLRETI); + CurveFactory::curveDehaContL (retinexcontlutili, retinexParams.cdcurve, cdcurve, 1, lhist16RETI, histLRETI); } CurveFactory::mapcurve(mapcontlutili, retinexParams.mapcurve, mapcurve, 1, lhist16RETI, histLRETI); @@ -1973,7 +1959,7 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara t4.set(); if (settings->verbose) { - printf("Applying Retinex\n"); + printf ("Applying Retinex\n"); } LUTf lutToneireti; @@ -1982,11 +1968,11 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara LUTf *retinexigamtab = nullptr;//gamma before and after Retinex to restore tones if (deh.gammaretinex == "low") { - retinexigamtab = & (Color::igammatab_115_2); + retinexigamtab = &(Color::igammatab_115_2); } else if (deh.gammaretinex == "mid") { - retinexigamtab = & (Color::igammatab_13_2); + retinexigamtab = &(Color::igammatab_13_2); } else if (deh.gammaretinex == "hig") { - retinexigamtab = & (Color::igammatab_145_3); + retinexigamtab = &(Color::igammatab_145_3); } else if (deh.gammaretinex == "fre") { GammaValues g_a; double pwr = 1.0 / deh.gam; @@ -2019,9 +2005,9 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara double x; if (gamm2 < 1.) { - x = Color::gammareti(val, gamm, start, ts, mul, add); + x = Color::gammareti (val, gamm, start, ts, mul , add); } else { - x = Color::igammareti(val, gamm, start, ts, mul, add); + x = Color::igammareti (val, gamm, start, ts, mul , add); } lutToneireti[i] = CLIP(x * 65535.); @@ -2035,7 +2021,7 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara const int HNew = H - 2 * border; const int WNew = W - 2 * border; - array2D LBuffer(WNew, HNew); + array2D LBuffer (WNew, HNew); float **temp = conversionBuffer[2]; // one less dereference LUTf dLcurve; LUTu hist16RET; @@ -2090,7 +2076,8 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara int pos = LBuffer[i][j]; hist16RETThr[pos]++; //histogram in Curve } - } else + } + else for (int j = 0; j < W - 2 * border; j++) { LBuffer[i][j] = temp[i][j]; } @@ -2105,7 +2092,7 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara } } - if (hist16RET) { //update histogram + if (hist16RET) {//update histogram // TODO : When rgbcurvesspeedup branch is merged into master, replace this by the following 1-liner // hist16RET.compressTo(histLRETI); // also remove declaration and init of dLcurve some lines above then and finally remove this comment :) @@ -2218,7 +2205,7 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara { float aa = conversionBuffer[0][i - border][j - border]; float bb = conversionBuffer[1][i - border][j - border]; - float Chprov1 = sqrt(SQR(aa) + SQR(bb)) / 327.68f; + float Chprov1 = std::sqrt(SQR(aa) + SQR(bb)) / 327.68f; sqrtBuffer[j - border] = Chprov1; float HH = xatan2f(bb, aa); atan2Buffer[j - border] = HH; @@ -2246,7 +2233,7 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara #else float aa = conversionBuffer[0][i - border][j - border]; float bb = conversionBuffer[1][i - border][j - border]; - float Chprov1 = sqrt(SQR(aa) + SQR(bb)) / 327.68f; + float Chprov1 = std::sqrt(SQR(aa) + SQR(bb)) / 327.68f; float HH = xatan2f(bb, aa); float2 sincosval;// = xsincosf(HH); @@ -2260,8 +2247,8 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara #endif - if (chutili) { // c=f(H) - float valp = float ((chcurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f)); + if (chutili) { // c=f(H) + float valp = float((chcurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f)); Chprov1 *= (1.f + 2.f * valp); } @@ -2360,15 +2347,16 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara } -void RawImageSource::flushRawData() +void RawImageSource::flush() { + for (size_t i = 0; i + 1 < numFrames; ++i) { + delete rawDataBuffer[i]; + rawDataBuffer[i] = nullptr; + } + if (rawData) { rawData(0, 0); } -} - -void RawImageSource::flushRGB() -{ if (green) { green(0, 0); } @@ -2380,6 +2368,18 @@ void RawImageSource::flushRGB() if (blue) { blue(0, 0); } + + if (greenloc) { + greenloc(0, 0); + } + + if (redloc) { + redloc(0, 0); + } + + if (blueloc) { + blueloc(0, 0); + } } void RawImageSource::HLRecovery_Global(const ToneCurveParams &hrp) @@ -2387,10 +2387,10 @@ void RawImageSource::HLRecovery_Global(const ToneCurveParams &hrp) if (hrp.hrenabled && hrp.method == "Color") { if (!rgbSourceModified) { if (settings->verbose) { - printf("Applying Highlight Recovery: Color propagation...\n"); + printf ("Applying Highlight Recovery: Color propagation...\n"); } - HLRecovery_inpaint(red, green, blue); + HLRecovery_inpaint (red, green, blue); rgbSourceModified = true; } } @@ -2419,9 +2419,9 @@ void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, Raw #endif for (int row = 0; row < H; row++) { const int c0 = FC(row, 0); - const float black0 = black[(c0 == 1 && !(row & 1) ) ? 3 : c0]; + const float black0 = black[(c0 == 1 && !(row & 1)) ? 3 : c0]; const int c1 = FC(row, 1); - const float black1 = black[(c1 == 1 && !(row & 1) ) ? 3 : c1]; + const float black1 = black[(c1 == 1 && !(row & 1)) ? 3 : c1]; int col; for (col = 0; col < W - 1; col += 2) { rawData[row][col] = max(src->data[row][col] + black0 - riDark->data[row][col], 0.0f); @@ -2432,6 +2432,7 @@ void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, Raw } } } else { + #ifdef _OPENMP #pragma omp parallel for #endif @@ -2479,7 +2480,7 @@ void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, Raw if (riDark && W == riDark->get_width() && H == riDark->get_height()) { for (int row = 0; row < H; row++) { for (int col = 0; col < W; col++) { - int c = FC(row, col); + int c = FC(row, col); int c4 = (c == 1 && !(row & 1)) ? 3 : c; rawData[row][3 * col + 0] = max(src->data[row][3 * col + 0] + black[c4] - riDark->data[row][3 * col + 0], 0.0f); rawData[row][3 * col + 1] = max(src->data[row][3 * col + 1] + black[c4] - riDark->data[row][3 * col + 1], 0.0f); @@ -2526,14 +2527,14 @@ void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const R } for (int i = 0; i < 4 ; i++) { - cblacksom[i] = max(c_black[i] + black_lev[i], 0.0f); // adjust black level + cblacksom[i] = max(c_black[i] + black_lev[i], 0.0f); // adjust black level } for (int i = 0; i < 4; ++i) { c_white[i] = (ri->get_white(i) - cblacksom[i]) / raw.expos + cblacksom[i]; } - initialGain = calculate_scale_mul(scale_mul, ref_pre_mul, c_white, cblacksom, isMono, ri->get_colors()); // recalculate scale colors with adjusted levels + initialGain = calculate_scale_mul(scale_mul, ref_pre_mul, c_white, cblacksom, isMono, ri->get_colors()); // recalculate scale colors with adjusted levels //fprintf(stderr, "recalc: %f [%f %f %f %f]\n", initialGain, scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]); for (int i = 0; i < 4 ; i++) { @@ -2558,8 +2559,8 @@ void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const R for (int row = winy; row < winy + winh; row ++) { for (int col = winx; col < winx + winw; col++) { - const int c = FC(row, col); // three colors, 0=R, 1=G, 2=B - const int c4 = ( c == 1 && !(row & 1) ) ? 3 : c; // four colors, 0=R, 1=G1, 2=B, 3=G2 + const int c = FC(row, col); // three colors, 0=R, 1=G, 2=B + const int c4 = (c == 1 && !(row & 1)) ? 3 : c; // four colors, 0=R, 1=G1, 2=B, 3=G2 const float val = max(0.f, rawData[row][col] - cblacksom[c4]) * scale_mul[c4]; rawData[row][col] = val; tmpchmax[c] = max(tmpchmax[c], val); @@ -2669,7 +2670,7 @@ void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const R //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -int RawImageSource::defTransform(int tran) +int RawImageSource::defTransform (int tran) { int deg = ri->get_rotateDegree(); @@ -2708,7 +2709,7 @@ int RawImageSource::defTransform(int tran) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // Thread called part -void RawImageSource::processFalseColorCorrectionThread(Imagefloat* im, array2D &rbconv_Y, array2D &rbconv_I, array2D &rbconv_Q, array2D &rbout_I, array2D &rbout_Q, const int row_from, const int row_to) +void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D &rbconv_Y, array2D &rbconv_I, array2D &rbconv_Q, array2D &rbout_I, array2D &rbout_Q, const int row_from, const int row_to) { const int W = im->getWidth(); @@ -2730,8 +2731,8 @@ void RawImageSource::processFalseColorCorrectionThread(Imagefloat* im, array2Dr(row_from - 1), im->g(row_from - 1), im->b(row_from - 1), rbconv_Y[px], rbconv_I[px], rbconv_Q[px], W); - convert_row_to_YIQ(im->r(row_from), im->g(row_from), im->b(row_from), rbconv_Y[cx], rbconv_I[cx], rbconv_Q[cx], W); + convert_row_to_YIQ (im->r(row_from - 1), im->g(row_from - 1), im->b(row_from - 1), rbconv_Y[px], rbconv_I[px], rbconv_Q[px], W); + convert_row_to_YIQ (im->r(row_from), im->g(row_from), im->b(row_from), rbconv_Y[cx], rbconv_I[cx], rbconv_Q[cx], W); for (int j = 0; j < W; j++) { rbout_I[px][j] = rbconv_I[px][j]; @@ -2744,11 +2745,11 @@ void RawImageSource::processFalseColorCorrectionThread(Imagefloat* im, array2Dr(i + 1), im->g(i + 1), im->b(i + 1), rbconv_Y[nx], rbconv_I[nx], rbconv_Q[nx], W); + convert_row_to_YIQ (im->r(i + 1), im->g(i + 1), im->b(i + 1), rbconv_Y[nx], rbconv_I[nx], rbconv_Q[nx], W); #ifdef __SSE2__ - pre1[0] = _mm_setr_ps(rbconv_I[px][0], rbconv_Q[px][0], 0, 0), pre1[1] = _mm_setr_ps(rbconv_I[cx][0], rbconv_Q[cx][0], 0, 0), pre1[2] = _mm_setr_ps(rbconv_I[nx][0], rbconv_Q[nx][0], 0, 0); - pre2[0] = _mm_setr_ps(rbconv_I[px][1], rbconv_Q[px][1], 0, 0), pre2[1] = _mm_setr_ps(rbconv_I[cx][1], rbconv_Q[cx][1], 0, 0), pre2[2] = _mm_setr_ps(rbconv_I[nx][1], rbconv_Q[nx][1], 0, 0); + pre1[0] = _mm_setr_ps(rbconv_I[px][0], rbconv_Q[px][0], 0, 0) , pre1[1] = _mm_setr_ps(rbconv_I[cx][0], rbconv_Q[cx][0], 0, 0), pre1[2] = _mm_setr_ps(rbconv_I[nx][0], rbconv_Q[nx][0], 0, 0); + pre2[0] = _mm_setr_ps(rbconv_I[px][1], rbconv_Q[px][1], 0, 0) , pre2[1] = _mm_setr_ps(rbconv_I[cx][1], rbconv_Q[cx][1], 0, 0), pre2[2] = _mm_setr_ps(rbconv_I[nx][1], rbconv_Q[nx][1], 0, 0); // fill first element in rbout_I and rbout_Q rbout_I[cx][0] = rbconv_I[cx][0]; @@ -2821,7 +2822,7 @@ void RawImageSource::processFalseColorCorrectionThread(Imagefloat* im, array2D row_from) { - convert_to_RGB(im->r(i - 1, 0), im->g(i - 1, 0), im->b(i - 1, 0), rbconv_Y[px][0], rbout_I[px][0], rbout_Q[px][0]); + convert_to_RGB (im->r(i - 1, 0), im->g(i - 1, 0), im->b(i - 1, 0), rbconv_Y[px][0], rbout_I[px][0], rbout_Q[px][0]); #ifdef _OPENMP #pragma omp simd @@ -2830,15 +2831,15 @@ void RawImageSource::processFalseColorCorrectionThread(Imagefloat* im, array2Dr(i - 1, j), im->g(i - 1, j), im->b(i - 1, j), rbconv_Y[px][j], I, Q); + convert_to_RGB (im->r(i - 1, j), im->g(i - 1, j), im->b(i - 1, j), rbconv_Y[px][j], I, Q); } - convert_to_RGB(im->r(i - 1, W - 1), im->g(i - 1, W - 1), im->b(i - 1, W - 1), rbconv_Y[px][W - 1], rbout_I[px][W - 1], rbout_Q[px][W - 1]); + convert_to_RGB (im->r(i - 1, W - 1), im->g(i - 1, W - 1), im->b(i - 1, W - 1), rbconv_Y[px][W - 1], rbout_I[px][W - 1], rbout_Q[px][W - 1]); } } // blur last 3 row and finalize H-1th row - convert_to_RGB(im->r(row_to - 1, 0), im->g(row_to - 1, 0), im->b(row_to - 1, 0), rbconv_Y[cx][0], rbout_I[cx][0], rbout_Q[cx][0]); + convert_to_RGB (im->r(row_to - 1, 0), im->g(row_to - 1, 0), im->b(row_to - 1, 0), rbconv_Y[cx][0], rbout_I[cx][0], rbout_Q[cx][0]); #ifdef _OPENMP #pragma omp simd #endif @@ -2846,16 +2847,16 @@ void RawImageSource::processFalseColorCorrectionThread(Imagefloat* im, array2Dr(row_to - 1, j), im->g(row_to - 1, j), im->b(row_to - 1, j), rbconv_Y[cx][j], I, Q); + convert_to_RGB (im->r(row_to - 1, j), im->g(row_to - 1, j), im->b(row_to - 1, j), rbconv_Y[cx][j], I, Q); } - convert_to_RGB(im->r(row_to - 1, W - 1), im->g(row_to - 1, W - 1), im->b(row_to - 1, W - 1), rbconv_Y[cx][W - 1], rbout_I[cx][W - 1], rbout_Q[cx][W - 1]); + convert_to_RGB (im->r(row_to - 1, W - 1), im->g(row_to - 1, W - 1), im->b(row_to - 1, W - 1), rbconv_Y[cx][W - 1], rbout_I[cx][W - 1], rbout_Q[cx][W - 1]); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // correction_YIQ_LQ -void RawImageSource::processFalseColorCorrection(Imagefloat* im, const int steps) +void RawImageSource::processFalseColorCorrection (Imagefloat* im, const int steps) { if (im->getHeight() < 4 || steps < 1) { @@ -2865,7 +2866,7 @@ void RawImageSource::processFalseColorCorrection(Imagefloat* im, const int steps #ifdef _OPENMP #pragma omp parallel { - multi_array2D buffer(W, 3); + multi_array2D buffer (W, 3); int tid = omp_get_thread_num(); int nthreads = omp_get_num_threads(); int blk = (im->getHeight() - 2) / nthreads; @@ -2873,19 +2874,19 @@ void RawImageSource::processFalseColorCorrection(Imagefloat* im, const int steps for (int t = 0; t < steps; t++) { if (tid < nthreads - 1) { - processFalseColorCorrectionThread(im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1 + tid * blk, 1 + (tid + 1)*blk); + processFalseColorCorrectionThread (im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1 + tid * blk, 1 + (tid + 1)*blk); } else { - processFalseColorCorrectionThread(im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1 + tid * blk, im->getHeight() - 1); + processFalseColorCorrectionThread (im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1 + tid * blk, im->getHeight() - 1); } #pragma omp barrier } } #else - multi_array2D buffer(W, 3); + multi_array2D buffer (W, 3); for (int t = 0; t < steps; t++) { - processFalseColorCorrectionThread(im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1, im->getHeight() - 1); + processFalseColorCorrectionThread (im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1 , im->getHeight() - 1); } #endif @@ -2959,7 +2960,7 @@ lab2ProphotoRgbD50(float L, float A, float B, float& r, float& g, float& b) } // Converts raw image including ICC input profile to working space - floating point version -void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double camMatrix[3][3], const std::string &camName) +void RawImageSource::colorSpaceConversion_ (Imagefloat* im, const ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double camMatrix[3][3], const std::string &camName) { // MyTime t1, t2, t3; @@ -3085,7 +3086,7 @@ void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagement // Initialize transform cmsHTRANSFORM hTransform; - cmsHPROFILE prophoto = ICCStore::getInstance()->workingSpace("ProPhoto"); // We always use Prophoto to apply the ICC profile to minimize problems with clipping in LUT conversion. + cmsHPROFILE prophoto = ICCStore::getInstance()->workingSpace("ProPhoto"); // We always use Prophoto to apply the ICC profile to minimize problems with clipping in LUT conversion. bool transform_via_pcs_lab = false; bool separate_pcs_lab_highlights = false; @@ -3115,7 +3116,7 @@ void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagement } } - lcmsMutex->lock(); + lcmsMutex->lock (); switch (camera_icc_type) { case CAMERA_ICC_TYPE_PHASE_ONE: @@ -3124,7 +3125,7 @@ void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagement transform_via_pcs_lab = true; separate_pcs_lab_highlights = true; // We transform to Lab because we can and that we avoid getting an unnecessary unmatched gamma conversion which we would need to revert. - hTransform = cmsCreateTransform(in, TYPE_RGB_FLT, nullptr, TYPE_Lab_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, nullptr, TYPE_Lab_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { @@ -3142,23 +3143,23 @@ void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagement case CAMERA_ICC_TYPE_NIKON: case CAMERA_ICC_TYPE_GENERIC: default: - hTransform = cmsCreateTransform(in, TYPE_RGB_FLT, prophoto, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); // NOCACHE is important for thread safety + hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, prophoto, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); // NOCACHE is important for thread safety break; } - lcmsMutex->unlock(); + lcmsMutex->unlock (); if (hTransform == nullptr) { // Fallback: create transform from camera profile. Should not happen normally. - lcmsMutex->lock(); - hTransform = cmsCreateTransform(camprofile, TYPE_RGB_FLT, prophoto, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); - lcmsMutex->unlock(); + lcmsMutex->lock (); + hTransform = cmsCreateTransform (camprofile, TYPE_RGB_FLT, prophoto, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + lcmsMutex->unlock (); } TMatrix toxyz = {}, torgb = {}; if (!working_space_is_prophoto) { - toxyz = ICCStore::getInstance()->workingSpaceMatrix("ProPhoto"); + toxyz = ICCStore::getInstance()->workingSpaceMatrix ("ProPhoto"); torgb = ICCStore::getInstance()->workingSpaceInverseMatrix (cmp.workingProfile); //sRGB .. Adobe...Wide... } @@ -3178,9 +3179,9 @@ void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagement // Apply pre-processing for (int w = 0; w < im->getWidth(); ++w) { - float r = * (pR++); - float g = * (pG++); - float b = * (pB++); + float r = *(pR++); + float g = *(pG++); + float b = *(pB++); // convert to 0-1 range as LCMS expects that r /= 65535.0f; @@ -3242,16 +3243,16 @@ void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagement break; } - * (p++) = r; - * (p++) = g; - * (p++) = b; + *(p++) = r; + *(p++) = g; + *(p++) = b; } // Run icc transform - cmsDoTransform(hTransform, buffer.data, buffer.data, im->getWidth()); + cmsDoTransform (hTransform, buffer.data, buffer.data, im->getWidth()); if (separate_pcs_lab_highlights) { - cmsDoTransform(hTransform, hl_buffer.data, hl_buffer.data, im->getWidth()); + cmsDoTransform (hTransform, hl_buffer.data, hl_buffer.data, im->getWidth()); } // Apply post-processing @@ -3265,9 +3266,9 @@ void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagement float r, g, b, hr = 0.f, hg = 0.f, hb = 0.f; if (transform_via_pcs_lab) { - float L = * (p++); - float A = * (p++); - float B = * (p++); + float L = *(p++); + float A = *(p++); + float B = *(p++); // profile connection space CIELAB should have D50 illuminant lab2ProphotoRgbD50(L, A, B, r, g, b); @@ -3275,9 +3276,9 @@ void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagement lab2ProphotoRgbD50(hl_buffer.data[3 * w + 0], hl_buffer.data[3 * w + 1], hl_buffer.data[3 * w + 2], hr, hg, hb); } } else { - r = * (p++); - g = * (p++); - b = * (p++); + r = *(p++); + g = *(p++); + b = *(p++); } // restore pre-processing and/or add post-processing for the various ICC types @@ -3296,7 +3297,7 @@ void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagement if (maxc > mix) { float fac = (maxc - mix) / (1.0 - mix); - fac = sqrtf(sqrtf(fac)); // gamma 0.25 to mix in highlight render relatively quick + fac = sqrtf(sqrtf(fac)); // gamma 0.25 to mix in highlight render relatively quick r = (1.0 - fac) * r + fac * hr; g = (1.0 - fac) * g + fac * hg; b = (1.0 - fac) * b + fac * hb; @@ -3341,9 +3342,9 @@ void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagement g *= 65535.0; b *= 65535.0; - * (pR++) = r; - * (pG++) = g; - * (pB++) = b; + *(pR++) = r; + *(pG++) = g; + *(pB++) = b; } } } // End of parallelization @@ -3377,7 +3378,7 @@ bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embed } else if (inProfile != "(camera)" && !inProfile.empty()) { Glib::ustring normalName = inProfile; - if (!inProfile.compare(0, 5, "file:")) { + if (!inProfile.compare (0, 5, "file:")) { normalName = inProfile.substr(5); } @@ -3386,7 +3387,7 @@ bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embed } if (*dcpProf == nullptr) { - in = ICCStore::getInstance()->getProfile(inProfile); + in = ICCStore::getInstance()->getProfile (inProfile); } } @@ -3406,9 +3407,7 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi constexpr float trans[ColorCount][ColorCount] = { { 1, 1, 1 }, { 1.7320508, -1.7320508, 0 }, { -1, -1, 2 } }; constexpr float itrans[ColorCount][ColorCount] = { { 1, 0.8660254, -0.5 }, { 1, -0.8660254, -0.5 }, { 1, 0, 1 } }; -#define FOREACHCOLOR for (int c=0; c < ColorCount; c++) - - float minpt = min(hlmax[0], hlmax[1], hlmax[2]); //min of the raw clip points + float minpt = rtengine::min(hlmax[0], hlmax[1], hlmax[2]); //min of the raw clip points //float maxpt=max(hlmax[0],hlmax[1],hlmax[2]);//max of the raw clip points //float medpt=hlmax[0]+hlmax[1]+hlmax[2]-minpt-maxpt;//median of the raw clip points float maxave = (hlmax[0] + hlmax[1] + hlmax[2]) / 3; //ave of the raw clip points @@ -3418,7 +3417,9 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi const float satthresh = 0.5; float clip[3]; - FOREACHCOLOR clip[c] = min(maxave, hlmax[c]); + for (int c = 0; c < ColorCount; ++c) { + clip[c] = rtengine::min(maxave, hlmax[c]); + } // Determine the maximum level (clip) of all channels const float clippt = clipthresh * maxval; @@ -3435,20 +3436,20 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi rgb[2] = bin[col]; // If no channel is clipped, do nothing on pixel - int c; + int cc; - for (c = 0; c < ColorCount; c++) { - if (rgb[c] > clippt) { + for (cc = 0; cc < ColorCount; ++cc) { + if (rgb[cc] > clippt) { break; } } - if (c == ColorCount) { + if (cc == ColorCount) { continue; } // Initialize cam with raw input [0] and potentially clipped input [1] - FOREACHCOLOR { + for (int c = 0; c < ColorCount; ++c) { lratio += min(rgb[c], clip[c]); cam[0][c] = rgb[c]; cam[1][c] = min(cam[0][c], maxval); @@ -3456,7 +3457,7 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi // Calculate the lightness correction ratio (chratio) for (int i = 0; i < 2; i++) { - FOREACHCOLOR { + for (int c = 0; c < ColorCount; ++c) { lab[i][c] = 0; for (int j = 0; j < ColorCount; j++) @@ -3472,7 +3473,7 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi } } - chratio = (sqrt(sum[1] / sum[0])); + chratio = std::sqrt(sum[1] / sum[0]); // Apply ratio to lightness in LCH space for (int c = 1; c < ColorCount; c++) { @@ -3480,7 +3481,7 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi } // Transform back from LCH to RGB - FOREACHCOLOR { + for (int c = 0; c < ColorCount; ++c) { cam[0][c] = 0; for (int j = 0; j < ColorCount; j++) @@ -3488,7 +3489,9 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi cam[0][c] += itrans[c][j] * lab[0][j]; } } - FOREACHCOLOR rgb[c] = cam[0][c] / ColorCount; + for (int c = 0; c < ColorCount; ++c) { + rgb[c] = cam[0][c] / ColorCount; + } // Copy converted pixel back if (rin[col] > fixpt) { @@ -3525,7 +3528,7 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi } } -void RawImageSource::HLRecovery_Luminance(float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval) +void RawImageSource::HLRecovery_Luminance (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval) { for (int i = 0; i < width; i++) { @@ -3542,7 +3545,7 @@ void RawImageSource::HLRecovery_Luminance(float* rin, float* gin, float* bin, fl double Ho = 2 * bo - ro - go; if (r != g && g != b) { - double ratio = sqrt((Co * Co + Ho * Ho) / (C * C + H * H)); + double ratio = std::sqrt ((Co * Co + Ho * Ho) / (C * C + H * H)); C *= ratio; H *= ratio; } @@ -3563,8 +3566,8 @@ void RawImageSource::HLRecovery_Luminance(float* rin, float* gin, float* bin, fl //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::HLRecovery_CIELab(float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, - int width, float maxval, double xyz_cam[3][3], double cam_xyz[3][3]) +void RawImageSource::HLRecovery_CIELab (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, + int width, float maxval, double xyz_cam[3][3], double cam_xyz[3][3]) { //static bool crTableReady = false; @@ -3620,14 +3623,15 @@ void RawImageSource::HLRecovery_CIELab(float* rin, float* gin, float* bin, float //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::hlRecovery(const std::string &method, float* red, float* green, float* blue, int width, float* hlmax) +void RawImageSource::hlRecovery (const std::string &method, float* red, float* green, float* blue, int width, float* hlmax) { if (method == "Luminance") { - HLRecovery_Luminance(red, green, blue, red, green, blue, width, 65535.0); + HLRecovery_Luminance (red, green, blue, red, green, blue, width, 65535.0); } else if (method == "CIELab blending") { - HLRecovery_CIELab(red, green, blue, red, green, blue, width, 65535.0, imatrices.xyz_cam, imatrices.cam_xyz); - } else if (method == "Blend") { // derived from Dcraw + HLRecovery_CIELab (red, green, blue, red, green, blue, width, 65535.0, imatrices.xyz_cam, imatrices.cam_xyz); + } + else if (method == "Blend") { // derived from Dcraw HLRecovery_blend(red, green, blue, width, 65535.0, hlmax); } @@ -3635,7 +3639,7 @@ void RawImageSource::hlRecovery(const std::string &method, float* red, float* gr //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::getAutoExpHistogram(LUTu & histogram, int& histcompr) +void RawImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) { // BENCHFUN histcompr = 3; @@ -3656,12 +3660,12 @@ void RawImageSource::getAutoExpHistogram(LUTu & histogram, int& histcompr) for (int i = border; i < H - border; i++) { int start, end; - getRowStartEnd(i, start, end); + getRowStartEnd (i, start, end); if (ri->getSensorType() == ST_BAYER) { // precalculate factors to avoid expensive per pixel calculations - float refwb0 = refwb[ri->FC(i, start)]; - float refwb1 = refwb[ri->FC(i, start + 1)]; + float refwb0 = refwb[ri->FC(i, start)]; + float refwb1 = refwb[ri->FC(i, start + 1)]; int j; for (j = start; j < end - 1; j += 2) { @@ -3674,12 +3678,12 @@ void RawImageSource::getAutoExpHistogram(LUTu & histogram, int& histcompr) } } else if (ri->getSensorType() == ST_FUJI_XTRANS) { // precalculate factors to avoid expensive per pixel calculations - float refwb0 = refwb[ri->XTRANSFC(i, start)]; - float refwb1 = refwb[ri->XTRANSFC(i, start + 1)]; - float refwb2 = refwb[ri->XTRANSFC(i, start + 2)]; - float refwb3 = refwb[ri->XTRANSFC(i, start + 3)]; - float refwb4 = refwb[ri->XTRANSFC(i, start + 4)]; - float refwb5 = refwb[ri->XTRANSFC(i, start + 5)]; + float refwb0 = refwb[ri->XTRANSFC(i, start)]; + float refwb1 = refwb[ri->XTRANSFC(i, start + 1)]; + float refwb2 = refwb[ri->XTRANSFC(i, start + 2)]; + float refwb3 = refwb[ri->XTRANSFC(i, start + 3)]; + float refwb4 = refwb[ri->XTRANSFC(i, start + 4)]; + float refwb5 = refwb[ri->XTRANSFC(i, start + 5)]; int j; for (j = start; j < end - 5; j += 6) { @@ -3717,7 +3721,7 @@ void RawImageSource::getAutoExpHistogram(LUTu & histogram, int& histcompr) } // Histogram MUST be 256 in size; gamma is applied, blackpoint and gain also -void RawImageSource::getRAWHistogram(LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) +void RawImageSource::getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) { // BENCHFUN histRedRaw.clear(); @@ -3755,7 +3759,7 @@ void RawImageSource::getRAWHistogram(LUTu & histRedRaw, LUTu & histGreenRaw, LUT #ifdef _OPENMP int numThreads; // reduce the number of threads under certain conditions to avoid overhead of too many critical regions - numThreads = sqrt((((H - 2 * border) * (W - 2 * border)) / 262144.f)); + numThreads = std::sqrt((((H - 2 * border) * (W - 2 * border)) / 262144.f)); numThreads = std::min(std::max(numThreads, 1), omp_get_max_threads()); #pragma omp parallel num_threads(numThreads) @@ -3784,7 +3788,7 @@ void RawImageSource::getRAWHistogram(LUTu & histRedRaw, LUTu & histGreenRaw, LUT for (int i = border; i < H - border; i++) { int start, end; - getRowStartEnd(i, start, end); + getRowStartEnd (i, start, end); if (ri->getSensorType() == ST_BAYER) { int j; @@ -3843,7 +3847,7 @@ void RawImageSource::getRAWHistogram(LUTu & histRedRaw, LUTu & histGreenRaw, LUT return f > 0.f ? (f < 1.f ? 1 : std::min(int(f), 255)) : 0; }; - for(int i = 0; i < histoSize; i++) { + for (int i = 0; i < histoSize; i++) { int idx = getidx(0, i); histRedRaw[idx] += hist[0][i]; @@ -3864,10 +3868,12 @@ void RawImageSource::getRAWHistogram(LUTu & histRedRaw, LUTu & histGreenRaw, LUT if (ri->getSensorType() == ST_BAYER) // since there are twice as many greens, correct for it for (int i = 0; i < 256; i++) { histGreenRaw[i] >>= 1; - } else if (ri->getSensorType() == ST_FUJI_XTRANS) // since Xtrans has 2.5 as many greens, correct for it + } + else if (ri->getSensorType() == ST_FUJI_XTRANS) // since Xtrans has 2.5 as many greens, correct for it for (int i = 0; i < 256; i++) { histGreenRaw[i] = (histGreenRaw[i] * 2) / 5; - } else if (ri->get_colors() == 1) { // monochrome sensor => set all histograms equal + } + else if (ri->get_colors() == 1) { // monochrome sensor => set all histograms equal histGreenRaw += histRedRaw; histBlueRaw += histRedRaw; } @@ -3876,11 +3882,11 @@ void RawImageSource::getRAWHistogram(LUTu & histRedRaw, LUTu & histGreenRaw, LUT //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::getRowStartEnd(int x, int &start, int &end) +void RawImageSource::getRowStartEnd (int x, int &start, int &end) { if (fuji) { 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; } else { start = border; @@ -3888,8 +3894,1727 @@ void RawImageSource::getRowStartEnd(int x, int &start, int &end) } } -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::getAutoWBMultipliers(double &rm, double &gm, double &bm) + +static void histoxyY(int bfhitc, int bfwitc, const array2D & xc, const array2D & yc, const array2D & Yc, LUTf &xxx, LUTf &yyy, LUTf &YYY, LUTu &histxy) +{ + //calculate histogram x y in a range of 190 colors + //this "choice" are guided by generally colors who are in nature skin, sky, etc. in those cases "steps" are small + // of course we can change to be more precise +#ifdef _OPENMP + #pragma omp parallel +#endif + { + LUTu histxythr(histxy.getSize()); + histxythr.clear(); + LUTf xxxthr(xxx.getSize()); + xxxthr.clear(); + LUTf yyythr(yyy.getSize()); + yyythr.clear(); + LUTf YYYthr(YYY.getSize()); + YYYthr.clear(); +#ifdef _OPENMP + #pragma omp for schedule(dynamic, 4) nowait +#endif + for (int y = 0; y < bfhitc ; y++) { + for (int x = 0; x < bfwitc ; x++) { + int nh = -1; + if (xc[y][x] < 0.12f && xc[y][x] > 0.03f && yc[y][x] > 0.1f) { // near Prophoto + if (yc[y][x] < 0.2f) { + nh = 0; + //blue hard + } else if (yc[y][x] < 0.3f) { + nh = 1; + //blue + } else if (yc[y][x] < 0.4f) { + nh = 2; + + } else if (yc[y][x] < 0.5f) { + //blue green + nh = 3; + } else if (yc[y][x] < 0.6f) { + nh = 4; + } else if (yc[y][x] < 0.82f) { + //green + nh = 5; + } + } else if (xc[y][x] < 0.24f && yc[y][x] > 0.05f) { + if (yc[y][x] < 0.2f) { + nh = 6; + } else if (yc[y][x] < 0.3f) { + nh = 7; + } else if (yc[y][x] < 0.4f) { + nh = 8; + } else if (yc[y][x] < 0.5f) { + nh = 9; + } else if (yc[y][x] < 0.6f) { + nh = 10; + } else if (yc[y][x] < 0.75f) { + nh = 11; + } + } else if (xc[y][x] < 0.28f && yc[y][x] > 0.1f) {//blue sky and other + if (yc[y][x] < 0.2f) { + nh = 12; + } else if (yc[y][x] < 0.25f) { + nh = 13; + } else if (yc[y][x] < 0.29f) { + nh = 14; + } else if (yc[y][x] < 0.33f) { + nh = 15; + } else if (yc[y][x] < 0.37f) { + nh = 16; + } else if (yc[y][x] < 0.4f) { + nh = 17; + } else if (yc[y][x] < 0.45f) { + nh = 18; + } else if (yc[y][x] < 0.5f) { + nh = 19; + } else if (yc[y][x] < 0.6f) { + nh = 20; + } else if (yc[y][x] < 0.75f) { + nh = 21; + } + } else if (xc[y][x] < 0.31f && yc[y][x] > 0.1f) {//near neutral others + if (yc[y][x] < 0.2f) { + nh = 22; + } else if (yc[y][x] < 0.24f) { + nh = 23; + } else if (yc[y][x] < 0.29f) { + nh = 24; + } else if (yc[y][x] < 0.32f) { + nh = 25; + } else if (yc[y][x] < 0.36f) { + nh = 26; + } else if (yc[y][x] < 0.4f) { + nh = 27; + } else if (yc[y][x] < 0.5f) { + nh = 28; + } else if (yc[y][x] < 0.7f) { + nh = 29; + } + } else if (xc[y][x] < 0.325f && yc[y][x] > 0.1f) {//neutral 34 + if (yc[y][x] < 0.2f) { + nh = 30; + } else if (yc[y][x] < 0.24f) { + nh = 31; + } else if (yc[y][x] < 0.29f) { + nh = 32; + } else if (yc[y][x] < 0.32f) { + nh = 33; + } else if (yc[y][x] < 0.33f) { + nh = 34; + } else if (yc[y][x] < 0.335f) { + nh = 35; + } else if (yc[y][x] < 0.34f) { + nh = 36; + } else if (yc[y][x] < 0.35f) { + nh = 37; + } else if (yc[y][x] < 0.37f) { + nh = 38; + } else if (yc[y][x] < 0.4f) { + nh = 39; + } else if (yc[y][x] < 0.45f) { + nh = 40; + } else if (yc[y][x] < 0.5f) { + nh = 41; + } else if (yc[y][x] < 0.55f) { + nh = 42; + } else if (yc[y][x] < 0.7f) { + nh = 43; + } + } else if (xc[y][x] < 0.335f && yc[y][x] > 0.1f) {//neutral + if (yc[y][x] < 0.2f) { + nh = 44; + } else if (yc[y][x] < 0.24f) { + nh = 45; + } else if (yc[y][x] < 0.29f) { + nh = 46; + } else if (yc[y][x] < 0.32f) { + nh = 47; + } else if (yc[y][x] < 0.33f) { + nh = 48; + } else if (yc[y][x] < 0.335f) { + nh = 49; + } else if (yc[y][x] < 0.34f) { + nh = 50; + } else if (yc[y][x] < 0.345f) { + nh = 51; + } else if (yc[y][x] < 0.35f) { + nh = 52; + } else if (yc[y][x] < 0.355f) { + nh = 53; + } else if (yc[y][x] < 0.36f) { + nh = 54; + } else if (yc[y][x] < 0.37f) { + nh = 55; + } else if (yc[y][x] < 0.38f) { + nh = 56; + } else if (yc[y][x] < 0.4f) { + nh = 57; + } else if (yc[y][x] < 0.45f) { + nh = 58; + } else if (yc[y][x] < 0.5f) { + nh = 59; + } else if (yc[y][x] < 0.55f) { + nh = 60; + } else if (yc[y][x] < 0.7f) { + nh = 61; + } + } else if (xc[y][x] < 0.340f && yc[y][x] > 0.1f) {//neutral + if (yc[y][x] < 0.2f) { + nh = 62; + } else if (yc[y][x] < 0.24f) { + nh = 63; + } else if (yc[y][x] < 0.29f) { + nh = 64; + } else if (yc[y][x] < 0.32f) { + nh = 65; + } else if (yc[y][x] < 0.325f) { + nh = 66; + } else if (yc[y][x] < 0.33f) { + nh = 67; + } else if (yc[y][x] < 0.335f) { + nh = 68; + } else if (yc[y][x] < 0.34f) { + nh = 69; + } else if (yc[y][x] < 0.345f) { + nh = 70; + } else if (yc[y][x] < 0.35f) { + nh = 71; + } else if (yc[y][x] < 0.355f) { + nh = 72; + } else if (yc[y][x] < 0.36f) { + nh = 73; + } else if (yc[y][x] < 0.37f) { + nh = 74; + } else if (yc[y][x] < 0.38f) { + nh = 75; + } else if (yc[y][x] < 0.4f) { + nh = 76; + } else if (yc[y][x] < 0.45f) { + nh = 77; + } else if (yc[y][x] < 0.5f) { + nh = 78; + } else if (yc[y][x] < 0.55f) { + nh = 79; + } else if (yc[y][x] < 0.7f) { + nh = 80; + } + } else if (xc[y][x] < 0.345f && yc[y][x] > 0.1f) {//neutral 37 + if (yc[y][x] < 0.2f) { + nh = 81; + } else if (yc[y][x] < 0.24f) { + nh = 82; + } else if (yc[y][x] < 0.29f) { + nh = 83; + } else if (yc[y][x] < 0.32f) { + nh = 84; + } else if (yc[y][x] < 0.33f) { + nh = 85; + } else if (yc[y][x] < 0.335f) { + nh = 86; + } else if (yc[y][x] < 0.34f) { + nh = 87; + } else if (yc[y][x] < 0.345f) { + nh = 88; + } else if (yc[y][x] < 0.35f) { + nh = 89; + } else if (yc[y][x] < 0.355f) { + nh = 90; + } else if (yc[y][x] < 0.36f) { + nh = 91; + } else if (yc[y][x] < 0.37f) { + nh = 92; + } else if (yc[y][x] < 0.38f) { + nh = 93; + } else if (yc[y][x] < 0.39f) { + nh = 94; + } else if (yc[y][x] < 0.4f) { + nh = 95; + } else if (yc[y][x] < 0.42f) { + nh = 96; + } else if (yc[y][x] < 0.45f) { + nh = 97; + } else if (yc[y][x] < 0.48f) { + nh = 98; + } else if (yc[y][x] < 0.5f) { + nh = 99; + } else if (yc[y][x] < 0.55f) { + nh = 100; + } else if (yc[y][x] < 0.65f) { + nh = 101; + } + } else if (xc[y][x] < 0.355f && yc[y][x] > 0.1f) {//neutral 37 + if (yc[y][x] < 0.2f) { + nh = 102; + } else if (yc[y][x] < 0.24f) { + nh = 103; + } else if (yc[y][x] < 0.29f) { + nh = 104; + } else if (yc[y][x] < 0.32f) { + nh = 105; + } else if (yc[y][x] < 0.33f) { + nh = 106; + } else if (yc[y][x] < 0.335f) { + nh = 107; + } else if (yc[y][x] < 0.34f) { + nh = 108; + } else if (yc[y][x] < 0.345f) { + nh = 109; + } else if (yc[y][x] < 0.35f) { + nh = 110; + } else if (yc[y][x] < 0.355f) { + nh = 111; + } else if (yc[y][x] < 0.36f) { + nh = 112; + } else if (yc[y][x] < 0.37f) { + nh = 113; + } else if (yc[y][x] < 0.38f) { + nh = 114; + } else if (yc[y][x] < 0.39f) { + nh = 115; + } else if (yc[y][x] < 0.4f) { + nh = 116; + } else if (yc[y][x] < 0.42f) { + nh = 117; + } else if (yc[y][x] < 0.45f) { + nh = 118; + } else if (yc[y][x] < 0.48f) { + nh = 119; + } else if (yc[y][x] < 0.5f) { + nh = 120; + } else if (yc[y][x] < 0.55f) { + nh = 121; + } else if (yc[y][x] < 0.65f) { + nh = 122; + } + } else if (xc[y][x] < 0.365f && yc[y][x] > 0.15f) { //0.4 + if (yc[y][x] < 0.2f) { + nh = 123; + } else if (yc[y][x] < 0.24f) { + nh = 124; + } else if (yc[y][x] < 0.29f) { + nh = 125; + } else if (yc[y][x] < 0.32f) { + nh = 126; + } else if (yc[y][x] < 0.33f) { + nh = 127; + } else if (yc[y][x] < 0.34f) { + nh = 128; + } else if (yc[y][x] < 0.35f) { + nh = 129; + } else if (yc[y][x] < 0.36f) { + nh = 130; + } else if (yc[y][x] < 0.37f) { + nh = 131; + } else if (yc[y][x] < 0.38f) { + nh = 132; + } else if (yc[y][x] < 0.39f) { + nh = 133; + } else if (yc[y][x] < 0.4f) { + nh = 134; + } else if (yc[y][x] < 0.42f) { + nh = 135; + } else if (yc[y][x] < 0.45f) { + nh = 136; + } else if (yc[y][x] < 0.5f) { + nh = 137; + } else if (yc[y][x] < 0.55f) { + nh = 138; + } else if (yc[y][x] < 0.63f) { + nh = 139; + } + } else if (xc[y][x] < 0.405f && yc[y][x] > 0.15f) {//45 + if (yc[y][x] < 0.2f) { + nh = 140; + } else if (yc[y][x] < 0.24f) { + nh = 141; + } else if (yc[y][x] < 0.29f) { + nh = 142; + } else if (yc[y][x] < 0.32f) { + nh = 143; + } else if (yc[y][x] < 0.34f) { + nh = 144; + } else if (yc[y][x] < 0.37f) { + nh = 145; + } else if (yc[y][x] < 0.4f) { + nh = 146; + } else if (yc[y][x] < 0.45f) { + nh = 147; + } else if (yc[y][x] < 0.5f) { + nh = 148; + } else if (yc[y][x] < 0.55f) { + nh = 149; + } else if (yc[y][x] < 0.6f) { + nh = 150; + } + } else if (xc[y][x] < 0.445f && yc[y][x] > 0.15f) {//45 + if (yc[y][x] < 0.2f) { + nh = 151; + } else if (yc[y][x] < 0.24f) { + nh = 152; + } else if (yc[y][x] < 0.29f) { + nh = 153; + } else if (yc[y][x] < 0.32f) { + nh = 154; + } else if (yc[y][x] < 0.34f) { + nh = 155; + } else if (yc[y][x] < 0.37f) { + nh = 156; + } else if (yc[y][x] < 0.4f) { + nh = 157; + } else if (yc[y][x] < 0.45f) { + nh = 158; + } else if (yc[y][x] < 0.5f) { + nh = 159; + } else if (yc[y][x] < 0.55f) { + nh = 160; + } else if (yc[y][x] < 0.58f) { + nh = 161; + } + } else if (xc[y][x] < 0.495f && yc[y][x] > 0.15f) { + if (yc[y][x] < 0.2f) { + nh = 162; + } else if (yc[y][x] < 0.24f) { + nh = 163; + } else if (yc[y][x] < 0.29f) { + nh = 164; + } else if (yc[y][x] < 0.32f) { + nh = 165; + } else if (yc[y][x] < 0.34f) { + nh = 166; + } else if (yc[y][x] < 0.37f) { + nh = 167; + } else if (yc[y][x] < 0.4f) { + nh = 168; + } else if (yc[y][x] < 0.45f) { + nh = 169; + } else if (yc[y][x] < 0.5f) { + nh = 170; + } else if (yc[y][x] < 0.55f) { + nh = 171; + } + } else if (xc[y][x] < 0.545f && yc[y][x] > 0.15f) { + if (yc[y][x] < 0.2f) { + nh = 172; + } else if (yc[y][x] < 0.24f) { + nh = 173; + } else if (yc[y][x] < 0.29f) { + nh = 174; + } else if (yc[y][x] < 0.32f) { + nh = 175; + } else if (yc[y][x] < 0.34f) { + nh = 176; + } else if (yc[y][x] < 0.37f) { + nh = 177; + } else if (yc[y][x] < 0.4f) { + nh = 178; + } else if (yc[y][x] < 0.45f) { + nh = 179; + } else if (yc[y][x] < 0.5f) { + nh = 180; + } + } else if (xc[y][x] < 0.595f && yc[y][x] > 0.15f) { + if (yc[y][x] < 0.22f) { + nh = 181; + } else if (yc[y][x] < 0.25f) { + nh = 182; + } else if (yc[y][x] < 0.3f) { + nh = 183; + } else if (yc[y][x] < 0.35f) { + nh = 184; + } else if (yc[y][x] < 0.4f) { + nh = 185; + } else if (yc[y][x] < 0.45f) { + nh = 186; + } + } else if (xc[y][x] < 0.65f && yc[y][x] > 0.12f) { + if (yc[y][x] < 0.25f) { + nh = 187; + } else if (yc[y][x] < 0.3f) { + nh = 188; + } else if (yc[y][x] < 0.35f) { + nh = 189; + } else if (yc[y][x] < 0.45f) { + nh = 190; + } + } else if (xc[y][x] < 0.75f && yc[y][x] > 0.1f) { + nh = 191; + } + if (nh >= 0) { + histxythr[nh]++; + xxxthr[nh] += xc[y][x]; + yyythr[nh] += yc[y][x]; + YYYthr[nh] += Yc[y][x]; + } + } + } +#ifdef _OPENMP + #pragma omp critical +#endif + { + histxy += histxythr; + xxx += xxxthr; + yyy += yyythr; + YYY += YYYthr; + } + } +} + +float static studentXY(const array2D & YYcurr, const array2D & reffYY, int sizcurr, int Nc, int tt) +{ + //calculate Student coeff YY + float somcurrY = 0.f; + float somreffY = 0.f; + float somcurr2Y = 0.f; + float somreff2Y = 0.f; + + for (int i = 0; i < sizcurr; i++) { + somcurrY += YYcurr[i][tt]; + //sum observations first group + } + somcurrY *= 100.f; + + for (int i = 0; i < Nc; i++) { + somreffY += reffYY[i][tt]; + //sum observations second group + } + somreffY *= 100.f; + + for (int i = 0; i < sizcurr; i++) { + somcurr2Y += SQR(YYcurr[i][tt]); + //sum sqr observations first group + } + somcurr2Y *= SQR(100.f); + + for (int i = 0; i < Nc; i++) { + somreff2Y += SQR(reffYY[i][tt]); + //sum sqr observations second group + } + somreff2Y *= SQR(100.f); + + const float somsqueccurrY = somcurr2Y - SQR(somcurrY) / sizcurr; + //sum sqr differences first + const float somsquecreffY = somreff2Y - SQR(somreffY) / Nc; + //sum sqr differences second + + const float diviY = std::sqrt(((somsqueccurrY + somsquecreffY) * (1.f / sizcurr + 1.f / Nc)) / (sizcurr + Nc - 2)); + //divisor student + const float numerY = somcurrY / sizcurr - somreffY / Nc; + //numerator student + + return numerY / diviY ; + //student coeeficient +} + +void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, const ColorManagementParams &cmp, const RAWParams &raw, const WBParams & wbpar) +{ + /* + Copyright (c) Jacques Desmis 6 - 2018 jdesmis@gmail.com + Copyright (c) Ingo Weyrich 3 - 2020 (heckflosse67@gmx.de) + + This algorithm try to find temperature correlation between 20 to 201 color between 201 spectral color and about 20 to 55 color found in the image between 192, I just found the idea in the web "correlate with chroma" instead of RGB grey point,but I don't use any algo found on the web. + + I have test many many algorithms to find the first one that work :) + Probably (sure) there are improvement to do... + + I have create a table temperature with temp and white point with 118 values between 2000K and 12000K we can obviously change these values, more...with different steps + I have create a table for tint (green)with 134 values between 0.4 to 4. + I have create or recuparate and transformed 201 spectral colors from Colorchecker24, others color and my 468 colors target, or from web flowers, etc. with a step of 5nm, I think it is large enough. + I think this value of 201 is now complete: I tested correlation with 60, 90, 100, 120, 155...better student increase with number of color, but now it seems stabilized + Of course we can increase this number :) + + 1) for the current raw file we create a table for each temp of RGB multipliers + 2) then, I choose the "camera temp" to initialize calculation (why not) + 3) for this temp, I calculated XYZ values for the 201 spectral datas + 4) then I create for the image an "histogram", but for xyY (CIE 1931 color space or CIE 1964 (default)) + 5) for each pixel (in fact to accelerate only 1/5 for and 1/5 for y), I determine for each couple xy, the number of occurences, can be change by Itcwb_precis to 3 or 9 + 6) I sort this result in ascending order + 7) in option we can sort in another manner to take into account chroma : chromax = x - white point x, chromay = y - white point y + 8) then I compare this result, with spectral datas found above in 3) with deltaE (limited to chroma) + 9) at this point we have xyY values that match Camera temp, and spectral datas associated + 10) then I recalculate RGB values from xyY histogram + 11) after, I vary temp, between 2000K to 12000K + 12) RGB values are recalculated from 10) with RGB multipliers, and then xyY are calculated for each temp + 13) spectral datas choose are recalculated with temp between 2000K to 12000K with matrix spectral calculation, that leads to xyY values + 14) I calculated for each couple xy, Student correlation (without Snedecor test) + 15) the good result, is the best correlation + 16) we have found the best temperature where color image and color references are correlate + 17) after we pass this value to improccoordinator + + 18) in a second part if camera green is out, I used an "extra" algorithm + 19) we make vary green between 2 limits (settings in option) + 20) between these green limits, we make slightly vary temp (settings in options) and recalculated RGB multipliers + 21) with this multipliers for the RGB color find in histogram we recalculate xyY + 22) we re-adjust references color for these xyY from 20) + 23) then find all Student correlation for each couple green / temp + 24) sort these Student values, and choose the minimum + 25) then for the 3 better couple "temp / green" choose the one where green is nearest from 1. + + Some variables or function are not used, keep in case of + I have test with cat02 but result are not stable enough ! why ??, therefore cat02 neutralized + This operation is done (actually) 100 times and compare Student coefficient, and keep the absolute minimum, We can probably optimize.... + But actually the goal is to find the good algorithm ! + + I think, this algo is very good in most cases :) ...to verify of course. + You can used it in images :flowers, landscape, portrait, skin, where illuminants are "normal" (daylight, blackbody) + You must avoid when illuminant is non standard (fluorescent, LED...) and also, when the subject is lost in the image (some target to generate profiles). + + You can change parameters in option.cc + Itcwb_thres : 34 by default ==> number of color used in final algorithm - between 10 and max 55 + Itcwb_sort : false by default, can improve algorithm if true, ==> sort value in something near chroma order, instead of histogram number + Itcwb_greenrange : 0 amplitude of green variation - between 0 to 2 + Itcwb_greendeltatemp : 1 - delta temp in green iterate loop for "extra" - between 0 to 4 + Itcwb_forceextra : false - if true force algorithm "extra" ("extra" is used when camera wbsettings are wrong) to all images + Itcwb_sizereference : 3 by default, can be set to 5 ==> size of reference color compare to size of histogram real color + itcwb_delta : 1 by default can be set between 0 to 5 ==> delta temp to build histogram xy - if camera temp is not probably good + itcwb_stdobserver10 : true by default - use standard observer 10°, false = standard observer 2° + itcwb_precis : 5 by default - can be set to 3 or 9 - 3 best sampling but more time...9 "old" settings - but low differences in times with 3 instead of 9 about twice time 160ms instead of 80ms for a big raw file + */ +// BENCHFUN + + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix("sRGB"); + const float wp[3][3] = { + {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, + {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, + {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} + }; + + TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix("sRGB"); + //inverse matrix user select + const float wip[3][3] = { + {static_cast(wiprof[0][0]), static_cast(wiprof[0][1]), static_cast(wiprof[0][2])}, + {static_cast(wiprof[1][0]), static_cast(wiprof[1][1]), static_cast(wiprof[1][2])}, + {static_cast(wiprof[2][0]), static_cast(wiprof[2][1]), static_cast(wiprof[2][2])} + }; + + const int bfwitc = bfw; + const int bfhitc = bfh; + + typedef struct WbGreen { + double green; + float snedecor;//1. actually but put in case of confiance interval + } WbGreen; + //green (tint) values between 0.4 to 4.0 + constexpr WbGreen gree[134] = {//symmetric coefficient between 0.717 and 1.40 + {0.400, 1.f}, + {0.420, 1.f}, + {0.440, 1.f}, + {0.460, 1.f}, + {0.480, 1.f}, + {0.500, 1.f}, + {0.520, 1.f}, + {0.540, 1.f}, + {0.550, 1.f}, + {0.560, 1.f}, + {0.570, 1.f}, + {0.580, 1.f}, + {0.590, 1.f}, + {0.600, 1.f}, + {0.610, 1.f}, + {0.620, 1.f}, + {0.630, 1.f}, + {0.640, 1.f}, + {0.650, 1.f}, + {0.660, 1.f}, + {0.670, 1.f}, + {0.680, 1.f}, + {0.690, 1.f}, + {0.700, 1.f}, + {0.714, 1.f}, + {0.727, 1.f}, + {0.741, 1.f}, + {0.755, 1.f}, + {0.769, 1.f}, + {0.784, 1.f}, + {0.800, 1.f}, + {0.806, 1.f}, + {0.813, 1.f}, + {0.820, 1.f}, + {0.826, 1.f}, + {0.833, 1.f}, + {0.840, 1.f}, + {0.847, 1.f}, + {0.855, 1.f}, + {0.862, 1.f}, + {0.870, 1.f}, + {0.877, 1.f}, + {0.885, 1.f}, + {0.893, 1.f}, + {0.901, 1.f}, + {0.909, 1.f}, + {0.917, 1.f}, + {0.926, 1.f}, + {0.935, 1.f}, + {0.943, 1.f}, + {0.952, 1.f}, + {0.962, 1.f}, + {0.971, 1.f}, + {0.980, 1.f}, + {0.990, 1.f}, + {1.000, 1.f},//55 + {1.010, 1.f}, + {1.020, 1.f}, + {1.030, 1.f}, + {1.040, 1.f}, + {1.050, 1.f}, + {1.060, 1.f}, + {1.070, 1.f}, + {1.080, 1.f}, + {1.090, 1.f}, + {1.100, 1.f}, + {1.110, 1.f}, + {1.120, 1.f}, + {1.130, 1.f}, + {1.140, 1.f}, + {1.150, 1.f}, + {1.160, 1.f}, + {1.170, 1.f}, + {1.180, 1.f}, + {1.190, 1.f}, + {1.200, 1.f}, + {1.210, 1.f}, + {1.220, 1.f}, + {1.230, 1.f}, + {1.240, 1.f}, + {1.250, 1.f}, + {1.275, 1.f}, + {1.300, 1.f}, + {1.325, 1.f}, + {1.350, 1.f}, + {1.375, 1.f}, + {1.400, 1.f}, + {1.425, 1.f}, + {1.450, 1.f}, + {1.475, 1.f}, + {1.500, 1.f}, + {1.525, 1.f}, + {1.550, 1.f}, + {1.575, 1.f}, + {1.600, 1.f}, + {1.633, 1.f}, + {1.666, 1.f}, + {1.700, 1.f}, + {1.733, 1.f}, + {1.766, 1.f}, + {1.800, 1.f}, + {1.833, 1.f}, + {1.866, 1.f}, + {1.900, 1.f}, + {1.933, 1.f}, + {1.966, 1.f}, + {2.000, 1.f}, + {2.033, 1.f}, + {2.066, 1.f}, + {2.100, 1.f}, + {2.133, 1.f}, + {2.166, 1.f}, + {2.200, 1.f}, + {2.250, 1.f}, + {2.300, 1.f}, + {2.350, 1.f}, + {2.400, 1.f}, + {2.450, 1.f}, + {2.500, 1.f}, + {2.550, 1.f}, + {2.600, 1.f}, + {2.650, 1.f}, + {2.700, 1.f}, + {2.750, 1.f}, + {2.800, 1.f}, + {2.850, 1.f}, + {2.900, 1.f}, + {2.950, 1.f}, + {3.000, 1.f}, + {3.200, 1.f}, + {3.400, 1.f}, + {3.600, 1.f}, + {3.800, 1.f}, + {4.000, 1.f} + }; + const int N_g = sizeof(gree) / sizeof(gree[0]); //number of green + + typedef struct RangeGreen { + int begin; + int end; + } RangeGreen; + + constexpr RangeGreen Rangestandard = {24, 86}; + constexpr RangeGreen Rangeextended = {15, 93}; + const RangeGreen Rangemax = {0, N_g}; + + RangeGreen Rangegreenused; + + if (settings->itcwb_greenrange == 0) { + Rangegreenused = Rangestandard; + } else if (settings->itcwb_greenrange == 1) { + Rangegreenused = Rangeextended; + } else { + Rangegreenused = Rangemax; + } + + typedef struct WbTxyz { + double Tem; + double XX; + double ZZ; + } WbTxyz; + //we can change step to increase precision if need - also in Colortemp.cc with same changes + //I don't know how to pass this structure to Colortemp ! + // X and Z values calculate for each temp between 2000K to 12000K, so no result after 12000K ! + //of course we can change the step between each temp if need + constexpr WbTxyz Txyz[118] = {//temperature Xwb Zwb 118 values x wb and y wb are calculated after, Xwb and Ywb calculated with a spreadsheet + {2001., 1.273842, 0.145295}, + {2101., 1.244008, 0.167533}, + {2201., 1.217338, 0.190697}, + {2301., 1.193444, 0.214632}, + {2401., 1.171996, 0.239195}, + {2501., 1.152883, 0.264539}, + {2605., 1.134667, 0.290722}, + {2655., 1.126659, 0.303556}, + {2705., 1.119049, 0.316446}, + {2755., 1.111814, 0.329381}, + {2803., 1.105381, 0.342193}, + {2856., 1.098258, 0.355599}, + {2910., 1.091550, 0.369645}, + {2960., 1.085649, 0.382655}, + {3003., 1.080982, 0.394258}, + {3050., 1.075727, 0.406057}, + {3103., 1.070277, 0.419815}, + {3153., 1.065384, 0.432769}, + {3203., 1.060906, 0.446161}, + {3250., 1.056535, 0.457806}, + {3303., 1.052034, 0.471422}, + {3353., 1.047990, 0.484218}, + {3400., 1.044547, 0.496719}, + {3450., 1.040667, 0.508891}, + {3500., 1.037145, 0.521523}, + {3550., 1.033783, 0.534090}, + {3600., 1.030574, 0.546590}, + {3650., 1.027510, 0.559020}, + {3699., 1.024834, 0.571722}, + {3801., 1.019072, 0.596102}, + {3851., 1.016527, 0.608221}, + {3902., 1.014244, 0.621136}, + {3952., 1.011729, 0.632447}, + {4002., 0.996153, 0.609518}, + {4052., 0.993720, 0.620805}, + {4102., 0.993908, 0.631520}, + {4152., 0.989179, 0.643262}, + {4202., 0.989283, 0.653999}, + {4252., 0.985039, 0.665536}, + {4302., 0.985067, 0.676288}, + {4352., 0.981271, 0.687599}, + {4402., 0.981228, 0.698349}, + {4452., 0.977843, 0.709425}, + {4502., 0.977736, 0.720159}, + {4552., 0.974728, 0.730993}, + {4602., 0.974562, 0.741698}, + {4652., 0.971899, 0.752284}, + {4702., 0.971681, 0.762949}, + {4752., 0.969335, 0.773285}, + {4802., 0.969069, 0.783899}, + {4827., 0.967570, 0.788836}, + {4852., 0.967011, 0.793982}, + {4877., 0.966465, 0.799108}, + {4902., 0.965933, 0.804214}, + {4927., 0.965414, 0.809229}, + {4952., 0.964908, 0.814366}, + {4977., 0.964415, 0.819412}, + {5002., 0.963934, 0.824438}, + {5027., 0.963465, 0.829444}, + {5052., 0.963008, 0.834429}, + {5077., 0.962563, 0.839395}, + {5102., 0.962129, 0.844339}, + {5127., 0.961706, 0.849263}, + {5152., 0.961294, 0.854166}, + {5177., 0.960893, 0.859049}, + {5202., 0.960501, 0.863911}, + {5252., 0.959749, 0.873572}, + {5302., 0.959313, 0.883815}, + {5352., 0.958361, 0.892644}, + {5402., 0.957903, 0.902793}, + {5452., 0.957116, 0.911379}, + {5502., 0.956639, 0.921431}, + {5552., 0.956002, 0.929779}, + {5602., 0.955509, 0.939728}, + {5652., 0.955008, 0.947842}, + {5702., 0.954502, 0.957685}, + {5752., 0.954124, 0.965569}, + {5802., 0.953608, 0.975303}, + {5852., 0.953342, 0.982963}, + {5902., 0.952818, 0.992584}, + {5952., 0.952652, 1.000025}, + {6002., 0.952122, 1.009532}, + {6052., 0.952047, 1.016759}, + {6102., 0.951514, 1.026149}, + {6152., 0.951520, 1.033168}, + {6202., 0.950985, 1.042439}, + {6252., 0.951064, 1.049256}, + {6302., 0.950530, 1.058406}, + {6352., 0.950674, 1.065027}, + {6402., 0.950143, 1.074055}, + {6452., 0.950345, 1.080484}, + {6502., 0.950201, 1.088097}, + {6552., 0.950070, 1.095633}, + {6602., 0.949952, 1.103094}, + {6652., 0.949846, 1.110479}, + {6702., 0.949752, 1.119138}, + {6752., 0.949668, 1.125027}, + {6802., 0.949596, 1.132190}, + {6902., 0.949033, 1.147691}, + {7002., 0.949402, 1.160129}, + {7152., 0.949348, 1.180429}, + {7301., 0.948896, 1.201432}, + {7451., 0.949434, 1.219076}, + {7601., 0.949099, 1.239061}, + {7751., 0.949729, 1.255559}, + {7901., 0.949498, 1.274460}, + {8151., 0.950361, 1.300912}, + {8301., 0.950253, 1.318464}, + {8451., 0.950966, 1.332651}, + {8601., 0.950941, 1.349261}, + {8801., 0.951772, 1.367421}, + {9001., 0.951969, 1.387639}, + {9201., 0.952784, 1.404422}, + {9401., 0.953081, 1.423213}, + {9901., 0.954537, 1.464134}, + {10501., 0.956321, 1.508623}, + {11001., 0.957747, 1.541281}, + {12001., 0.960440, 1.601019} + }; + const int N_t = sizeof(Txyz) / sizeof(Txyz[0]); //number of temperature White point + constexpr int Nc = 201 + 1;//201 number of reference spectral colors, I think it is enough to retrieve good values + array2D Tx(N_t, Nc); + array2D Ty(N_t, Nc); + array2D Tz(N_t, Nc); + array2D Ta(N_t, Nc); + array2D Tb(N_t, Nc); + array2D TL(N_t, Nc); + double TX[Nc]; + double TY[Nc]; + double TZ[Nc]; + std::vector good_spectral(Nc, false); + + float rmm[N_t]; + float gmm[N_t]; + float bmm[N_t]; + + constexpr int siza = 192;//size of histogram + + //tempref and greenref are camera wb values. + // I used them by default to select good spectral values !! + tempref = rtengine::min(tempref, 12000.0); + + int repref = 0; + + for (int tt = 0; tt < N_t; tt++) { + if (Txyz[tt].Tem > tempref) { + repref = tt;//show the select temp + break; + } + } + + //calculate R G B multiplier in function illuminant and temperature + const bool isMono = (ri->getSensorType() == ST_FUJI_XTRANS && raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO)) + || (ri->getSensorType() == ST_BAYER && raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)); + for (int tt = 0; tt < N_t; ++tt) { + double r, g, b; + float rm, gm, bm; + ColorTemp WBiter = ColorTemp(Txyz[tt].Tem, greenitc, 1.f, "Custom"); + WBiter.getMultipliers(r, g, b); + rm = imatrices.cam_rgb[0][0] * r + imatrices.cam_rgb[0][1] * g + imatrices.cam_rgb[0][2] * b; + gm = imatrices.cam_rgb[1][0] * r + imatrices.cam_rgb[1][1] * g + imatrices.cam_rgb[1][2] * b; + bm = imatrices.cam_rgb[2][0] * r + imatrices.cam_rgb[2][1] * g + imatrices.cam_rgb[2][2] * b; + + const float new_pre_mul[4] = { ri->get_pre_mul(0) / rm, ri->get_pre_mul(1) / gm, ri->get_pre_mul(2) / bm, ri->get_pre_mul(3) / gm }; + float new_scale_mul[4]; + const float gain = calculate_scale_mul(new_scale_mul, new_pre_mul, c_white, cblacksom, isMono, ri->get_colors()); + + rm = new_scale_mul[0] / scale_mul[0] * gain; + gm = new_scale_mul[1] / scale_mul[1] * gain; + bm = new_scale_mul[2] / scale_mul[2] * gain; + rmm[tt] = rm / gm; + gmm[tt] = 1.f; + bmm[tt] = bm / gm; + //return rmm, gmm, bmm in function of temp + } + + struct hiss { + int histnum; + int index; + bool operator()(const hiss& lhis, const hiss& rhis) + { + return lhis.histnum < rhis.histnum; + } + + } ; + + //intermediate structure + struct chrom { + float chroxy_number; + float chroxy; + float chrox; + float chroy; + float Y; + int index; + int interest; + bool operator()(const chrom& lchro, const chrom& rchro) + { + return lchro.chroxy_number < rchro.chroxy_number; + } + + } ; + + LUTu histxy(siza); //number of values for each pair xy + histxy.clear(); + + LUTf xxx(siza);//for color references calculated ==> max in images "like histogram" + xxx.clear(); + LUTf yyy(siza); + yyy.clear(); + LUTf YYY(siza);//not used directly, but necessary to keep good range + YYY.clear(); + + bool separated = true; + int w = -1; + + array2D reff_spect_yy_camera(N_t, 2 * Nc + 2); + array2D reff_spect_xx_camera(N_t, 2 * Nc + 2); + + //here we select the good spectral color inside the 113 values + //call tempxy to calculate for 201 color references Temp and XYZ with cat02 + + ColorTemp::tempxy(separated, repref, Tx, Ty, Tz, Ta, Tb, TL, TX, TY, TZ, wbpar); //calculate chroma xy (xyY) for Z known colors on under 200 illuminants + + //find the good spectral values + //calculate xy reference spectral for tempref + for (int j = 0; j < Nc ; j++) { + reff_spect_xx_camera[j][repref] = TX[j] / (TX[j] + TY[j] + TZ[j]); // x from xyY + reff_spect_yy_camera[j][repref] = TY[j] / (TX[j] + TY[j] + TZ[j]); // y from xyY + } + + array2D xc(bfwitc, bfhitc); + array2D yc(bfwitc, bfhitc); + array2D Yc(bfwitc, bfhitc); + + const int deltarepref = settings->itcwb_delta; + + for (int nn = 0, drep = -deltarepref; nn <= 2; ++nn, drep += deltarepref) { + //three loop to refine color if temp camera is probably not very good + const int rep = rtengine::LIM(repref + drep, 0, N_t); + + //initialize calculation of xy current for tempref +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int y = 0; y < bfh ; ++y) { + for (int x = 0; x < bfw ; ++x) { + const float RR = rmm[rep] * redloc[y][x]; + const float GG = gmm[rep] * greenloc[y][x]; + const float BB = bmm[rep] * blueloc[y][x]; + Color::rgbxyY(RR, GG, BB, xc[y][x], yc[y][x], Yc[y][x], wp); + } + } + //histogram xy depend of temp...but in most cases D45 ..D65.. + //calculate for this image the mean values for each family of color, near histogram x y (number) + //xy vary from x 0..0.77 y 0..0.82 + //neutral values are near x=0.34 0.33 0.315 0.37 y =0.35 0.36 0.34 + //skin are about x 0.45 0.49 y 0.4 0.47 + //blue sky x=0.25 y=0.28 and x=0.29 y=0.32 + // step about 0.02 x 0.32 0.34 y= 0.34 0.36 skin -- sky x 0.24 0.30 y 0.28 0.32 + //big step about 0.2 + + histoxyY(bfhitc, bfwitc, xc, yc, Yc, xxx, yyy, YYY, histxy); + //return histogram x and y for each temp and in a range of 158 colors (siza) + } + + // free some memory + xc.free(); + yc.free(); + Yc.free(); + //calculate x y Y + const int sizcurrref = siza;//choice of number of correlate colors in image + array2D histcurrref(N_t, sizcurrref); + array2D xx_curref(N_t, sizcurrref); + array2D yy_curref(N_t, sizcurrref); + array2D YY_curref(N_t, sizcurrref); + array2D xx_curref_reduc(N_t, sizcurrref); + array2D yy_curref_reduc(N_t, sizcurrref); + array2D YY_curref_reduc(N_t, sizcurrref); + + hiss Wbhis[siza]; + + for (int nh = 0; nh < siza; nh++) { + Wbhis[nh].histnum = histxy[nh]; + Wbhis[nh].index = nh; + } + + //sort in ascending order + std::sort(Wbhis, Wbhis + siza, Wbhis[0]); + + int n1 = 0; + int n4 = 0; + int n15 = 0; + int n30 = 0; + //part to improve + //determined the number of colors who be used after + for (int nh = 0; nh < siza; nh++) { + if (Wbhis[nh].histnum < 30) { + n30++; //keep only existing color but avoid to small + if (Wbhis[nh].histnum < 15) { + n15++; //keep only existing color but avoid to small + if (Wbhis[nh].histnum < 4) { + n4++; //keep only existing color but avoid to small + if (Wbhis[nh].histnum < 1) { + n1++; //keep only existing color but avoid to small + } + } + } + } + } + + int ntr = n30; + + if (ntr > (siza - 25)) { + ntr = n15; //if to less elements 25 elements mini + } + + if (ntr > (siza - 23)) { + ntr = n4; //if to less elements 25 elements mini + } + + if (ntr > (siza - 20)) { + ntr = n1; //if to less elements 20 elements mini - normally never be used ! + } + + int sizcurr2ref = sizcurrref - ntr; + const int sizcu30 = sizcurrref - n30; + const int sizcu4 = rtengine::min(sizcu30, 55); + + chrom wbchro[sizcu4]; + const float swpr = Txyz[repref].XX + Txyz[repref].ZZ + 1.f; + const float xwpr = Txyz[repref].XX / swpr;//white point for tt in xy coordiantes + const float ywpr = 1.f / swpr; + + for (int i = 0; i < sizcu4; ++i) { //take the max values + histcurrref[i][repref] = Wbhis[siza - (i + 1)].histnum; + xx_curref[i][repref] = xxx[Wbhis[siza - (i + 1)].index] / histcurrref[i][repref]; + yy_curref[i][repref] = yyy[Wbhis[siza - (i + 1)].index] / histcurrref[i][repref]; + YY_curref[i][repref] = YYY[Wbhis[siza - (i + 1)].index] / histcurrref[i][repref]; + } + + float estimchrom = 0.f; + //estimate chromaticity for references + for (int nh = 0; nh < sizcu4; ++nh) { + const float chxy = std::sqrt(SQR(xx_curref[nh][repref] - xwpr) + SQR(yy_curref[nh][repref] - ywpr)); + wbchro[nh].chroxy_number = chxy * std::sqrt(histcurrref[nh][repref]); + wbchro[nh].chroxy = std::sqrt(chxy); + wbchro[nh].chrox = xx_curref[nh][repref]; + wbchro[nh].chroy = yy_curref[nh][repref]; + wbchro[nh].Y = YY_curref[nh][repref]; + wbchro[nh].index = nh; + estimchrom += chxy; + } + + estimchrom /= sizcu4; + if (settings->verbose) { + printf("estimchrom=%f\n", estimchrom); + } + if (settings->itcwb_sort) { //sort in ascending with chroma values + std::sort(wbchro, wbchro + sizcu4, wbchro[0]); + } + + const int maxval = rtengine::LIM(settings->itcwb_thres, 10, 55);//max values of color to find correllation + + sizcurr2ref = rtengine::min(sizcurr2ref, maxval); //keep about the biggest values, + + for (int i = 0; i < sizcurr2ref; ++i) { + //is condition chroxy necessary ? + if (wbchro[sizcu4 - (i + 1)].chrox > 0.1f && wbchro[sizcu4 - (i + 1)].chroy > 0.1f && wbchro[sizcu4 - (i + 1)].chroxy > 0.0f) { //suppress value too far from reference spectral + w++; + xx_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].chrox; + yy_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].chroy; + YY_curref_reduc[w][repref] = wbchro[sizcu4 - (i + 1)].Y; + } + } + + //calculate deltaE xx to find best values of spectrals datas - limited to chroma values + int maxnb = rtengine::LIM(settings->itcwb_sizereference, 1, 5); + + if (settings->itcwb_thres > 55) { + maxnb = 201 / settings->itcwb_thres; + } + + for (int nb = 1; nb <= maxnb; ++nb) { //max 5 iterations for Itcwb_thres=33, after trial 3 is good in most cases but in some cases 5 + for (int i = 0; i < w; ++i) { + float mindeltaE = 100000.f; + int kN = 0; + + for (int j = 0; j < Nc ; j++) { + if (!good_spectral[j]) { + const float deltaE = SQR(xx_curref_reduc[i][repref] - reff_spect_xx_camera[j][repref]) + SQR(yy_curref_reduc[i][repref] - reff_spect_yy_camera[j][repref]); + + if (deltaE < mindeltaE) { + mindeltaE = deltaE; + kN = j; + } + } + } + + good_spectral[kN] = true;//good spectral are spectral color that match color histogram xy + } + } + + // reuse some buffers + array2D& R_curref_reduc = xx_curref_reduc; + array2D& G_curref_reduc = yy_curref_reduc; + array2D& B_curref_reduc = YY_curref_reduc; + + //reconvert to RGB for "reduction" + for (int i = 0; i < w; i++) { + const float X = 65535.f * xx_curref_reduc[i][repref] * YY_curref_reduc[i][repref] / yy_curref_reduc[i][repref]; + const float Y = 65535.f * YY_curref_reduc[i][repref]; + const float Z = 65535.f * (1.f - xx_curref_reduc[i][repref] - yy_curref_reduc[i][repref]) * YY_curref_reduc[i][repref] / yy_curref_reduc[i][repref]; + float r, g, b; + Color::xyz2rgb(X, Y, Z, r, g, b, wip); + R_curref_reduc[i][repref] = r / rmm[repref]; + G_curref_reduc[i][repref] = g / gmm[repref]; + B_curref_reduc[i][repref] = b / bmm[repref]; + + } + +//end first part + + //Now begin real calculations + separated = false; + //recalculate histogram with good values and not estimated + ColorTemp::tempxy(separated, repref, Tx, Ty, Tz, Ta, Tb, TL, TX, TY, TZ, wbpar); //calculate chroma xy (xyY) for Z known colors on under 90 illuminants + //calculate x y Y + int sizcurr = siza;//choice of number of correlate colors in image + array2D xxyycurr_reduc(N_t, 2 * sizcurr); + array2D reff_spect_xxyy(N_t, 2 * Nc + 2); + array2D reff_spect_xxyy_prov(N_t, 2 * Nc + 2); + + float minstud = 100000.f; + int goodref = 1; + +//calculate x y z for each pixel with multiplier rmm gmm bmm + + for (int tt = 0; tt < N_t; ++tt) {//N_t + for (int i = 0; i < w; ++i) { + float unused; + + const float RR = rmm[tt] * R_curref_reduc[i][repref]; + const float GG = gmm[tt] * G_curref_reduc[i][repref]; + const float BB = bmm[tt] * B_curref_reduc[i][repref]; + Color::rgbxyY(RR, GG, BB, xxyycurr_reduc[2 * i][tt], xxyycurr_reduc[2 * i + 1][tt], unused, wp); + } + + for (int j = 0; j < Nc ; ++j) { + reff_spect_xxyy_prov[2 * j][tt] = Tx[j][tt] / (Tx[j][tt] + Ty[j][tt] + Tz[j][tt]); // x from xyY + reff_spect_xxyy_prov[2 * j + 1][tt] = Ty[j][tt] / (Tx[j][tt] + Ty[j][tt] + Tz[j][tt]); // y from xyY + } + + int kk = -1; + + for (int i = 0; i < Nc ; ++i) { + if (good_spectral[i]) { + kk++; + //we calculate now absolute chroma for each spectral color + reff_spect_xxyy[2 * kk][tt] = reff_spect_xxyy_prov[2 * i][tt]; + reff_spect_xxyy[2 * kk + 1][tt] = reff_spect_xxyy_prov[2 * i + 1][tt]; + } + } + + const float abstud = std::fabs(studentXY(xxyycurr_reduc, reff_spect_xxyy, 2 * w, 2 * kk, tt)); + + if (abstud < minstud) { // find the minimum Student + minstud = abstud; + goodref = tt; + } + } + + if (extra) {//always used because I made this choice, brings better results + struct Tempgreen { + float student; + int tempref; + int greenref; + bool operator()(const Tempgreen& ltg, const Tempgreen& rtg) + { + return ltg.student < rtg.student; + } + }; + Tempgreen Tgstud[N_g]; + + for (int i = 0; i < N_g; ++i) {//init variables with + Tgstud[i].student = 1000.f;//max value to initialize + Tgstud[i].tempref = 57;//5002K + Tgstud[i].greenref = 55;// 1.f + + } + + const int dgoodref = rtengine::min(settings->itcwb_greendeltatemp, 4); + const int scantempbeg = rtengine::max(goodref - (dgoodref + 1), 1); + const int scantempend = rtengine::min(goodref + dgoodref, N_t - 1); + for (int gr = Rangegreenused.begin; gr < Rangegreenused.end; ++gr) { + float minstudgr = 100000.f; + int goodrefgr = 1; + + for (int tt = scantempbeg; tt < scantempend; ++tt) { + double r, g, b; + ColorTemp WBiter(Txyz[tt].Tem, gree[gr].green, 1.f, "Custom"); + WBiter.getMultipliers(r, g, b); + float rm = imatrices.cam_rgb[0][0] * r + imatrices.cam_rgb[0][1] * g + imatrices.cam_rgb[0][2] * b; + float gm = imatrices.cam_rgb[1][0] * r + imatrices.cam_rgb[1][1] * g + imatrices.cam_rgb[1][2] * b; + float bm = imatrices.cam_rgb[2][0] * r + imatrices.cam_rgb[2][1] * g + imatrices.cam_rgb[2][2] * b; + //recalculate Multipliers now with good range of temp and green + + const float new_pre_mul[4] = { ri->get_pre_mul(0) / rm, ri->get_pre_mul(1) / gm, ri->get_pre_mul(2) / bm, ri->get_pre_mul(3) / gm }; + float new_scale_mul[4]; + const float gain = calculate_scale_mul(new_scale_mul, new_pre_mul, c_white, cblacksom, isMono, ri->get_colors()); + + rm = new_scale_mul[0] / scale_mul[0] * gain; + gm = new_scale_mul[1] / scale_mul[1] * gain; + bm = new_scale_mul[2] / scale_mul[2] * gain; + rmm[tt] = rm / gm; + gmm[tt] = 1.f; + bmm[tt] = bm / gm; + } + + + for (int tt = scantempbeg; tt < scantempend; ++tt) {//N_t + for (int i = 0; i < w; ++i) { + float unused; + + const float RR = rmm[tt] * R_curref_reduc[i][repref]; + const float GG = gmm[tt] * G_curref_reduc[i][repref]; + const float BB = bmm[tt] * B_curref_reduc[i][repref]; + Color::rgbxyY(RR, GG, BB, xxyycurr_reduc[2 * i][tt], xxyycurr_reduc[2 * i + 1][tt], unused, wp); + } + //recalculate xy spectral now with good range of temp and green + + for (int j = 0; j < Nc ; ++j) { + reff_spect_xxyy_prov[2 * j][tt] = Tx[j][tt] / (Tx[j][tt] + Ty[j][tt] + Tz[j][tt]); // x from xyY + reff_spect_xxyy_prov[2 * j + 1][tt] = Ty[j][tt] / (Tx[j][tt] + Ty[j][tt] + Tz[j][tt]); // y from xyY + } + + int kkg = -1; + for (int i = 0; i < Nc ; ++i) { + if (good_spectral[i]) { + kkg++; + reff_spect_xxyy[2 * kkg][tt] = reff_spect_xxyy_prov[2 * i][tt]; + reff_spect_xxyy[2 * kkg + 1][tt] = reff_spect_xxyy_prov[2 * i + 1][tt]; + } + } + //now we have good spectral datas + //claculate student correlation + const float abstudgr = std::fabs(studentXY(xxyycurr_reduc, reff_spect_xxyy, 2 * w, 2 * kkg, tt)); + + if (abstudgr < minstudgr) { // find the minimum Student + minstudgr = abstudgr; + goodrefgr = tt; + } + //found the values + Tgstud[gr].tempref = goodrefgr; + Tgstud[gr].greenref = gr; + Tgstud[gr].student = minstudgr; + + } + } + + std::sort(Tgstud, Tgstud + N_g, Tgstud[0]); + + //now search the value of green the nearest of 1 with a good student value + // I take the 3 first values + //I admit a symetrie in green coefiicient for rgb multiplier...probably not exactly true + //perhaps we can used a Snedecor test ? but why...at least we have confidence interval > 90% + int greengood; + int greengoodprov; + int goodrefprov; + float studprov; + const int goodref0 = Tgstud[0].tempref; + const int greengood0 = Tgstud[0].greenref - 55;//55 green = 1 + const float stud0 = Tgstud[0].student; + const int goodref1 = Tgstud[1].tempref; + const float stud1 = Tgstud[1].student; + const int greengood1 = Tgstud[1].greenref - 55; + const int goodref2 = Tgstud[2].tempref; + const int greengood2 = Tgstud[2].greenref - 55; + const float stud2 = Tgstud[2].student; + + if (std::fabs(greengood2) < std::fabs(greengood1)) { + greengoodprov = greengood2; + goodrefprov = goodref2; + studprov = stud2; + } else { + greengoodprov = greengood1; + goodrefprov = goodref1; + studprov = stud1; + + } + + if (std::fabs(greengoodprov) < std::fabs(greengood0)) { + goodref = goodrefprov; + greengood = greengoodprov + 55; + studgood = studprov; + + } else { + goodref = goodref0; + greengood = greengood0 + 55; + studgood = stud0; + } + + tempitc = Txyz[goodref].Tem; + greenitc = gree[greengood].green; + if (estimchrom < 0.025f) { + float ac = -2.40f * estimchrom + 0.06f;//small empirical correction, maximum 0.06 if chroma=0 for all image, currently for very low chroma +0.02 + greenitc += ac; + } + } + + avg_rm = 10000.f * rmm[goodref]; + avg_gm = 10000.f * gmm[goodref]; + avg_bm = 10000.f * bmm[goodref]; + + if (!extra) { + tempitc = Txyz[goodref].Tem; + } + //now we have temp green and student + if (settings->verbose) { + printf("ITCWB tempitc=%f gritc=%f stud=%f \n", tempitc, greenitc, studgood); + } +} + +void RawImageSource::WBauto(double & tempref, double & greenref, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double & avg_rm, double & avg_gm, double & avg_bm, double & tempitc, double & greenitc, float & studgood, bool & twotimes, const WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const ColorManagementParams & cmp, const RAWParams & raw) +{ +// BENCHFUN + //auto white balance + //put green (tint) in reasonable limits for an Daylight illuminant + // avoid too bi or too low values + if (wbpar.method == "autitcgreen") { + bool extra = false; + + if (greenref > 0.5 && greenref < 1.3) {// 0.5 and 1.3 arbitraties values + greenitc = greenref; + + if (settings->itcwb_forceextra) { + extra = true; + } + } else { + greenitc = 1.; + extra = true; + } + + tempitc = 5000.; + + ItcWB(extra, tempref, greenref, tempitc, greenitc, studgood, redloc, greenloc, blueloc, bfw, bfh, avg_rm, avg_gm, avg_bm, cmp, raw, wbpar); + } +} + +void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) +{ +// BENCHFUN + //used by auto WB local to calculate red, green, blue in local region + int precision = 5; + if (settings->itcwb_precis == 5) { + precision = 5; + } else if (settings->itcwb_precis < 5) { + precision = 3; + } else if (settings->itcwb_precis > 5) { + precision = 9; + } + + const int bfw = W / precision + ((W % precision) > 0 ? 1 : 0);// 5 arbitrary value can be change to 3 or 9 ; + const int bfh = H / precision + ((H % precision) > 0 ? 1 : 0); + + if (! greenloc) { + greenloc(bfw, bfh); + } + + if (! redloc) { + redloc(bfw, bfh); + } + + if (! blueloc) { + blueloc(bfw, bfh); + } + + double avgL = 0.0; + //center data on normal values + int nn = 0; + +#ifdef _OPENMP + #pragma omp parallel for reduction(+:avgL, nn) +#endif + for (int i = 0; i < H; i ++) { + for (int j = 0; j < W; j++) { + const float LL = 0.299f * red[i][j] + 0.587f * green[i][j] + 0.114f * blue[i][j]; + avgL += static_cast(LL); + nn++; + } + } + avgL /= nn; + + double vari = 0.f; + int mm = 0; + +#ifdef _OPENMP + #pragma omp parallel for reduction(+:vari, mm) +#endif + for (int i = 0; i < H; i++) + for (int j = 0; j < W; j++) { + const float LL = 0.299f * red[i][j] + 0.587f * green[i][j] + 0.114f * blue[i][j]; + vari += SQR(LL - avgL); + mm++; + } + + const float sig = std::sqrt(vari / mm); + const float multip = 60000.f / (avgL + 2.f * sig); + //multip to put red, blue, green in a good range +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int i = 0; i < bfh; ++i) { + const int ii = i * precision; + if (ii < H) { + for (int j = 0, jj = 0; j < bfw; ++j, jj += precision) { + redloc[i][j] = red[ii][jj] * multip; + greenloc[i][j] = green[ii][jj] * multip; + blueloc[i][j] = blue[ii][jj] * multip; + } + } + } +} + +void RawImageSource::getAutoWBMultipliersitc(double & tempref, double & greenref, double & tempitc, double & greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double & rm, double & gm, double & bm, const WBParams & wbpar, const ColorManagementParams & cmp, const RAWParams & raw) +{ +// BENCHFUN + constexpr double clipHigh = 64000.0; + + if (ri->get_colors() == 1) { + rm = gm = bm = 1; + return; + } + + double avg_r = 0; + double avg_g = 0; + double avg_b = 0; + int rn = 0, gn = 0, bn = 0; + double avg_rm, avg_gm, avg_bm; + if (wbpar.method == "autold") { + if (fuji) { + for (int i = 32; i < H - 32; i++) { + int fw = ri->get_FujiWidth(); + int start = ABS(fw - i) + 32; + int end = min(H + W - fw - i, fw + i) - 32; + + for (int j = start; j < end; j++) { + if (ri->getSensorType() != ST_BAYER) { + double dr = CLIP(initialGain * (rawData[i][3 * j] )); + double dg = CLIP(initialGain * (rawData[i][3 * j + 1])); + double db = CLIP(initialGain * (rawData[i][3 * j + 2])); + + if (dr > clipHigh || dg > clipHigh || db > clipHigh) { + continue; + } + + avg_r += dr; + avg_g += dg; + avg_b += db; + rn = gn = ++bn; + } else { + int c = FC(i, j); + double d = CLIP(initialGain * (rawData[i][j])); + + if (d > clipHigh) { + continue; + } + + // Let's test green first, because they are more numerous + if (c == 1) { + avg_g += d; + gn++; + } else if (c == 0) { + avg_r += d; + rn++; + } else { /*if (c==2)*/ + avg_b += d; + bn++; + } + } + } + } + } else { + if (ri->getSensorType() != ST_BAYER) { + if (ri->getSensorType() == ST_FUJI_XTRANS) { + const double compval = clipHigh / initialGain; +#ifdef _OPENMP + #pragma omp parallel +#endif + { + double avg_c[3] = {0.0}; + int cn[3] = {0}; +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) nowait +#endif + + for (int i = 32; i < H - 32; i++) { + for (int j = 32; j < W - 32; j++) { + // each loop read 1 rgb triplet value + double d = rawData[i][j]; + + if (d > compval) { + continue; + } + + int c = ri->XTRANSFC(i, j); + avg_c[c] += d; + cn[c]++; + } + } + +#ifdef _OPENMP + #pragma omp critical +#endif + { + avg_r += avg_c[0]; + avg_g += avg_c[1]; + avg_b += avg_c[2]; + rn += cn[0]; + gn += cn[1]; + bn += cn[2]; + } + } + avg_r *= initialGain; + avg_g *= initialGain; + avg_b *= initialGain; + } else { + for (int i = 32; i < H - 32; i++) + for (int j = 32; j < W - 32; j++) { + // each loop read 1 rgb triplet value + + double dr = CLIP(initialGain * (rawData[i][3 * j] )); + double dg = CLIP(initialGain * (rawData[i][3 * j + 1])); + double db = CLIP(initialGain * (rawData[i][3 * j + 2])); + + if (dr > clipHigh || dg > clipHigh || db > clipHigh) { + continue; + } + + avg_r += dr; + rn++; + avg_g += dg; + avg_b += db; + } + + gn = rn; + bn = rn; + } + } else { + //determine GRBG coset; (ey,ex) is the offset of the R subarray + int ey, ex; + + if (ri->ISGREEN(0, 0)) { //first pixel is G + if (ri->ISRED(0, 1)) { + ey = 0; + ex = 1; + } else { + ey = 1; + ex = 0; + } + } else {//first pixel is R or B + if (ri->ISRED(0, 0)) { + ey = 0; + ex = 0; + } else { + ey = 1; + ex = 1; + } + } + + const double compval = clipHigh / initialGain; +#ifdef _OPENMP + #pragma omp parallel for reduction(+:avg_r,avg_g,avg_b,rn,gn,bn) schedule(dynamic,8) +#endif + + for (int i = 32; i < H - 32; i += 2) + for (int j = 32; j < W - 32; j += 2) { + //average each Bayer quartet component individually if non-clipped + double d[2][2]; + d[0][0] = rawData[i][j]; + d[0][1] = rawData[i][j + 1]; + d[1][0] = rawData[i + 1][j]; + d[1][1] = rawData[i + 1][j + 1]; + + if (d[ey][ex] <= compval) { + avg_r += d[ey][ex]; + rn++; + } + + if (d[1 - ey][ex] <= compval) { + avg_g += d[1 - ey][ex]; + gn++; + } + + if (d[ey][1 - ex] <= compval) { + avg_g += d[ey][1 - ex]; + gn++; + } + + if (d[1 - ey][1 - ex] <= compval) { + avg_b += d[1 - ey][1 - ex]; + bn++; + } + } + + avg_r *= initialGain; + avg_g *= initialGain; + avg_b *= initialGain; + + } + } + } + + if (wbpar.method == "autitcgreen") { + bool twotimes = false; + int precision = 5; + if (settings->itcwb_precis == 5) { + precision = 5; + } else if (settings->itcwb_precis < 5) { + precision = 3; + } else if (settings->itcwb_precis > 5) { + precision = 9; + } + + const int bfw = W / precision + ((W % precision) > 0 ? 1 : 0);// 5 arbitrary value can be change to 3 or 9 ; + const int bfh = H / precision + ((H % precision) > 0 ? 1 : 0); + WBauto(tempref, greenref, redloc, greenloc, blueloc, bfw, bfh, avg_rm, avg_gm, avg_bm, tempitc, greenitc, studgood, twotimes, wbpar, begx, begy, yEn, xEn, cx, cy, cmp, raw); + } + + redloc(0, 0); + greenloc(0, 0); + blueloc(0, 0); + + if (settings->verbose) { + printf ("AVG: %g %g %g\n", avg_r / std::max(1, rn), avg_g / std::max(1, gn), avg_b / std::max(1, bn)); + } + + if (wbpar.method == "autitcgreen") { + //not used + redAWBMul = rm = avg_rm * refwb_red; + greenAWBMul = gm = avg_gm * refwb_green; + blueAWBMul = bm = avg_bm * refwb_blue; + } else { + const double reds = avg_r / std::max(1, rn) * refwb_red; + const double greens = avg_g / std::max(1, gn) * refwb_green; + const double blues = avg_b / std::max(1, bn) * refwb_blue; + redAWBMul = rm = imatrices.rgb_cam[0][0] * reds + imatrices.rgb_cam[0][1] * greens + imatrices.rgb_cam[0][2] * blues; + greenAWBMul = gm = imatrices.rgb_cam[1][0] * reds + imatrices.rgb_cam[1][1] * greens + imatrices.rgb_cam[1][2] * blues; + blueAWBMul = bm = imatrices.rgb_cam[2][0] * reds + imatrices.rgb_cam[2][1] * greens + imatrices.rgb_cam[2][2] * blues; + } + +} + +void RawImageSource::getAutoWBMultipliers (double &rm, double &gm, double &bm) { // BENCHFUN constexpr double clipHigh = 64000.0; @@ -3921,12 +5646,12 @@ void RawImageSource::getAutoWBMultipliers(double &rm, double &gm, double &bm) if (fuji) { for (int i = 32; i < H - 32; i++) { 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; for (int j = start; j < end; j++) { if (ri->getSensorType() != ST_BAYER) { - double dr = CLIP(initialGain * (rawData[i][3 * j])); + double dr = CLIP(initialGain * (rawData[i][3 * j] )); double dg = CLIP(initialGain * (rawData[i][3 * j + 1])); double db = CLIP(initialGain * (rawData[i][3 * j + 2])); @@ -4009,7 +5734,7 @@ void RawImageSource::getAutoWBMultipliers(double &rm, double &gm, double &bm) for (int j = 32; j < W - 32; j++) { // each loop read 1 rgb triplet value - double dr = CLIP(initialGain * (rawData[i][3 * j])); + double dr = CLIP(initialGain * (rawData[i][3 * j] )); double dg = CLIP(initialGain * (rawData[i][3 * j + 1])); double db = CLIP(initialGain * (rawData[i][3 * j + 2])); @@ -4030,7 +5755,7 @@ void RawImageSource::getAutoWBMultipliers(double &rm, double &gm, double &bm) //determine GRBG coset; (ey,ex) is the offset of the R subarray int ey, ex; - if (ri->ISGREEN(0, 0)) { //first pixel is G + if (ri->ISGREEN(0, 0)) { //first pixel is G if (ri->ISRED(0, 1)) { ey = 0; ex = 1; @@ -4091,24 +5816,21 @@ void RawImageSource::getAutoWBMultipliers(double &rm, double &gm, double &bm) } if (settings->verbose) { - printf("AVG: %g %g %g\n", avg_r / std::max(1, rn), avg_g / std::max(1, gn), avg_b / std::max(1, bn)); + printf ("AVG: %g %g %g\n", avg_r / std::max(1, rn), avg_g / std::max(1, gn), avg_b / std::max(1, bn)); } // return ColorTemp (pow(avg_r/rn, 1.0/6.0)*img_r, pow(avg_g/gn, 1.0/6.0)*img_g, pow(avg_b/bn, 1.0/6.0)*img_b); - double reds = avg_r / std::max(1, rn) * refwb_red; + double reds = avg_r / std::max(1, rn) * refwb_red; double greens = avg_g / std::max(1, gn) * refwb_green; - double blues = avg_b / std::max(1, bn) * refwb_blue; + double blues = avg_b / std::max(1, bn) * refwb_blue; - redAWBMul = rm = imatrices.rgb_cam[0][0] * reds + imatrices.rgb_cam[0][1] * greens + imatrices.rgb_cam[0][2] * blues; + redAWBMul = rm = imatrices.rgb_cam[0][0] * reds + imatrices.rgb_cam[0][1] * greens + imatrices.rgb_cam[0][2] * blues; greenAWBMul = gm = imatrices.rgb_cam[1][0] * reds + imatrices.rgb_cam[1][1] * greens + imatrices.rgb_cam[1][2] * blues; - blueAWBMul = bm = imatrices.rgb_cam[2][0] * reds + imatrices.rgb_cam[2][1] * greens + imatrices.rgb_cam[2][2] * blues; + blueAWBMul = bm = imatrices.rgb_cam[2][0] * reds + imatrices.rgb_cam[2][1] * greens + imatrices.rgb_cam[2][2] * blues; } -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -ColorTemp RawImageSource::getSpotWB(std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) +ColorTemp RawImageSource::getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) { int x; @@ -4121,7 +5843,7 @@ ColorTemp RawImageSource::getSpotWB(std::vector &red, std::vector &red, std::vector= 0 && yv >= 0 && xv < W && yv < H) { - if (ri->ISXTRANSRED(yv, xv)) { //RED + if (ri->ISXTRANSRED(yv, xv)) { //RED rloc += (rawData[yv][xv]); rnbrs++; continue; - } else if (ri->ISXTRANSBLUE(yv, xv)) { //BLUE + } else if (ri->ISXTRANSBLUE(yv, xv)) { //BLUE bloc += (rawData[yv][xv]); bnbrs++; continue; @@ -4164,11 +5886,11 @@ ColorTemp RawImageSource::getSpotWB(std::vector &red, std::vector 52500 || + if (initialGain * (rawData[yr][3 * xr] ) > 52500 || initialGain * (rawData[yg][3 * xg + 1]) > 52500 || initialGain * (rawData[yb][3 * xb + 2]) > 52500) { continue; @@ -4180,7 +5902,7 @@ ColorTemp RawImageSource::getSpotWB(std::vector &red, std::vector= 0 && ymin >= 0 && xmax < W && ymax < H) { - reds += (rawData[yr][3 * xr]); + reds += (rawData[yr][3 * xr] ); greens += (rawData[yg][3 * xg + 1]); blues += (rawData[yb][3 * xb + 2]); rn++; @@ -4193,7 +5915,7 @@ ColorTemp RawImageSource::getSpotWB(std::vector &red, std::vector &red, std::vector &red, std::vector &red, std::vector &red, std::vector cForwardPoints; - cForwardPoints.push_back(double (DCT_Spline)); // The first value is the curve type + cForwardPoints.push_back(double(DCT_Spline)); // The first value is the curve type std::vector cInversePoints; - cInversePoints.push_back(double (DCT_Spline)); // The first value is the curve type + cInversePoints.push_back(double(DCT_Spline)); // The first value is the curve type for (unsigned int i = 0; i < sizeof(phase_one_forward) / sizeof(phase_one_forward[0]); i += 2) { cForwardPoints.push_back(phase_one_forward[i + 0]); @@ -4452,7 +6171,7 @@ void RawImageSource::init() void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int &B) { - if(d1x) { // Nikon D1x has special sensor. We just skip it + if (d1x) { // Nikon D1x has special sensor. We just skip it R = G = B = 0; return; } @@ -4460,15 +6179,14 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int int ynew = y + border; rotate += ri->get_rotateDegree(); rotate %= 360; - if (rotate == 90) { - std::swap(xnew, ynew); + std::swap(xnew,ynew); ynew = H - 1 - ynew; } else if (rotate == 180) { xnew = W - 1 - xnew; ynew = H - 1 - ynew; } else if (rotate == 270) { - std::swap(xnew, ynew); + std::swap(xnew,ynew); xnew = W - 1 - xnew; } @@ -4476,23 +6194,16 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int ynew = LIM(ynew, 0, H - 1); int c = ri->getSensorType() == ST_FUJI_XTRANS ? ri->XTRANSFC(ynew,xnew) : ri->FC(ynew,xnew); int val = round(rawData[ynew][xnew] / scale_mul[c]); - if (c == 0) { - R = val; - G = 0; - B = 0; + R = val; G = 0; B = 0; } else if (c == 2) { - R = 0; - G = 0; - B = val; + R = 0; G = 0; B = val; } else { - R = 0; - G = val; - B = 0; + R = 0; G = val; B = 0; } } -void RawImageSource::cleanup() +void RawImageSource::cleanup () { delete phaseOneIccCurve; delete phaseOneIccCurveInv; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index b514b24a3..3c19efd67 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -26,6 +26,7 @@ #include "colortemp.h" #include "iimage.h" #include "imagesource.h" +#include "procparams.h" #define HR_SCALE 2 @@ -86,11 +87,13 @@ protected: // the interpolated green plane: array2D green; + array2D greenloc; // the interpolated red plane: array2D red; + array2D redloc; // the interpolated blue plane: array2D blue; - // the interpolated green plane: + array2D blueloc; array2D* greenCache; // the interpolated red plane: array2D* redCache; @@ -108,6 +111,7 @@ protected: void hlRecovery(const std::string &method, float* red, float* green, float* blue, int width, float* hlmax); void transformRect(const PreviewProps &pp, int tran, int &sx1, int &sy1, int &width, int &height, int &fw); void transformPosition(int x, int y, int tran, int& tx, int& ty); + void ItcWB(bool extra, double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::WBParams & wbpar); unsigned FC(int row, int col) const; inline void getRowStartEnd (int x, int &start, int &end); @@ -120,14 +124,14 @@ public: int load(const Glib::ustring &fname) override { return load(fname, false); } int load(const Glib::ustring &fname, bool firstFrameOnly); void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) override; - void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) override; + void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms, std::array& filmBaseValues) override; bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const procparams::FilmNegativeParams ¤tParams, std::array& newExps) override; + bool getRawSpotValues(Coord2D spot, int spotSize, int tran, const procparams::FilmNegativeParams ¶ms, std::array& rawValues) override; void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache = false) override; void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) override; void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) override; void retinexPrepareBuffers (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI) override; - void flushRawData () override; - void flushRGB () override; + void flush () override; void HLRecovery_Global (const procparams::ToneCurveParams &hrp) override; void refinement(int PassCount); void setBorder(unsigned int rawBorder) override {border = rawBorder;} @@ -139,6 +143,9 @@ public: void processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, const float black[4]); void copyOriginalPixels(const procparams::RAWParams &raw, RawImage *ri, RawImage *riDark, RawImage *riFlatFile, array2D &rawData ); void scaleColors (int winx, int winy, int winw, int winh, const procparams::RAWParams &raw, array2D &rawData); // raw for cblack + void WBauto(double &tempref, double &greenref, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &studgood, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) override; + void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) override; + void getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) override; void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hrp, const procparams::RAWParams &raw) override; eSensorType getSensorType () const override; diff --git a/rtengine/rt_math.h b/rtengine/rt_math.h index 9342f5430..6d4799254 100644 --- a/rtengine/rt_math.h +++ b/rtengine/rt_math.h @@ -44,6 +44,12 @@ constexpr T pow4(T x) return SQR(SQR(x)); } +template +constexpr T pow5(T x) +{ + return x * pow4(x); +} + template constexpr const T& min(const T& a) { diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index ad97e1b55..f40b88aae 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -356,6 +356,8 @@ public : virtual void autoCamChanged(double ccam, double ccamout) = 0; virtual void adapCamChanged(double cadap) = 0; virtual void ybCamChanged(int yb) = 0; + virtual void wbCamChanged(double tem, double tin) = 0; + }; class AutoChromaListener @@ -418,7 +420,7 @@ class AutoWBListener { public: virtual ~AutoWBListener() = default; - virtual void WBChanged(double temp, double green) = 0; + virtual void WBChanged(double temp, double green, float studgood) = 0; }; class FrameCountListener @@ -464,6 +466,13 @@ public: }; +class FilmNegListener +{ +public: + virtual ~FilmNegListener() = default; + virtual void filmBaseValuesChanged(std::array rgb) = 0; +}; + /** This class represents a detailed part of the image (looking through a kind of window). * It can be created and destroyed with the appropriate members of StagedImageProcessor. * Several crops can be assigned to the same image. */ @@ -551,6 +560,8 @@ public: virtual void getCamWB (double& temp, double& green) = 0; virtual void getSpotWB (int x, int y, int rectSize, double& temp, double& green) = 0; virtual bool getFilmNegativeExponents(int xA, int yA, int xB, int yB, std::array& newExps) = 0; + virtual bool getRawSpotValues (int x, int y, int spotSize, std::array& rawValues) = 0; + virtual void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) = 0; virtual void saveInputICCReference (const Glib::ustring& fname, bool apply_wb) = 0; @@ -576,6 +587,7 @@ public: virtual void setWaveletListener (WaveletListener* l) = 0; virtual void setImageTypeListener (ImageTypeListener* l) = 0; virtual void setLocallabListener (LocallabListener* l) = 0; + virtual void setFilmNegListener (FilmNegListener* l) = 0; virtual void setMonitorProfile (const Glib::ustring& monitorProfile, RenderingIntent intent) = 0; virtual void getMonitorProfile (Glib::ustring& monitorProfile, RenderingIntent& intent) const = 0; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 8edebb17a..4ebb95842 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -31,6 +31,7 @@ #include "colortemp.h" #include "curves.h" #include "dcp.h" +#include "iccmatrices.h" #include "iccstore.h" #include "image8.h" #include "improcfun.h" @@ -593,6 +594,8 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati tpp->defGain = max (scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]) / min (scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]); tpp->defGain *= std::pow(2, ri->getBaselineExposure()); + tpp->scaleGain = scale_mul[0] / pre_mul[0]; // used to reconstruct scale_mul from filmnegativethumb.cc + tpp->gammaCorrected = true; unsigned filter = ri->get_filters(); @@ -1041,6 +1044,7 @@ Thumbnail::Thumbnail () : scaleForSave (8192), gammaCorrected (false), colorMatrix{}, + scaleGain (1.0), isRaw (true) { } @@ -1129,7 +1133,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT double cam_g = colorMatrix[1][0] * camwbRed + colorMatrix[1][1] * camwbGreen + colorMatrix[1][2] * camwbBlue; double cam_b = colorMatrix[2][0] * camwbRed + colorMatrix[2][1] * camwbGreen + colorMatrix[2][2] * camwbBlue; currWB = ColorTemp (cam_r, cam_g, cam_b, params.wb.equal); - } else if (params.wb.method == "Auto") { + } else if (params.wb.method == "autold") { currWB = ColorTemp (autoWBTemp, autoWBGreen, wbEqual, "Custom"); } @@ -1178,7 +1182,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT Imagefloat* baseImg = resizeTo (rwidth, rheight, interp, thumbImg); if (isRaw && params.filmNegative.enabled) { - processFilmNegative(params, baseImg, rwidth, rheight, rmi, gmi, bmi); + processFilmNegative(params, baseImg, rwidth, rheight); } if (params.coarse.rotate) { @@ -2122,6 +2126,10 @@ bool Thumbnail::readData (const Glib::ustring& fname) colorMatrix[i][j] = cm[ix++]; } } + + if (keyFile.has_key ("LiveThumbData", "ScaleGain")) { + scaleGain = keyFile.get_double ("LiveThumbData", "ScaleGain"); + } } return true; @@ -2173,6 +2181,7 @@ bool Thumbnail::writeData (const Glib::ustring& fname) keyFile.set_boolean ("LiveThumbData", "GammaCorrected", gammaCorrected); Glib::ArrayHandle cm ((double*)colorMatrix, 9, Glib::OWNERSHIP_NONE); keyFile.set_double_list ("LiveThumbData", "ColorMatrix", cm); + keyFile.set_double ("LiveThumbData", "ScaleGain", scaleGain); keyData = keyFile.to_data (); @@ -2253,44 +2262,6 @@ bool Thumbnail::writeEmbProfile (const Glib::ustring& fname) 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() { if (thumbImg && thumbImg->getType() == rtengine::sImage8) { diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h index c8d657a62..a0033d35f 100644 --- a/rtengine/rtthumbnail.h +++ b/rtengine/rtthumbnail.h @@ -75,8 +75,9 @@ class Thumbnail int scaleForSave; bool gammaCorrected; double colorMatrix[3][3]; + double scaleGain; - void processFilmNegative(const procparams::ProcParams& params, const Imagefloat* baseImg, int rwidth, int rheight, float &rmi, float &gmi, float &bmi); + void processFilmNegative(const procparams::ProcParams& params, const Imagefloat* baseImg, int rwidth, int rheight); public: @@ -113,10 +114,6 @@ public: bool readEmbProfile (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. // Hombre: ... let's hope that proper template can make this cleaner diff --git a/rtengine/settings.h b/rtengine/settings.h index 9ee452321..fde6fa132 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -7,8 +7,8 @@ * 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, +itcw * * 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. @@ -90,6 +90,15 @@ public: double cbdlsensi; // bool showtooltip; + int itcwb_thres; + bool itcwb_sort; + int itcwb_greenrange; + int itcwb_greendeltatemp; + bool itcwb_forceextra; + int itcwb_sizereference; + int itcwb_delta; + bool itcwb_stdobserver10; + int itcwb_precis; enum class ThumbnailInspectorMode { diff --git a/rtengine/shmap.cc b/rtengine/shmap.cc index abdcc42a4..306e30bdd 100644 --- a/rtengine/shmap.cc +++ b/rtengine/shmap.cc @@ -27,6 +27,37 @@ #undef THREAD_PRIORITY_NORMAL #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 { @@ -51,39 +82,13 @@ SHMap::~SHMap () 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) { + const float lumif[3] = { static_cast(lumi[0]), static_cast(lumi[1]), static_cast(lumi[2]) }; + 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 @@ -91,7 +96,7 @@ void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int #pragma omp parallel if (!useBoxBlur) #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 - float thresh = (100.f * radius); //1000; + float thresh = 100.0 * radius; //1000; // 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) @@ -142,7 +147,7 @@ void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int dirpyrlo[1] = buffer; } - fillLuminance( img, dirpyrlo[0], lumi); + fillLuminance(img, dirpyrlo[0], lumif, W, H); scale = 1; 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++) { _val = map[i][j]; - if (_val < _min_f) { - _min_f = _val; - } + _min_f = std::min(_min_f, _val); + _max_f = std::max(_max_f, _val); - if (_val > _max_f) { - _max_f = _val; - } - - _avg += _val; + _avg += static_cast(_val); } #ifdef _OPENMP #pragma omp critical #endif { - if(_min_f < min_f ) { - min_f = _min_f; - } - - if(_max_f > max_f ) { - max_f = _max_f; - } + min_f = std::min(min_f, _min_f); + max_f = std::max(max_f, _max_f); } } _avg /= ((H) * (W)); @@ -214,7 +209,7 @@ void SHMap::updateL (float** L, double radius, bool hq, int skip) { if (!hq) { - fillLuminanceL( L, map); + fillLuminanceL(L, map, W, H); #ifdef _OPENMP #pragma omp parallel #endif @@ -228,7 +223,7 @@ void SHMap::updateL (float** L, double radius, bool hq, int skip) { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //experimental dirpyr shmap - float thresh = (100.f * radius); //1000; + float thresh = 100.0 * radius; //1000; int levrad; // = 16; levrad = 2; //for retinex - otherwise levrad = 16 // set up range function @@ -274,7 +269,7 @@ void SHMap::updateL (float** L, double radius, bool hq, int skip) dirpyrlo[1] = buffer; } - fillLuminanceL( L, dirpyrlo[0]); + fillLuminanceL(L, dirpyrlo[0], W, H); scale = 1; 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++) { _val = map[i][j]; - if (_val < _min_f) { - _min_f = _val; - } + _min_f = std::min(_min_f, _val); + _max_f = std::max(_max_f, _val); - if (_val > _max_f) { - _max_f = _val; - } - - _avg += _val; + _avg += static_cast(_val); } #ifdef _OPENMP #pragma omp critical #endif { - if(_min_f < min_f ) { - min_f = _min_f; - } - - if(_max_f > max_f ) { - max_f = _max_f; - } + min_f = std::min(min_f, _min_f); + max_f = std::max(max_f, _max_f); } } _avg /= ((H) * (W)); diff --git a/rtengine/shmap.h b/rtengine/shmap.h index 03276276e..8e8f73c0e 100644 --- a/rtengine/shmap.h +++ b/rtengine/shmap.h @@ -51,8 +51,6 @@ private: int W, H; void fillLuminanceLab( LabImage * img, float **luminance); - 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); }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index c3eda643f..287248790 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -35,7 +35,8 @@ #include "rawimagesource.h" #include "../rtgui/multilangmgr.h" #include "mytime.h" - +#include "guidedfilter.h" +#include "color.h" #undef THREAD_PRIORITY_NORMAL @@ -67,7 +68,7 @@ public: pl(pl), flush(flush), // internal state - ii(nullptr), + initialImage(nullptr), imgsrc(nullptr), fw(0), fh(0), @@ -96,6 +97,7 @@ public: hlcomprthresh(0), baseImg(nullptr), labView(nullptr), + ctColorCurve(), autili(false), butili(false) { @@ -149,10 +151,10 @@ private: pl->setProgress(0.0); } - ii = job->initialImage; + initialImage = job->initialImage; - if (!ii) { - ii = InitialImage::load(job->fname, job->isRaw, &errorCode); + if (!initialImage) { + initialImage = InitialImage::load(job->fname, job->isRaw, &errorCode); if (errorCode) { delete job; @@ -163,11 +165,12 @@ private: procparams::ProcParams& params = job->pparams; // acquire image from imagesource - imgsrc = ii->getImageSource(); + imgsrc = initialImage->getImageSource(); tr = getCoarseBitMask(params.coarse); - if(imgsrc->getSensorType() == ST_BAYER) { - if(params.raw.bayersensor.method!= RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT)) { + + if (imgsrc->getSensorType() == ST_BAYER) { + if (params.raw.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT)) { imgsrc->setBorder(params.raw.bayersensor.border); } else { imgsrc->setBorder(std::max(params.raw.bayersensor.border, 2)); @@ -175,6 +178,7 @@ private: } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS) { imgsrc->setBorder(params.raw.xtranssensor.border); } + imgsrc->getFullSize(fw, fh, tr); // check the crop params @@ -217,12 +221,18 @@ private: // After preprocess, run film negative processing if enabled if ((imgsrc->getSensorType() == ST_BAYER || (imgsrc->getSensorType() == ST_FUJI_XTRANS)) && params.filmNegative.enabled) { - imgsrc->filmNegativeProcess (params.filmNegative); + std::array filmBaseValues = { + static_cast(params.filmNegative.redBase), + static_cast(params.filmNegative.greenBase), + static_cast(params.filmNegative.blueBase) + }; + imgsrc->filmNegativeProcess (params.filmNegative, filmBaseValues); } if (pl) { pl->setProgress(0.20); } + bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicAutoContrast : params.raw.xtranssensor.dualDemosaicAutoContrast; double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicContrast : params.raw.xtranssensor.dualDemosaicContrast; @@ -235,12 +245,12 @@ private: if (pl) { pl->setProgress(0.30); } - pp = PreviewProps (0, 0, fw, fh, 1); + + pp = PreviewProps(0, 0, fw, fh, 1); if (params.retinex.enabled) { //enabled Retinex LUTf cdcurve(65536, 0); LUTf mapcurve(65536, 0); - LUTu dummy; RetinextransmissionCurve dehatransmissionCurve; RetinexgaintransmissionCurve dehagaintransmissionCurve; bool dehacontlutili = false; @@ -271,7 +281,7 @@ private: currWB = ColorTemp(); } else if (params.wb.method == "Camera") { currWB = imgsrc->getWB(); - } else if (params.wb.method == "Auto") { + } else if (params.wb.method == "autold") { double rm, gm, bm; imgsrc->getAutoWBMultipliers(rm, gm, bm); currWB.update(rm, gm, bm, params.wb.equal, params.wb.tempBias); @@ -397,7 +407,7 @@ private: float multip = 1.f; float adjustr = 1.f; - if (params.icm.workingProfile == "ProPhoto") { + if (params.icm.workingProfile == "ProPhoto") { adjustr = 1.f; // } else if (params.icm.workingProfile == "Adobe RGB") { adjustr = 1.f / 1.3f; @@ -644,7 +654,7 @@ private: float MinRMoy = 0.f; float MinBMoy = 0.f; - if (params.icm.workingProfile == "ProPhoto") { + if (params.icm.workingProfile == "ProPhoto") { adjustr = 1.f; } else if (params.icm.workingProfile == "Adobe RGB") { adjustr = 1.f / 1.3f; @@ -796,8 +806,7 @@ private: // commented out because it makes the application crash when batch processing... // TODO: find a better place to flush rawData and rawRGB if (flush) { - imgsrc->flushRawData(); - imgsrc->flushRGB(); + imgsrc->flush(); } return true; @@ -904,9 +913,9 @@ private: const int W = baseImg->getWidth(); const int H = baseImg->getHeight(); LabImage labcbdl(W, H); - ipf.rgb2lab (*baseImg, labcbdl, params.icm.workingProfile); + ipf.rgb2lab(*baseImg, labcbdl, params.icm.workingProfile); ipf.dirpyrequalizer(&labcbdl, 1); - ipf.lab2rgb (labcbdl, *baseImg, params.icm.workingProfile); + ipf.lab2rgb(labcbdl, *baseImg, params.icm.workingProfile); } //gamma TRC working @@ -916,11 +925,11 @@ private: if (profile == "sRGB" || profile == "Adobe RGB" || profile == "ProPhoto" || profile == "WideGamut" || profile == "BruceRGB" || profile == "Beta RGB" || profile == "BestRGB" || profile == "Rec2020" || profile == "ACESp0" || profile == "ACESp1") { const int cw = baseImg->getWidth(); const int ch = baseImg->getHeight(); - cmsHTRANSFORM dummy = nullptr; + cmsHTRANSFORM dummyTransForm = nullptr; // put gamma TRC to 1 - ipf.workingtrc(baseImg, baseImg, cw, ch, -5, params.icm.workingProfile, 2.4, 12.92310, dummy, true, false, false); + ipf.workingtrc(baseImg, baseImg, cw, ch, -5, params.icm.workingProfile, 2.4, 12.92310, dummyTransForm, true, false, false); //adjust TRC - ipf.workingtrc(baseImg, baseImg, cw, ch, 5, params.icm.workingProfile, params.icm.workingTRCGamma, params.icm.workingTRCSlope, dummy, false, true, false); + ipf.workingtrc(baseImg, baseImg, cw, ch, 5, params.icm.workingProfile, params.icm.workingTRCGamma, params.icm.workingTRCSlope, dummyTransForm, false, true, false); } } @@ -948,7 +957,7 @@ private: bool opautili = false; if (params.colorToning.enabled) { - TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix (params.icm.workingProfile); + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params.icm.workingProfile); double wp[3][3] = { {wprof[0][0], wprof[0][1], wprof[0][2]}, {wprof[1][0], wprof[1][1], wprof[1][2]}, @@ -995,14 +1004,14 @@ private: autor = -9000.f; // This will ask to compute the "auto" values for the B&W tool (have to be inferior to -5000) DCPProfileApplyState as; - DCPProfile *dcpProf = imgsrc->getDCP (params.icm, as); + DCPProfile *dcpProf = imgsrc->getDCP(params.icm, as); LUTu histToneCurve; - 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) { - 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(autor), static_cast(autog), static_cast(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) @@ -1419,14 +1428,6 @@ private: } - WaveletParams WaveParams = params.wavelet; - WavCurve wavCLVCurve; - WavOpacityCurveRG waOpacityCurveRG; - WavOpacityCurveBY waOpacityCurveBY; - WavOpacityCurveW waOpacityCurveW; - WavOpacityCurveWL waOpacityCurveWL; - - params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); // directional pyramid wavelet @@ -1436,16 +1437,166 @@ private: } } - bool wavcontlutili = false; + if ((params.wavelet.enabled)) { + LabImage *unshar = nullptr; + Glib::ustring provis; - CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve,/* hist16C, dummy,*/ 1); + bool wavcontlutili = false; + WaveletParams WaveParams = params.wavelet; + WavCurve wavCLVCurve; + Wavblcurve wavblcurve; + WavOpacityCurveRG waOpacityCurveRG; + WavOpacityCurveBY waOpacityCurveBY; + WavOpacityCurveW waOpacityCurveW; + WavOpacityCurveWL waOpacityCurveWL; + LabImage *provradius = nullptr; + bool procont = WaveParams.expcontrast; + bool prochro = WaveParams.expchroma; + bool proedge = WaveParams.expedge; + bool profin = WaveParams.expfinal; + bool proton = WaveParams.exptoning; + bool pronois = WaveParams.expnoise; + +/* + if(WaveParams.showmask) { + WaveParams.showmask = false; + WaveParams.expclari = true; + } +*/ + if (WaveParams.softrad > 0.f) { + provradius = new LabImage(fw, fh); + provradius->CopyFrom(labView); + } - if (params.wavelet.enabled) { - ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); + params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + + CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve,/* hist16C, dummy,*/ 1); + + if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { + unshar = new LabImage(fw, fh); + provis = params.wavelet.CLmethod; + params.wavelet.CLmethod = "all"; + ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); + unshar->CopyFrom(labView); + params.wavelet.CLmethod = provis; + + WaveParams.expcontrast = false; + WaveParams.expchroma = false; + WaveParams.expedge = false; + WaveParams.expfinal = false; + WaveParams.exptoning = false; + WaveParams.expnoise = false; + } + + ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); + + if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { + WaveParams.expcontrast = procont; + WaveParams.expchroma = prochro; + WaveParams.expedge = proedge; + WaveParams.expfinal = profin; + WaveParams.exptoning = proton; + WaveParams.expnoise = pronois; + + if (WaveParams.softrad > 0.f) { + array2D ble(fw, fh); + array2D guid(fw, fh); + Imagefloat *tmpImage = nullptr; + tmpImage = new Imagefloat(fw, fh); +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < fh; ir++) + for (int jr = 0; jr < fw; jr++) { + float X, Y, Z; + float L = provradius->L[ir][jr]; + float a = provradius->a[ir][jr]; + float b = provradius->b[ir][jr]; + Color::Lab2XYZ(L, a, b, X, Y, Z); + + guid[ir][jr] = Y / 32768.f; + float La = labView->L[ir][jr]; + float aa = labView->a[ir][jr]; + float ba = labView->b[ir][jr]; + Color::Lab2XYZ(La, aa, ba, X, Y, Z); + tmpImage->r(ir, jr) = X; + tmpImage->g(ir, jr) = Y; + tmpImage->b(ir, jr) = Z; + ble[ir][jr] = Y / 32768.f; + } + double epsilmax = 0.0001; + double epsilmin = 0.00001; + double aepsil = (epsilmax - epsilmin) / 90.f; + double bepsil = epsilmax - 100.f * aepsil; + double epsil = aepsil * WaveParams.softrad + bepsil; + + float blur = 10.f / 1 * (0.0001f + 0.8f * WaveParams.softrad); + // rtengine::guidedFilter(guid, ble, ble, blur, 0.001, multiTh); + rtengine::guidedFilter(guid, ble, ble, blur, epsil, false); + + + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < fh; ir++) + for (int jr = 0; jr < fw; jr++) { + float X = tmpImage->r(ir, jr); + float Y = 32768.f * ble[ir][jr]; + float Z = tmpImage->b(ir, jr); + float L, a, b; + Color::XYZ2Lab(X, Y, Z, L, a, b); + labView->L[ir][jr] = L; + } + delete tmpImage; + } + + } + + if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { + float mL = (float)(WaveParams.mergeL / 100.f); + float mC = (float)(WaveParams.mergeC / 100.f); + float mL0; + float mC0; + + if ((WaveParams.CLmethod == "one" || WaveParams.CLmethod == "inf") && WaveParams.Backmethod == "black") { + mL0 = mC0 = 0.f; + mL = -1.5f * mL; + mC = -mC; + } else if (WaveParams.CLmethod == "sup" && WaveParams.Backmethod == "resid") { + mL0 = mL; + mC0 = mC; + } else { + mL0 = mL = mC0 = mC = 0.f; + } + + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int x = 0; x < fh; x++) + for (int y = 0; y < fw; y++) { + labView->L[x][y] = LIM((1.f + mL0) * (unshar->L[x][y]) - mL * labView->L[x][y], 0.f, 32768.f); + labView->a[x][y] = (1.f + mC0) * (unshar->a[x][y]) - mC * labView->a[x][y]; + labView->b[x][y] = (1.f + mC0) * (unshar->b[x][y]) - mC * labView->b[x][y]; + } + + delete unshar; + unshar = NULL; + + if (WaveParams.softrad > 0.f) { + delete provradius; + provradius = NULL; + } + + } + + wavCLVCurve.Reset(); } - wavCLVCurve.Reset(); - ipf.softLight(labView, params.softlight); //Colorappearance and tone-mapping associated @@ -1489,10 +1640,10 @@ private: adap = 2000.; }//if no exif data or wrong 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 += log2(params.raw.expos); // exposure raw white point ; log2 ==> linear to EV - adap = powf(2.f, E_V - 3.f); //cd / m2 + E_V += log2(params.raw.expos); // exposure raw white point ; log2 ==> linear to EV + adap = std::pow(2.0, E_V - 3.0); //cd / m2 } LUTf CAMBrightCurveJ; @@ -1551,7 +1702,7 @@ private: if (labResize) { // resize lab data if ((labView->W != imw || labView->H != imh) && - (params.resize.allowUpscaling || (labView->W >= imw && labView->H >= imh))) { + (params.resize.allowUpscaling || (labView->W >= imw && labView->H >= imh))) { // resize image tmplab = new LabImage(imw, imh); ipf.Lanczos(labView, tmplab, tmpScale); @@ -1573,9 +1724,6 @@ private: } } - cmsHPROFILE jprof = nullptr; - constexpr bool customGamma = false; - constexpr bool useLCMS = false; bool bwonly = params.blackwhite.enabled && !params.colorToning.enabled && !autili && !butili && !params.colorappearance.enabled; ///////////// Custom output gamma has been removed, the user now has to create @@ -1584,10 +1732,10 @@ private: // if Default gamma mode: we use the profile selected in the "Output profile" combobox; // gamma come from the selected profile, otherwise it comes from "Free gamma" tool - Imagefloat* readyImg = ipf.lab2rgbOut (labView, cx, cy, cw, ch, params.icm); + Imagefloat* readyImg = ipf.lab2rgbOut(labView, cx, cy, cw, ch, params.icm); if (settings->verbose) { - printf ("Output profile_: \"%s\"\n", params.icm.outputProfile.c_str()); + printf("Output profile_: \"%s\"\n", params.icm.outputProfile.c_str()); } delete labView; @@ -1615,7 +1763,7 @@ private: } if (tmpScale != 1.0 && params.resize.method == "Nearest" && - (params.resize.allowUpscaling || (readyImg->getWidth() >= imw && readyImg->getHeight() >= imh))) { // resize rgb data (gamma applied) + (params.resize.allowUpscaling || (readyImg->getWidth() >= imw && readyImg->getHeight() >= imh))) { // resize rgb data (gamma applied) Imagefloat* tempImage = new Imagefloat(imw, imh); ipf.resize(readyImg, tempImage, tmpScale); delete readyImg; @@ -1626,12 +1774,12 @@ private: case MetaDataParams::TUNNEL: // Sending back the whole first root, which won't necessarily be the selected frame number // and may contain subframe depending on initial raw's hierarchy - readyImg->setMetadata(ii->getMetaData()->getRootExifData()); + readyImg->setMetadata(initialImage->getMetaData()->getRootExifData()); break; case MetaDataParams::EDIT: // ask for the correct frame number, but may contain subframe depending on initial raw's hierarchy - readyImg->setMetadata(ii->getMetaData()->getBestExifData(imgsrc, ¶ms.raw), params.exif, params.iptc); + readyImg->setMetadata(initialImage->getMetaData()->getBestExifData(imgsrc, ¶ms.raw), params.exif, params.iptc); break; default: // case MetaDataParams::STRIP @@ -1641,36 +1789,28 @@ private: // Setting the output curve to readyImg - if (customGamma) { - if (!useLCMS) { - // use corrected sRGB profile in order to apply a good TRC if present, otherwise use LCMS2 profile generated by lab2rgb16 w/ gamma - ProfileContent pc(jprof); + // use the selected output profile if present, otherwise use LCMS2 profile generate by lab2rgb16 w/ gamma + + if (!params.icm.outputProfile.empty() && params.icm.outputProfile != ColorManagementParams::NoICMString) { + + // if ICCStore::getInstance()->getProfile send back an object, then ICCStore::getInstance()->getContent will do too + cmsHPROFILE jprof = ICCStore::getInstance()->getProfile(params.icm.outputProfile); //get outProfile + + if (jprof == nullptr) { + if (settings->verbose) { + printf("\"%s\" ICC output profile not found!\n - use LCMS2 substitution\n", params.icm.outputProfile.c_str()); + } + } else { + if (settings->verbose) { + printf("Using \"%s\" output profile\n", params.icm.outputProfile.c_str()); + } + + ProfileContent pc = ICCStore::getInstance()->getContent(params.icm.outputProfile); readyImg->setOutputProfile(pc.getData().c_str(), pc.getData().size()); } } else { - // use the selected output profile if present, otherwise use LCMS2 profile generate by lab2rgb16 w/ gamma - - if (!params.icm.outputProfile.empty() && params.icm.outputProfile != ColorManagementParams::NoICMString) { - - // if ICCStore::getInstance()->getProfile send back an object, then ICCStore::getInstance()->getContent will do too - cmsHPROFILE jprof = ICCStore::getInstance()->getProfile (params.icm.outputProfile); //get outProfile - - if (jprof == nullptr) { - if (settings->verbose) { - printf ("\"%s\" ICC output profile not found!\n - use LCMS2 substitution\n", params.icm.outputProfile.c_str()); - } - } else { - if (settings->verbose) { - printf ("Using \"%s\" output profile\n", params.icm.outputProfile.c_str()); - } - - ProfileContent pc = ICCStore::getInstance()->getContent (params.icm.outputProfile); - readyImg->setOutputProfile(pc.getData().c_str(), pc.getData().size()); - } - } else { - // No ICM - readyImg->setOutputProfile(nullptr, 0); - } + // No ICM + readyImg->setOutputProfile(nullptr, 0); } // t2.set(); @@ -1678,7 +1818,7 @@ private: // printf("Total:- %d usec\n", t2.etime(t1)); if (!job->initialImage) { - ii->decreaseRef(); + initialImage->decreaseRef(); } delete job; @@ -1711,7 +1851,7 @@ private: double scale_factor = ipf.resizeScale(¶ms, fw, fh, imw, imh); std::unique_ptr tmplab(new LabImage(fw, fh)); - ipf.rgb2lab (*baseImg, *tmplab, params.icm.workingProfile); + ipf.rgb2lab(*baseImg, *tmplab, params.icm.workingProfile); if (params.crop.enabled) { int cx = params.crop.x; @@ -1748,7 +1888,7 @@ private: delete baseImg; baseImg = new Imagefloat(fw, fh); - ipf.lab2rgb (*tmplab, *baseImg, params.icm.workingProfile); + ipf.lab2rgb(*tmplab, *baseImg, params.icm.workingProfile); } void adjust_procparams(double scale_factor) @@ -1842,7 +1982,7 @@ private: // internal state std::unique_ptr ipf_p; - InitialImage *ii; + InitialImage *initialImage; ImageSource *imgsrc; int fw; int fh; diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 271818303..8cb8fa792 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -32,6 +32,8 @@ namespace rtengine { +using namespace procparams; +ProcParams* params; template void freeArray (T** a, int H) { @@ -309,6 +311,27 @@ void StdImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) } } +void StdImageSource::WBauto(double &tempref, double &greenref, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &studgood, bool &twotimes, const WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const ColorManagementParams &cmp, const RAWParams &raw) +{ +} + +void StdImageSource::getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const WBParams & wbpar, const ColorManagementParams &cmp, const RAWParams &raw) +{ + if (redAWBMul != -1.) { + rm = redAWBMul; + gm = greenAWBMul; + bm = blueAWBMul; + return; + } + + img->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc,studgood, begx, begy, yEn, xEn, cx, cy, bf_h, bf_w, rm, gm, bm, params->wb, params->icm, params->raw); + + redAWBMul = rm; + greenAWBMul = gm; + blueAWBMul = bm; +} + + void StdImageSource::getAutoWBMultipliers (double &rm, double &gm, double &bm) { if (redAWBMul != -1.) { @@ -340,7 +363,7 @@ ColorTemp StdImageSource::getSpotWB (std::vector &red, std::vectorallocate(0, 0); }; diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index b95328c80..f937188b4 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -20,6 +20,7 @@ #include "colortemp.h" #include "imagesource.h" +#include "procparams.h" namespace rtengine { @@ -57,12 +58,15 @@ public: int load (const Glib::ustring &fname) override; void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hrp, const procparams::RAWParams &raw) override; + void getrgbloc (int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) override {}; ColorTemp getWB () const override { return wb; } void getAutoWBMultipliers (double &rm, double &gm, double &bm) override; ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) override; + void WBauto(double &tempref, double &greenref, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &studgood, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) override; + void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) override; eSensorType getSensorType() const override {return ST_NONE;} bool isMono() const override {return false;} @@ -114,7 +118,7 @@ public: void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override { R = G = B = 0;} - void flushRGB () override; + void flush () override; void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) override {}; }; diff --git a/rtengine/tmo_fattal02.cc b/rtengine/tmo_fattal02.cc index a87d7510c..60fbc7b4c 100644 --- a/rtengine/tmo_fattal02.cc +++ b/rtengine/tmo_fattal02.cc @@ -310,7 +310,7 @@ float calculateGradients(Array2Df* H, Array2Df* G, int k, bool multithread) // however, the impact is not visible so we ignore this here (*G)(x, y) = sqrt(gx * gx + gy * gy) / divider; - avgGrad += (*G)(x, y); + avgGrad += static_cast((*G) (x, y)); } } @@ -385,7 +385,7 @@ void calculateFiMatrix(Array2Df* FI, Array2Df* gradients[], for (int y = 0; y < height; y++) { 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 value = pow((grad + noise) / a, beta - 1.0f); @@ -615,8 +615,8 @@ void tmo_fattal02(size_t width, // sets index+1 based on the boundary assumption H(N+1)=H(N-1) unsigned int xp1 = (x + 1 >= width ? width - 2 : x + 1); // 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)); - (*Gy)(x, y) = ((*H)(x, yp1) - (*H)(x, y)) * 0.5 * ((*FI)(x, yp1) + (*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.5f * ((*FI) (x, yp1) + (*FI) (x, y)); } } @@ -759,7 +759,7 @@ void transform_ev2normal(Array2Df *A, Array2Df *T, bool multithread) } for (int y = 1 ; y < height - 1 ; y++) { - (*A)(0, y) *= 0.5; + (*A) (0, y) *= 0.5f; (*A)(width - 1, y) *= 0.5f; } @@ -924,7 +924,7 @@ void solve_pde_fft(Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread, in for (int y = 0 ; y < height ; y++) { 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((*F_tr) (x, y)) / (l1[y] + l2[x]); } } diff --git a/rtengine/xtrans_demosaic.cc b/rtengine/xtrans_demosaic.cc index cb1315ed0..b01b0ac1c 100644 --- a/rtengine/xtrans_demosaic.cc +++ b/rtengine/xtrans_demosaic.cc @@ -31,7 +31,7 @@ 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.212671, 0.715160, 0.072169 }, { 0.019334, 0.119193, 0.950227 } diff --git a/rtexif/CMakeLists.txt b/rtexif/CMakeLists.txt index 5a3831455..836f832e2 100644 --- a/rtexif/CMakeLists.txt +++ b/rtexif/CMakeLists.txt @@ -18,12 +18,12 @@ if(WIN32) link_directories(. "${PROJECT_SOURCE_DIR}/rtexif" ${EXTRA_LIBDIR} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS} ${LENSFUN_LIBRARY_DIRS}) else() set_target_properties(rtexif PROPERTIES COMPILE_FLAGS " -fPIC") - include_directories(${EXTRA_INCDIR} ${GLIB2_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS} ${GTK_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS}) - link_directories(${EXTRA_LIBDIR} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS} ${LENSFUN_LIBRARY_DIRS}) + include_directories("${EXTRA_INCDIR} ${GLIB2_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS} ${GTK_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS}") + link_directories("${EXTRA_LIBDIR} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS} ${LENSFUN_LIBRARY_DIRS}") endif() include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}") if(BUILD_SHARED_LIBS) - install(TARGETS rtexif DESTINATION ${LIBDIR}) + install(TARGETS rtexif DESTINATION "${LIBDIR}") endif() diff --git a/rtexif/canonattribs.cc b/rtexif/canonattribs.cc index c434634dc..a91b7266c 100644 --- a/rtexif/canonattribs.cc +++ b/rtexif/canonattribs.cc @@ -845,7 +845,7 @@ public: {195, "Canon EF 35-105mm f/4.5-5.6 USM"}, {196, "Canon EF 75-300mm f/4-5.6 USM"}, {197, "Canon EF 75-300mm f/4-5.6 IS USM or Sigma Lens"}, - {197, "Sigma 18-300mm f/3.5-6.3 DC Macro OS HS"}, + {197, "Sigma 18-300mm f/3.5-6.3 DC Macro OS HSM"}, {198, "Canon EF 50mm f/1.4 USM or Other Lens"}, {198, "Zeiss Otus 55mm f/1.4 ZE"}, {198, "Zeiss Otus 85mm f/1.4 ZE"}, @@ -1229,7 +1229,7 @@ public: int a = Interpreter::toInt (t, ofs, astype); if (a > 1) { - int i = int (double (powf (2.f, float (a) / 32.f - 4.f)) * 50.f + 0.5f); + int i = static_cast(powf (2.f, static_cast(a) / 32.f - 4.f)) * 50.0 + 0.5; return i; } else { return 0; diff --git a/rtexif/kodakattribs.cc b/rtexif/kodakattribs.cc index 619925760..c89ca2298 100644 --- a/rtexif/kodakattribs.cc +++ b/rtexif/kodakattribs.cc @@ -56,7 +56,7 @@ void parseKodakIfdTextualInfo (Tag *textualInfo, Tag* exif_) // Proback645 may have "Lens" but not "Focal Length" float flen = atof (val.c_str()); - if (flen != 0.0) { + if (flen != 0.f) { t = new Tag (exif, lookupAttrib (exifAttribs, "FocalLength")); t->initRational (flen * 32, 32); exif->replaceTag (t); @@ -64,7 +64,7 @@ void parseKodakIfdTextualInfo (Tag *textualInfo, Tag* exif_) } else if (key == "Focal Length") { float flen = atof (val.c_str()); - if (flen != 0.0) { + if (flen != 0.f) { t = new Tag (exif, lookupAttrib (exifAttribs, "FocalLength")); t->initRational (flen * 32, 32); exif->replaceTag (t); @@ -72,7 +72,7 @@ void parseKodakIfdTextualInfo (Tag *textualInfo, Tag* exif_) } else if (key == "Aperture") { float aperture = atof (&val.c_str()[1]); - if (aperture != 0.0) { + if (aperture != 0.f) { t = new Tag (exif, lookupAttrib (exifAttribs, "FNumber")); t->initRational ((int) (aperture * 10), 10); exif->replaceTag (t); diff --git a/rtexif/nikonattribs.cc b/rtexif/nikonattribs.cc index 9c52f3b8a..0bc9ce730 100644 --- a/rtexif/nikonattribs.cc +++ b/rtexif/nikonattribs.cc @@ -68,7 +68,7 @@ public: int a = t->getValue()[ofs]; if (a > 1) { - int i = int (double (powf (2.f, float (a) / 12.f - 5.f)) * 100.f + 0.5f); + int i = static_cast(powf(2.f, float (a) / 12.f - 5.f)) * 100.0 + 0.5; return i; } else { return 0; diff --git a/rtexif/olympusattribs.cc b/rtexif/olympusattribs.cc index ec7ab98c7..52fbec55d 100644 --- a/rtexif/olympusattribs.cc +++ b/rtexif/olympusattribs.cc @@ -131,6 +131,7 @@ public: lenses["00 32 10"] = "Olympus M.Zuiko Digital ED 12-200mm f/3.5-6.3"; lenses["00 33 00"] = "Olympus Zuiko Digital 25mm f/2.8"; lenses["00 34 00"] = "Olympus Zuiko Digital ED 9-18mm f/4.0-5.6"; + lenses["00 34 10"] = "Olympus M.Zuiko Digital ED 12-45mm f/4.0 Pro"; lenses["00 35 00"] = "Olympus Zuiko Digital 14-54mm f/2.8-3.5 II"; lenses["01 01 00"] = "Sigma 18-50mm f/3.5-5.6 DC"; lenses["01 01 10"] = "Sigma 30mm f/2.8 EX DN"; diff --git a/rtexif/pentaxattribs.cc b/rtexif/pentaxattribs.cc index abc25b7a1..d6b9a9c84 100644 --- a/rtexif/pentaxattribs.cc +++ b/rtexif/pentaxattribs.cc @@ -782,6 +782,7 @@ public: choices.insert (p_t (256 * 4 + 2, "smc PENTAX-FA 80-320mm f/4.5-5.6")); choices.insert (p_t (256 * 4 + 3, "smc PENTAX-FA 43mm f/1.9 Limited")); choices.insert (p_t (256 * 4 + 6, "smc PENTAX-FA 35-80mm f/4-5.6")); + choices.insert (p_t (256 * 4 + 8, "Irix 150mm f/2.8 Macro")); choices.insert (p_t (256 * 4 + 9, "Irix 11mm f/4 Firefly")); choices.insert (p_t (256 * 4 + 10, "Irix 15mm f/2.4")); choices.insert (p_t (256 * 4 + 12, "smc PENTAX-FA 50mm f/1.4")); @@ -938,6 +939,7 @@ public: choices.insert (p_t (256 * 8 + 62, "HD PENTAX-D FA 24-70mm f/2.8 ED SDM WR")); choices.insert (p_t (256 * 8 + 63, "HD PENTAX-D FA 15-30mm f/2.8 ED SDM WR")); choices.insert (p_t (256 * 8 + 64, "HD PENTAX-D FA* 50mm f/1.4 SDM AW")); + choices.insert (p_t (256 * 8 + 65, "HD PENTAX-D FA 70-210mm f/4 ED SDM WR")); choices.insert (p_t (256 * 8 + 196, "HD PENTAX-DA* 11-18mm f/2.8 ED DC AW")); choices.insert (p_t (256 * 8 + 197, "HD PENTAX-DA 55-300mm f/4.5-6.3 ED PLM WR RE")); choices.insert (p_t (256 * 8 + 198, "smc PENTAX-DA L 18-50mm f/4-5.6 DC WR RE")); @@ -1393,9 +1395,9 @@ public: std::string toString (const Tag* t) const override { int a = t->toInt (0, BYTE); - float b = float (10 * int (a >> 2)) * pow (4.f, float (int (a & 0x03) - 2)); + double b = static_cast(10 * (a >> 2)) * std::pow(4.0, static_cast((a & 0x03) - 2)); - if (b > 1.f) { + if (b > 1.0) { char buffer[32]; sprintf (buffer, "%.2f", b ); return buffer; @@ -1406,9 +1408,9 @@ public: double toDouble (const Tag* t, int ofs) override { int a = t->toInt (ofs, BYTE); - float b = float (10 * int (a >> 2)) * pow (4.f, float (int (a & 0x03) - 2)); + double b = static_cast(10 * (a >> 2)) * std::pow(4.0, static_cast((a & 0x03) - 2)); - if (b > 1.f) { + if (b > 1.0) { return b; } else { return 0.; diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index 89ff6cd33..06604ade5 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -2344,7 +2344,7 @@ void ExifManager::parseCIFF (int length, TagDirectory* root) ev = ((short)get2 (f, INTEL)) / 32.0f; fseek (f, 34, SEEK_CUR); - if (shutter > 1e6) { + if (shutter > 1e6f) { shutter = get2 (f, INTEL) / 10.0f; } diff --git a/rtexif/sonyminoltaattribs.cc b/rtexif/sonyminoltaattribs.cc index ee41b2a9b..4c901b8c0 100644 --- a/rtexif/sonyminoltaattribs.cc +++ b/rtexif/sonyminoltaattribs.cc @@ -1126,6 +1126,7 @@ public: choices.insert (p_t (49458, "Tamron 17-28mm f/2.8 Di III RXD")); choices.insert (p_t (49459, "Tamron 35mm f/2.8 Di III OSD M1:2")); choices.insert (p_t (49460, "Tamron 24mm f/2.8 Di III OSD M1:2")); + choices.insert (p_t (49461, "Tamron 20mm f/2.8 Di III OSD M1:2")); choices.insert (p_t (49712, "Tokina FiRIN 20mm f/2 FE AF")); choices.insert (p_t (49713, "Tokina FiRIN 100mm f/2.8 FE MACRO")); choices.insert (p_t (50480, "Sigma 30mm f/1.4 DC DN | C")); @@ -1152,6 +1153,7 @@ public: choices.insert (p_t (50514, "Sigma 45mm f/2.8 DG DN | C")); choices.insert (p_t (50515, "Sigma 35mm f/1.2 DG DN | A")); choices.insert (p_t (50516, "Sigma 14-24mm f/2.8 DG DN | A")); + choices.insert (p_t (50517, "Sigma 24-70mm f/2.8 DG DN | A")); choices.insert (p_t (50992, "Voigtlander SUPER WIDE-HELIAR 15mm f/4.5 III")); choices.insert (p_t (50993, "Voigtlander HELIAR-HYPER WIDE 10mm f/5.6")); choices.insert (p_t (50994, "Voigtlander ULTRA WIDE-HELIAR 12mm f/5.6 III")); @@ -2114,7 +2116,7 @@ public: // Decode the value if (a && a != 254) { // 254 = 'Auto' for CameraSettings3, but we might say the same for CameraSettings & CameraSettings2 (?) - return int (expf ((double (a) / 8.f - 6.f) * logf (2.f)) * 100.f + 0.5f); + return std::exp((a / 8.f - 6.f) * std::log(2.f)) * 100.f + 0.5f; } else { return 0; } diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 6c449f4cb..6719d9de2 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -168,13 +168,13 @@ set(NONCLISOURCEFILES zoompanel.cc ) -include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}") +include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) if(APPLE) find_package(MacIntegration REQUIRED) # At the time of writing CMake has no module finder for gtkmacintegration so here we have it hard-coded, if installed via macports it should be in /opt/local/... - set(EXTRA_LIB_RTGUI ${MacIntegration_LIBRARIES}) - set(EXTRA_INCDIR ${EXTRA_INCDIR} ${MacIntegration_INCLUDE_DIRS}) + set(EXTRA_LIB_RTGUI "${MacIntegration_LIBRARIES}") + set(EXTRA_INCDIR "${EXTRA_INCDIR}" "${MacIntegration_INCLUDE_DIRS}") endif() if(WIN32) @@ -240,16 +240,16 @@ else() endif() # Excluding libatomic needed by Clang/FreeBSD, #3636 -if(OPENMP_FOUND AND NOT APPLE AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD") - set(EXTRA_LIB_RTGUI ${EXTRA_LIB_RTGUI} "atomic") +if(OPENMP_FOUND AND NOT APPLE AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") + set(EXTRA_LIB_RTGUI "${EXTRA_LIB_RTGUI}" "atomic") endif() # Create config.h which defines where data are stored configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h") # Create new executables targets -add_executable(rth ${EXTRA_SRC_NONCLI} ${NONCLISOURCEFILES}) -add_executable(rth-cli ${EXTRA_SRC_CLI} ${CLISOURCEFILES}) +add_executable(rth "${EXTRA_SRC_NONCLI}" "${NONCLISOURCEFILES}") +add_executable(rth-cli "${EXTRA_SRC_CLI}" "${CLISOURCEFILES}") # Add dependencies to executables targets add_dependencies(rth UpdateInfo) @@ -315,5 +315,5 @@ target_link_libraries(rth-cli rtengine ) # Install executables -install(TARGETS rth DESTINATION ${BINDIR}) -install(TARGETS rth-cli DESTINATION ${BINDIR}) +install(TARGETS rth DESTINATION "${BINDIR}") +install(TARGETS rth-cli DESTINATION "${BINDIR}") diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index 05150517f..7a267bb02 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -84,6 +84,7 @@ enum { ADDSET_WA_SKINPROTECT, ADDSET_WA_THRR, ADDSET_WA_THRRH, + ADDSET_WA_RADIUS, ADDSET_WA_THRES, ADDSET_WA_THRESHOLD, ADDSET_WA_THRESHOLD2, @@ -101,6 +102,8 @@ enum { ADDSET_WA_EDGEDETECTTHR, ADDSET_WA_EDGEDETECTTHR2, ADDSET_WA_TMRS, + ADDSET_WA_EDGS, + ADDSET_WA_SCALE, ADDSET_WA_GAMMA, ADDSET_RETI_STR, ADDSET_RETI_NEIGH, diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index ad55e5860..b1906e8e6 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -172,7 +172,7 @@ void BatchToolPanelCoordinator::initSession () shadowshighlights->setAdjusterBehavior (false, false); dirpyrequalizer->setAdjusterBehavior (false, false, false); - wavelet->setAdjusterBehavior (false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); + wavelet->setAdjusterBehavior (false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); dirpyrdenoise->setAdjusterBehavior (false, false, false, false, false, false, false); bayerprocess->setAdjusterBehavior(false, false, false, false, false, false); xtransprocess->setAdjusterBehavior(false, false); @@ -220,7 +220,7 @@ void BatchToolPanelCoordinator::initSession () blackwhite->setAdjusterBehavior (options.baBehav[ADDSET_BLACKWHITE_HUES], options.baBehav[ADDSET_BLACKWHITE_GAMMA]); shadowshighlights->setAdjusterBehavior (options.baBehav[ADDSET_SH_HIGHLIGHTS], options.baBehav[ADDSET_SH_SHADOWS]); dirpyrequalizer->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYREQ], options.baBehav[ADDSET_DIRPYREQ_THRESHOLD], options.baBehav[ADDSET_DIRPYREQ_SKINPROTECT]); - wavelet->setAdjusterBehavior (options.baBehav[ADDSET_WA], options.baBehav[ADDSET_WA_THRESHOLD], options.baBehav[ADDSET_WA_THRESHOLD2], options.baBehav[ADDSET_WA_THRES], options.baBehav[ADDSET_WA_CHRO], options.baBehav[ADDSET_WA_CHROMA], options.baBehav[ADDSET_WA_CONTRAST], options.baBehav[ADDSET_WA_SKINPROTECT], options.baBehav[ADDSET_WA_RESCHRO], options.baBehav[ADDSET_WA_TMRS], options.baBehav[ADDSET_WA_RESCON], options.baBehav[ADDSET_WA_RESCONH], options.baBehav[ADDSET_WA_THRR], options.baBehav[ADDSET_WA_THRRH], options.baBehav[ADDSET_WA_SKYPROTECT], options.baBehav[ADDSET_WA_EDGRAD], options.baBehav[ADDSET_WA_EDGVAL], options.baBehav[ADDSET_WA_STRENGTH], options.baBehav[ADDSET_WA_GAMMA], options.baBehav[ADDSET_WA_EDGEDETECT], options.baBehav[ADDSET_WA_EDGEDETECTTHR], options.baBehav[ADDSET_WA_EDGEDETECTTHR2]); + wavelet->setAdjusterBehavior (options.baBehav[ADDSET_WA], options.baBehav[ADDSET_WA_THRESHOLD], options.baBehav[ADDSET_WA_THRESHOLD2], options.baBehav[ADDSET_WA_THRES], options.baBehav[ADDSET_WA_CHRO], options.baBehav[ADDSET_WA_CHROMA], options.baBehav[ADDSET_WA_CONTRAST], options.baBehav[ADDSET_WA_SKINPROTECT], options.baBehav[ADDSET_WA_RESCHRO], options.baBehav[ADDSET_WA_TMRS], options.baBehav[ADDSET_WA_EDGS], options.baBehav[ADDSET_WA_SCALE], options.baBehav[ADDSET_WA_RESCON], options.baBehav[ADDSET_WA_RESCONH], options.baBehav[ADDSET_WA_THRR], options.baBehav[ADDSET_WA_THRRH], options.baBehav[ADDSET_WA_RADIUS], options.baBehav[ADDSET_WA_SKYPROTECT], options.baBehav[ADDSET_WA_EDGRAD], options.baBehav[ADDSET_WA_EDGVAL], options.baBehav[ADDSET_WA_STRENGTH], options.baBehav[ADDSET_WA_GAMMA], options.baBehav[ADDSET_WA_EDGEDETECT], options.baBehav[ADDSET_WA_EDGEDETECTTHR], options.baBehav[ADDSET_WA_EDGEDETECTTHR2]); dirpyrdenoise->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYRDN_LUMA], options.baBehav[ADDSET_DIRPYRDN_LUMDET], options.baBehav[ADDSET_DIRPYRDN_CHROMA], options.baBehav[ADDSET_DIRPYRDN_CHROMARED], options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE], options.baBehav[ADDSET_DIRPYRDN_GAMMA], options.baBehav[ADDSET_DIRPYRDN_PASSES]); bayerprocess->setAdjusterBehavior(options.baBehav[ADDSET_BAYER_FALSE_COLOR_SUPPRESSION], options.baBehav[ADDSET_BAYER_ITER], options.baBehav[ADDSET_BAYER_DUALDEMOZCONTRAST], options.baBehav[ADDSET_BAYER_PS_SIGMA], options.baBehav[ADDSET_BAYER_PS_SMOOTH], options.baBehav[ADDSET_BAYER_PS_EPERISO]); xtransprocess->setAdjusterBehavior(options.baBehav[ADDSET_BAYER_FALSE_COLOR_SUPPRESSION], options.baBehav[ADDSET_BAYER_DUALDEMOZCONTRAST]); @@ -336,8 +336,11 @@ void BatchToolPanelCoordinator::initSession () if (options.baBehav[ADDSET_WA_RESCONH]) { pparams.wavelet.resconH = 0; } if (options.baBehav[ADDSET_WA_RESCHRO]) { pparams.wavelet.reschro = 0; } if (options.baBehav[ADDSET_WA_TMRS]) { pparams.wavelet.tmrs = 0; } + if (options.baBehav[ADDSET_WA_EDGS]) { pparams.wavelet.edgs = 0; } + if (options.baBehav[ADDSET_WA_SCALE]) { pparams.wavelet.scale = 0; } if (options.baBehav[ADDSET_WA_THRR]) { pparams.wavelet.thr = 0; } if (options.baBehav[ADDSET_WA_THRRH]) { pparams.wavelet.thrH = 0; } + if (options.baBehav[ADDSET_WA_RADIUS]) { pparams.wavelet.radius = 0; } if (options.baBehav[ADDSET_WA_SKYPROTECT]) { pparams.wavelet.sky = 0; } if (options.baBehav[ADDSET_WA_EDGRAD]) { pparams.wavelet.edgrad = 0; } if (options.baBehav[ADDSET_WA_EDGVAL]) { pparams.wavelet.edgval = 0; } diff --git a/rtgui/blackwhite.cc b/rtgui/blackwhite.cc index 596d99607..ea493d6e1 100644 --- a/rtgui/blackwhite.cc +++ b/rtgui/blackwhite.cc @@ -70,7 +70,7 @@ BlackWhite::BlackWhite (): FoldableToolPanel(this, "blackwhite", M("TP_BWMIX_LAB // -0.1 rad < Hue < 1.6 rad for (int i = 0; i < 7; i++) { - float x = float(i) * (1.0f / 6.0); + float x = float(i) * (1.0f / 6.f); Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); bottomMilestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); } @@ -1185,10 +1185,10 @@ void BlackWhite::updateRGBLabel () RGBLabels->set_text( Glib::ustring::compose(M("TP_BWMIX_RGBLABEL"), - Glib::ustring::format(std::fixed, std::setprecision(1), r * 100.), - Glib::ustring::format(std::fixed, std::setprecision(1), g * 100.), - Glib::ustring::format(std::fixed, std::setprecision(1), b * 100.), - Glib::ustring::format(std::fixed, std::setprecision(0), ceil(kcorrec * 100./*(r+g+b)*100.)*/))) + Glib::ustring::format(std::fixed, std::setprecision(1), r * 100.f), + Glib::ustring::format(std::fixed, std::setprecision(1), g * 100.f), + Glib::ustring::format(std::fixed, std::setprecision(1), b * 100.f), + Glib::ustring::format(std::fixed, std::setprecision(0), ceil(kcorrec * 100.f/*(r+g+b)*100.)*/))) ); // We have to update the RGB sliders too if preset values has been chosen diff --git a/rtgui/cachemanager.cc b/rtgui/cachemanager.cc index 9a3fc9574..5e540b604 100644 --- a/rtgui/cachemanager.cc +++ b/rtgui/cachemanager.cc @@ -39,7 +39,7 @@ namespace { constexpr int cacheDirMode = 0777; -constexpr const char* cacheDirs[] = { "profiles", "images", "aehistograms", "embprofiles", "data"}; +constexpr const char* cacheDirs[] = { "profiles", "images", "embprofiles", "data" }; } @@ -59,9 +59,7 @@ void CacheManager::init () auto error = g_mkdir_with_parents (baseDir.c_str(), cacheDirMode); for (const auto& cacheDir : cacheDirs) { - if (strncmp(cacheDir, "aehistograms", 12)) { // don't create aehistograms folder. - error |= g_mkdir_with_parents (Glib::build_filename (baseDir, cacheDir).c_str(), cacheDirMode); - } + error |= g_mkdir_with_parents (Glib::build_filename (baseDir, cacheDir).c_str(), cacheDirMode); } if (error != 0 && rtengine::settings->verbose) { @@ -193,7 +191,6 @@ void CacheManager::renameEntry (const std::string& oldfilename, const std::strin auto error = g_rename (getCacheFileName ("profiles", oldfilename, paramFileExtension, oldmd5).c_str (), getCacheFileName ("profiles", newfilename, paramFileExtension, newmd5).c_str ()); error |= g_rename (getCacheFileName ("images", oldfilename, ".rtti", oldmd5).c_str (), getCacheFileName ("images", newfilename, ".rtti", newmd5).c_str ()); - error |= g_rename (getCacheFileName ("aehistograms", oldfilename, "", oldmd5).c_str (), getCacheFileName ("aehistograms", newfilename, "", newmd5).c_str ()); error |= g_rename (getCacheFileName ("embprofiles", oldfilename, ".icc", oldmd5).c_str (), getCacheFileName ("embprofiles", newfilename, ".icc", newmd5).c_str ()); error |= g_rename (getCacheFileName ("data", oldfilename, ".txt", oldmd5).c_str (), getCacheFileName ("data", newfilename, ".txt", newmd5).c_str ()); @@ -248,7 +245,6 @@ void CacheManager::clearImages () const deleteDir ("data"); deleteDir ("images"); - deleteDir ("aehistograms"); deleteDir ("embprofiles"); } @@ -287,7 +283,6 @@ void CacheManager::deleteFiles (const Glib::ustring& fname, const std::string& m } auto error = g_remove (getCacheFileName ("images", fname, ".rtti", md5).c_str ()); - error |= g_remove (getCacheFileName ("aehistograms", fname, "", md5).c_str ()); error |= g_remove (getCacheFileName ("embprofiles", fname, ".icc", md5).c_str ()); if (purgeData) { diff --git a/rtgui/colorappearance.cc b/rtgui/colorappearance.cc index 62f6eee2c..bdbe3de3a 100644 --- a/rtgui/colorappearance.cc +++ b/rtgui/colorappearance.cc @@ -25,6 +25,7 @@ #include "guiutils.h" #include "options.h" #include "rtimage.h" +#include "eventmapper.h" #include "../rtengine/color.h" #include "../rtengine/procparams.h" @@ -32,7 +33,7 @@ #define MINTEMP0 2000 //1200 #define MAXTEMP0 12000 //12000 -#define CENTERTEMP0 5000 +#define CENTERTEMP0 5003 #define MINGREEN0 0.8 #define MAXGREEN0 1.2 @@ -217,8 +218,17 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" milestones.push_back ( GradientMilestone (0., 0., 0., 0.) ); milestones.push_back ( GradientMilestone (1., 1., 1., 1.) ); + auto m = ProcEventMapper::getInstance(); + Evcatpreset = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_CAT02PRESET"); + EvCATAutotempout = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_TEMPOUT"); + EvCATillum = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ILLUM"); + //preset button cat02 + presetcat02 = Gtk::manage (new Gtk::CheckButton (M ("TP_COLORAPP_PRESETCAT02"))); + presetcat02->set_tooltip_markup (M("TP_COLORAPP_PRESETCAT02_TIP")); + presetcat02conn = presetcat02->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::presetcat02pressed)); + pack_start (*presetcat02, Gtk::PACK_SHRINK); - // ------------------------ Process #1: Converting to CIECAM + // ----------------------- Process #1: Converting to CIECAM // Process 1 frame @@ -232,7 +242,7 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" p1VBox = Gtk::manage ( new Gtk::VBox()); p1VBox->set_spacing (2); - degree = Gtk::manage (new Adjuster (M ("TP_COLORAPP_CIECAT_DEGREE"), 0., 100., 1., 100.)); + degree = Gtk::manage (new Adjuster (M ("TP_COLORAPP_CIECAT_DEGREE"), 0., 100., 1., 90.)); if (degree->delay < options.adjusterMaxDelay) { degree->delay = options.adjusterMaxDelay; @@ -276,6 +286,26 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" wbmHBox->pack_start (*wbmodel); p1VBox->pack_start (*wbmHBox); + + Gtk::HBox* illumHBox = Gtk::manage (new Gtk::HBox ()); + illumHBox->set_spacing (2); + illumHBox->set_tooltip_markup (M ("TP_COLORAPP_ILLUM_TOOLTIP")); + Gtk::Label* illumLab = Gtk::manage (new Gtk::Label (M ("TP_COLORAPP_ILLUM") + ":")); + illumHBox->pack_start (*illumLab, Gtk::PACK_SHRINK); + illum = Gtk::manage (new MyComboBoxText ()); + illum->append (M ("TP_COLORAPP_ILA")); + illum->append (M ("TP_COLORAPP_IL41")); + illum->append (M ("TP_COLORAPP_IL50")); + illum->append (M ("TP_COLORAPP_IL55")); + illum->append (M ("TP_COLORAPP_IL60")); + illum->append (M ("TP_COLORAPP_IL65")); + illum->append (M ("TP_COLORAPP_IL75")); + illum->append (M ("TP_COLORAPP_ILFREE")); + + illum->set_active (0); + illumHBox->pack_start (*illum); + p1VBox->pack_start (*illumHBox); + Gtk::Image* itempL = Gtk::manage (new RTImage ("circle-blue-small.png")); Gtk::Image* itempR = Gtk::manage (new RTImage ("circle-yellow-small.png")); Gtk::Image* igreenL = Gtk::manage (new RTImage ("circle-magenta-small.png")); @@ -523,7 +553,7 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" float R, G, B; for (int i = 0; i < 7; i++) { - float x = float (i) * (1.0f / 6.0); + float x = float (i) * (1.0f / 6.f); Color::hsv2rgb01 (x, 0.5f, 0.5f, R, G, B); shape3Milestones.push_back ( GradientMilestone (double (x), double (R), double (G), double (B)) ); } @@ -599,7 +629,7 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" // Gtk::Image* iblueredL = Gtk::manage (new RTImage ("circle-blue-small.png")); // Gtk::Image* iblueredR = Gtk::manage (new RTImage ("circle-red-small.png")); - degreeout = Gtk::manage (new Adjuster (M ("TP_COLORAPP_CIECAT_DEGREE"), 0., 100., 1., 100.)); + degreeout = Gtk::manage (new Adjuster (M ("TP_COLORAPP_CIECAT_DEGREE"), 0., 100., 1., 90.)); if (degreeout->delay < options.adjusterMaxDelay) { degreeout->delay = options.adjusterMaxDelay; @@ -617,7 +647,9 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" tempout = Gtk::manage (new Adjuster (M ("TP_WBALANCE_TEMPERATURE"), MINTEMP0, MAXTEMP0, 5, CENTERTEMP0, itempR1, itempL1, &wbSlider2Temp, &wbTemp2Slider)); greenout = Gtk::manage (new Adjuster (M ("TP_WBALANCE_GREEN"), MINGREEN0, MAXGREEN0, 0.001, 1.0, igreenR1, igreenL1)); ybout = Gtk::manage (new Adjuster (M ("TP_COLORAPP_MEANLUMINANCE"), 5, 90, 1, 18)); - tempout->set_tooltip_markup (M ("TP_COLORAPP_TEMP_TOOLTIP")); + tempout->set_tooltip_markup (M ("TP_COLORAPP_TEMP2_TOOLTIP")); + tempout->throwOnButtonRelease(); + tempout->addAutoButton (M ("TP_COLORAPP_TEMPOUT_TOOLTIP")); tempout->show(); greenout->show(); @@ -690,6 +722,7 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" // surrconn = surrsource->signal_toggled().connect ( sigc::mem_fun (*this, &ColorAppearance::surrsource_toggled) ); wbmodelconn = wbmodel->signal_changed().connect ( sigc::mem_fun (*this, &ColorAppearance::wbmodelChanged) ); + illumconn = illum->signal_changed().connect ( sigc::mem_fun (*this, &ColorAppearance::illumChanged) ); algoconn = algo->signal_changed().connect ( sigc::mem_fun (*this, &ColorAppearance::algoChanged) ); surroundconn = surround->signal_changed().connect ( sigc::mem_fun (*this, &ColorAppearance::surroundChanged) ); surrsrcconn = surrsrc->signal_changed().connect ( sigc::mem_fun (*this, &ColorAppearance::surrsrcChanged) ); @@ -759,12 +792,14 @@ void ColorAppearance::neutral_pressed () qcontrast->resetValue (false); colorh->resetValue (false); tempout->resetValue (false); + tempout->setAutoValue (true); greenout->resetValue (false); ybout->resetValue (false); tempsc->resetValue (false); greensc->resetValue (false); badpixsl->resetValue (false); wbmodel->set_active (0); + illum->set_active (2); toneCurveMode->set_active (0); toneCurveMode2->set_active (0); toneCurveMode3->set_active (0); @@ -801,6 +836,7 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) tcmodeconn.block (true); tcmode2conn.block (true); tcmode3conn.block (true); + presetcat02conn.block (true); shape->setCurve (pp->colorappearance.curve); shape2->setCurve (pp->colorappearance.curve2); shape3->setCurve (pp->colorappearance.curve3); @@ -808,7 +844,11 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) toneCurveMode2->set_active (toUnderlying(pp->colorappearance.curveMode2)); toneCurveMode3->set_active (toUnderlying(pp->colorappearance.curveMode3)); curveMode3Changed(); // This will set the correct sensitive state of depending Adjusters + presetcat02->set_active(pp->colorappearance.presetcat02); + nexttemp = pp->wb.temperature; + nextgreen = 1.; //pp->wb.green; + if (pedited) { degree->setEditedState (pedited->colorappearance.degree ? Edited : UnEdited); degreeout->setEditedState (pedited->colorappearance.degreeout ? Edited : UnEdited); @@ -842,6 +882,7 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) adapscen->setAutoInconsistent (multiImage && !pedited->colorappearance.autoadapscen); ybscen->setAutoInconsistent (multiImage && !pedited->colorappearance.autoybscen); set_inconsistent (multiImage && !pedited->colorappearance.enabled); + tempout->setAutoInconsistent (multiImage && !pedited->colorappearance.autotempout); shape->setUnChanged (!pedited->colorappearance.curve); shape2->setUnChanged (!pedited->colorappearance.curve2); @@ -858,6 +899,7 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) if (!pedited->colorappearance.curveMode3) { toneCurveMode3->set_active (3); } + presetcat02->set_inconsistent(!pedited->colorappearance.presetcat02); } @@ -919,6 +961,32 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) // Have to be manually called to handle initial state update wbmodelChanged(); + illumconn.block (true); + + if (pedited && !pedited->colorappearance.illum) { + illum->set_active (8); + } else if (pp->colorappearance.illum == "iA") { + illum->set_active (0); + } else if (pp->colorappearance.illum == "i41") { + illum->set_active (1); + } else if (pp->colorappearance.illum == "i50") { + illum->set_active (2); + } else if (pp->colorappearance.illum == "i55") { + illum->set_active (3); + } else if (pp->colorappearance.illum == "i60") { + illum->set_active (4); + } else if (pp->colorappearance.illum == "i65") { + illum->set_active (5); + } else if (pp->colorappearance.illum == "i75") { + illum->set_active (6); + } else if (pp->colorappearance.illum == "ifree") { + illum->set_active (7); + } + + illumconn.block (false); + // Have to be manually called to handle initial state update + illumChanged(); + algoconn.block (true); if (pedited && !pedited->colorappearance.algo) { @@ -967,6 +1035,7 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) lastAutoAdapscen = pp->colorappearance.autoadapscen; lastAutoDegreeout = pp->colorappearance.autodegreeout; lastAutoybscen = pp->colorappearance.autoybscen; + lastAutotempout = pp->colorappearance.autotempout; degree->setValue (pp->colorappearance.degree); degree->setAutoValue (pp->colorappearance.autodegree); @@ -989,10 +1058,15 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) qcontrast->setValue (pp->colorappearance.qcontrast); colorh->setValue (pp->colorappearance.colorh); tempout->setValue (pp->colorappearance.tempout); + tempout->setAutoValue (pp->colorappearance.autotempout); greenout->setValue (pp->colorappearance.greenout); ybout->setValue (pp->colorappearance.ybout); tempsc->setValue (pp->colorappearance.tempsc); greensc->setValue (pp->colorappearance.greensc); + presetcat02conn.block (true); + presetcat02->set_active (pp->colorappearance.presetcat02); + presetcat02conn.block (false); + lastpresetcat02 = pp->colorappearance.presetcat02; tcmode3conn.block (false); tcmode2conn.block (false); @@ -1041,10 +1115,12 @@ void ColorAppearance::write (ProcParams* pp, ParamsEdited* pedited) pp->colorappearance.curve2 = shape2->getCurve (); pp->colorappearance.curve3 = shape3->getCurve (); pp->colorappearance.tempout = tempout->getValue (); + pp->colorappearance.autotempout = tempout->getAutoValue (); pp->colorappearance.greenout = greenout->getValue (); pp->colorappearance.ybout = ybout->getValue (); pp->colorappearance.tempsc = tempsc->getValue (); pp->colorappearance.greensc = greensc->getValue (); + pp->colorappearance.presetcat02 = presetcat02->get_active(); int tcMode = toneCurveMode->get_active_row_number(); @@ -1096,6 +1172,7 @@ void ColorAppearance::write (ProcParams* pp, ParamsEdited* pedited) pedited->colorappearance.surround = surround->get_active_text() != M ("GENERAL_UNCHANGED"); pedited->colorappearance.surrsrc = surrsrc->get_active_text() != M ("GENERAL_UNCHANGED"); pedited->colorappearance.wbmodel = wbmodel->get_active_text() != M ("GENERAL_UNCHANGED"); + pedited->colorappearance.illum = illum->get_active_text() != M ("GENERAL_UNCHANGED"); pedited->colorappearance.algo = algo->get_active_text() != M ("GENERAL_UNCHANGED"); // pedited->colorappearance.surrsource = !surrsource->get_inconsistent(); pedited->colorappearance.gamut = !gamut->get_inconsistent(); @@ -1114,6 +1191,8 @@ void ColorAppearance::write (ProcParams* pp, ParamsEdited* pedited) pedited->colorappearance.ybout = ybout->getEditedState (); pedited->colorappearance.tempsc = tempsc->getEditedState (); pedited->colorappearance.greensc = greensc->getEditedState (); + pedited->colorappearance.presetcat02 = presetcat02->get_inconsistent (); + pedited->colorappearance.autotempout = !tempout->getAutoInconsistent(); } @@ -1144,7 +1223,24 @@ void ColorAppearance::write (ProcParams* pp, ParamsEdited* pedited) pp->colorappearance.wbmodel = "RawTCAT02"; } else if (wbmodel->get_active_row_number() == 2) { pp->colorappearance.wbmodel = "free"; + } + if (illum->get_active_row_number() == 0) { + pp->colorappearance.illum = "iA"; + } else if (illum->get_active_row_number() == 1) { + pp->colorappearance.illum = "i41"; + } else if (illum->get_active_row_number() == 2) { + pp->colorappearance.illum = "i50"; + } else if (illum->get_active_row_number() == 3) { + pp->colorappearance.illum = "i55"; + } else if (illum->get_active_row_number() == 4) { + pp->colorappearance.illum = "i60"; + } else if (illum->get_active_row_number() == 5) { + pp->colorappearance.illum = "i65"; + } else if (illum->get_active_row_number() == 6) { + pp->colorappearance.illum = "i75"; + } else if (illum->get_active_row_number() == 7) { + pp->colorappearance.illum = "ifree"; } if (algo->get_active_row_number() == 0) { @@ -1309,6 +1405,133 @@ void ColorAppearance::badpix_toggled () { } */ +void ColorAppearance::presetcat02pressed () +{ + if (presetcat02->get_active ()) { + disableListener(); + jlight->resetValue (false); + qbright->resetValue (false); + chroma->resetValue (false); + schroma->resetValue (false); + mchroma->resetValue (false); + rstprotection->resetValue (false); + contrast->resetValue (false); + qcontrast->resetValue (false); + colorh->resetValue (false); + tempout->resetValue (false); + greenout->resetValue (false); + ybout->resetValue (false); + tempsc->resetValue (false); + greensc->resetValue (false); + badpixsl->resetValue (false); + wbmodel->set_active (0); + illum->set_active (2); + toneCurveMode->set_active (0); + toneCurveMode2->set_active (0); + toneCurveMode3->set_active (0); + shape->reset(); + shape2->reset(); + shape3->reset(); + gamutconn.block (true); + gamut->set_active (true); + gamutconn.block (false); + degree->setAutoValue (true); + degree->resetValue (false); + degree->setValue(90); + adapscen->resetValue (false); + adapscen->setAutoValue (true); + degreeout->resetValue (false); + degreeout->setAutoValue (true); + ybscen->resetValue (false); + ybscen->setAutoValue (true); + surrsrc->set_active (0); + wbmodel->set_active (2); + tempsc->resetValue (false); + greensc->resetValue (false); + adapscen->setValue(400.); + ybscen->setValue(18); + surround->set_active (0); + adaplum->setValue(400.); + degreeout->setValue(90); + ybout->setValue(18); + tempout->setValue (nexttemp); + greenout->setValue (nextgreen); + enableListener(); + } else { + disableListener(); +/* jlight->resetValue (false); + qbright->resetValue (false); + chroma->resetValue (false); + schroma->resetValue (false); + mchroma->resetValue (false); + rstprotection->resetValue (false); + contrast->resetValue (false); + qcontrast->resetValue (false); + colorh->resetValue (false); + tempout->resetValue (false); + greenout->resetValue (false); + ybout->resetValue (false); + tempsc->resetValue (false); + greensc->resetValue (false); + badpixsl->resetValue (false); + wbmodel->set_active (0); + toneCurveMode->set_active (0); + toneCurveMode2->set_active (0); + toneCurveMode3->set_active (0); + shape->reset(); + shape2->reset(); + shape3->reset(); + gamutconn.block (true); + gamut->set_active (true); + gamutconn.block (false); +*/ + degree->setAutoValue (true); + degree->resetValue (false); + adapscen->resetValue (false); + adapscen->setAutoValue (true); + degreeout->resetValue (false); + degreeout->setAutoValue (true); + ybscen->resetValue (false); + ybscen->setAutoValue (true); + surrsrc->set_active (0); + wbmodel->set_active (0); + illum->set_active (2); + tempsc->resetValue (false); + greensc->resetValue (false); + adapscen->resetValue (false); + ybscen->resetValue (false); + surround->set_active (0); + adaplum->resetValue (false); + degreeout->resetValue (false); + ybout->resetValue (false); + tempout->resetValue (false); + greenout->resetValue (false); + enableListener(); + + } + if (batchMode) { + if (presetcat02->get_inconsistent()) { + presetcat02->set_inconsistent (false); + presetcat02conn.block (true); + presetcat02->set_active (false); + presetcat02conn.block (false); + } else if (lastpresetcat02) { + presetcat02->set_inconsistent (true); + } + + lastpresetcat02 = presetcat02->get_active (); + } + + if (listener) { + if (presetcat02->get_active ()) { + listener->panelChanged (Evcatpreset, M ("GENERAL_ENABLED")); + } else { + listener->panelChanged (Evcatpreset, M ("GENERAL_DISABLED")); + } + } + +} + void ColorAppearance::datacie_toggled () { @@ -1470,6 +1693,10 @@ void ColorAppearance::autoCamChanged (double ccam, double ccamout) void ColorAppearance::adapCamChanged (double cadap) { + if(presetcat02->get_active()){ + return; + } + idle_register.add( [this, cadap]() -> bool { @@ -1481,8 +1708,28 @@ void ColorAppearance::adapCamChanged (double cadap) ); } + +void ColorAppearance::wbCamChanged (double temp, double tin) +{ + + idle_register.add( + [this, temp, tin]() -> bool + { + disableListener(); + tempout->setValue(temp); + greenout->setValue(tin); + enableListener(); + return false; + } + ); +} + void ColorAppearance::ybCamChanged (int ybsc) { + if(presetcat02->get_active()){ + return; + } + idle_register.add( [this, ybsc]() -> bool { @@ -1602,7 +1849,16 @@ void ColorAppearance::adjusterAutoToggled(Adjuster* a) ybscen->setAutoInconsistent (true); } - lastAutoybscen = ybscen->getAutoValue(); + lastAutotempout = tempout->getAutoValue(); + + if (tempout->getAutoInconsistent()) { + tempout->setAutoInconsistent (false); + tempout->setAutoValue (false); + } else if (lastAutotempout) { + tempout->setAutoInconsistent (true); + } + + lastAutotempout = tempout->getAutoValue(); } @@ -1649,6 +1905,15 @@ void ColorAppearance::adjusterAutoToggled(Adjuster* a) } } + if (a == tempout) { + if (tempout->getAutoInconsistent()) { + listener->panelChanged (EvCATAutotempout, M ("GENERAL_UNCHANGED")); + } else if (tempout->getAutoValue()) { + listener->panelChanged (EvCATAutotempout, M ("GENERAL_ENABLED")); + } else { + listener->panelChanged (EvCATAutotempout, M ("GENERAL_DISABLED")); + } + } } } @@ -1688,13 +1953,17 @@ void ColorAppearance::surroundChanged () void ColorAppearance::wbmodelChanged () { if (wbmodel->get_active_row_number() == 0 || wbmodel->get_active_row_number() == 1) { + illum->hide(); tempsc->hide(); greensc->hide(); + tempsc->setValue (5003); + greensc->setValue (1); } if (wbmodel->get_active_row_number() == 2) { tempsc->show(); greensc->show(); + illum->show(); } if (listener && (multiImage || getEnabled()) ) { @@ -1702,6 +1971,47 @@ void ColorAppearance::wbmodelChanged () } } +void ColorAppearance::illumChanged () +{ + if (illum->get_active_row_number() == 0) { + tempsc->setValue (2856); + tempsc->set_sensitive(false); + greensc->set_sensitive(false); + } else if (illum->get_active_row_number() == 1) { + tempsc->setValue (4100); + tempsc->set_sensitive(false); + greensc->set_sensitive(false); + } else if (illum->get_active_row_number() == 2) { + tempsc->setValue (5003); + tempsc->set_sensitive(false); + greensc->set_sensitive(false); + } else if (illum->get_active_row_number() == 3) { + tempsc->setValue (5503); + tempsc->set_sensitive(false); + greensc->set_sensitive(false); + } else if (illum->get_active_row_number() == 4) { + tempsc->setValue (6000); + tempsc->set_sensitive(false); + greensc->set_sensitive(false); + } else if (illum->get_active_row_number() == 5) { + tempsc->setValue (6504); + tempsc->set_sensitive(false); + greensc->set_sensitive(false); + } else if (illum->get_active_row_number() == 6) { + tempsc->setValue (7504); + tempsc->set_sensitive(false); + greensc->set_sensitive(false); + } else if (illum->get_active_row_number() == 7) { + tempsc->set_sensitive(true); + greensc->set_sensitive(true); + } + + if (listener && (multiImage || getEnabled()) ) { + listener->panelChanged (EvCATillum, illum->get_active_text ()); + } +} + + void ColorAppearance::algoChanged () { @@ -1804,6 +2114,7 @@ void ColorAppearance::setBatchMode (bool batchMode) surround->append (M ("GENERAL_UNCHANGED")); surrsrc->append (M ("GENERAL_UNCHANGED")); wbmodel->append (M ("GENERAL_UNCHANGED")); + illum->append (M ("GENERAL_UNCHANGED")); algo->append (M ("GENERAL_UNCHANGED")); toneCurveMode->append (M ("GENERAL_UNCHANGED")); toneCurveMode2->append (M ("GENERAL_UNCHANGED")); diff --git a/rtgui/colorappearance.h b/rtgui/colorappearance.h index c42bca774..c326b06f9 100644 --- a/rtgui/colorappearance.h +++ b/rtgui/colorappearance.h @@ -53,6 +53,7 @@ public: void surroundChanged (); void surrsrcChanged (); void wbmodelChanged (); + void illumChanged (); void algoChanged (); void surrsource_toggled (); void gamut_toggled (); @@ -63,10 +64,11 @@ public: void autoCamChanged (double ccam, double ccamout) override; bool autoCamComputed_ (); void adapCamChanged (double cadap) override; + void wbCamChanged(double tem, double tin) override; bool adapCamComputed_ (); void ybCamChanged (int yb) override; bool ybCamComputed_ (); - + void presetcat02pressed (); void curveChanged (CurveEditor* ce) override; void curveMode1Changed (); bool curveMode1Changed_ (); @@ -99,6 +101,9 @@ public: void writeOptions (std::vector &tpOpen); private: + rtengine::ProcEvent Evcatpreset; + rtengine::ProcEvent EvCATAutotempout; + rtengine::ProcEvent EvCATillum; bool bgTTipQuery (int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip); bool srTTipQuery (int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip); void foldAllButMe (GdkEventButton* event, MyExpander *expander); @@ -143,6 +148,9 @@ private: Gtk::CheckButton* tonecie; // Gtk::CheckButton* sharpcie; Gtk::Button* neutral; + Gtk::CheckButton* presetcat02; + sigc::connection presetcat02conn; + MyComboBoxText* surrsrc; sigc::connection surrsrcconn; @@ -150,6 +158,8 @@ private: sigc::connection surroundconn; MyComboBoxText* wbmodel; sigc::connection wbmodelconn; + MyComboBoxText* illum; + sigc::connection illumconn; MyComboBoxText* algo; sigc::connection algoconn; sigc::connection surrconn; @@ -168,10 +178,14 @@ private: bool lastAutoAdapscen; bool lastAutoDegreeout; bool lastAutoybscen; + bool lastAutotempout; bool lastsurr; bool lastgamut; bool lastdatacie; bool lasttonecie; + bool lastpresetcat02; + double nexttemp; + double nextgreen; IdleRegister idle_register; }; diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc index 59768a6ce..ddf917149 100644 --- a/rtgui/colortoning.cc +++ b/rtgui/colortoning.cc @@ -74,7 +74,7 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR // whole hue range for (int i = 0; i < 7; i++) { float R, G, B; - float x = float(i) * (1.0f / 6.0); + float x = float(i) * (1.0f / 6.f); Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); milestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); } @@ -1203,11 +1203,11 @@ void ColorToning::colorForValue (double valX, double valY, enum ColorCaller::Ele // the strength applied to the current hue double strength, hue; hlColSat->getValue(strength, hue); - Color::hsv2rgb01(hue / 360.f, 1.f, 1.f, R, G, B); + Color::hsv2rgb01(hue / 360.0, 1.f, 1.f, R, G, B); const double gray = 0.46; - R = (gray * (1.0 - valX)) + R * valX; - G = (gray * (1.0 - valX)) + G * valX; - B = (gray * (1.0 - valX)) + B * valX; + R = (gray * (1.0 - valX)) + static_cast(R) * valX; + G = (gray * (1.0 - valX)) + static_cast(G) * valX; + B = (gray * (1.0 - valX)) + static_cast(B) * valX; } } else if (callerId == 3) { // Slider 2 background if (valY <= 0.5) @@ -1218,17 +1218,17 @@ void ColorToning::colorForValue (double valX, double valY, enum ColorCaller::Ele // the strength applied to the current hue double strength, hue; shadowsColSat->getValue(strength, hue); - Color::hsv2rgb01(hue / 360.f, 1.f, 1.f, R, G, B); + Color::hsv2rgb01(hue / 360.0, 1.f, 1.f, R, G, B); const double gray = 0.46; - R = (gray * (1.0 - valX)) + R * valX; - G = (gray * (1.0 - valX)) + G * valX; - B = (gray * (1.0 - valX)) + B * valX; + R = (gray * (1.0 - valX)) + static_cast(R) * valX; + G = (gray * (1.0 - valX)) + static_cast(G) * valX; + B = (gray * (1.0 - valX)) + static_cast(B) * valX; } } else if (callerId == 4) { // color curve vertical and horizontal crosshair Color::hsv2rgb01(float(valY), 1.0f, 0.5f, R, G, B); } else if (callerId == ID_LABREGION_HUE) { // TODO - float x = valX - 1.f/6.f; + float x = valX - 1.0/6.0; if (x < 0.f) { x += 1.f; } diff --git a/rtgui/config.h.in b/rtgui/config.h.in index 95217b689..558c25f76 100644 --- a/rtgui/config.h.in +++ b/rtgui/config.h.in @@ -22,10 +22,19 @@ #cmakedefine BUILD_BUNDLE #cmakedefine HAVE_UNALIGNED_MALLOC + +#ifdef __APPLE__ +#define DATA_SEARCH_PATH "/Applications/RawTherapee.app/Contents/Resources/share" +#define DOC_SEARCH_PATH "/Applications/RawTherapee.app/Contents/Resources" +#define CREDITS_SEARCH_PATH "/Applications/RawTherapee.app/Contents/Resources" +#define LICENCE_SEARCH_PATH "/Applications/RawTherapee.app/Contents/Resources" +#define LENSFUN_DB_PATH "${LENSFUNDBDIR}" +#else #define DATA_SEARCH_PATH "${DATADIR}" #define DOC_SEARCH_PATH "${DOCDIR}" #define CREDITS_SEARCH_PATH "${CREDITSDIR}" #define LICENCE_SEARCH_PATH "${LICENCEDIR}" #define LENSFUN_DB_PATH "${LENSFUNDBDIR}" +#endif #endif diff --git a/rtgui/coordinateadjuster.cc b/rtgui/coordinateadjuster.cc index ebf36b7e7..57190cf63 100644 --- a/rtgui/coordinateadjuster.cc +++ b/rtgui/coordinateadjuster.cc @@ -69,14 +69,14 @@ void CoordinateAdjuster::AxisAdjuster::setValue(double newValue) { float range = rangeUpperBound - rangeLowerBound; spinButtonConn.block(true); - spinButton->set_value(newValue * range + rangeLowerBound); + spinButton->set_value(static_cast(newValue) * range + rangeLowerBound); spinButtonConn.block(false); } void CoordinateAdjuster::AxisAdjuster::valueChanged() { float range = rangeUpperBound - rangeLowerBound; - parent->updatePos(idx, (spinButton->get_value() - rangeLowerBound) / range); + parent->updatePos(idx, (static_cast(spinButton->get_value()) - rangeLowerBound) / range); } CoordinateAdjuster::CoordinateAdjuster(CoordinateProvider *provider, CurveEditorSubGroup *parent, const std::vector &axis) @@ -171,7 +171,7 @@ void CoordinateAdjuster::startNumericalAdjustment(const std::vector Gtk::SpinButton *currSpinButton = axisAdjusters.at(i)->spinButton; currSpinButton->set_sensitive(true); float range = axisAdjusters.at(i)->rangeUpperBound - axisAdjusters.at(i)->rangeLowerBound; - currSpinButton->set_range(newBoundaries.at(i).minVal * range + axisAdjusters.at(i)->rangeLowerBound, newBoundaries.at(i).maxVal * range + axisAdjusters.at(i)->rangeLowerBound); + currSpinButton->set_range(newBoundaries.at(i).minVal * static_cast(range) + static_cast(axisAdjusters.at(i)->rangeLowerBound), newBoundaries.at(i).maxVal * static_cast(range) + static_cast(axisAdjusters.at(i)->rangeLowerBound)); } axisAdjusters.at(0)->spinButton->grab_focus(); @@ -200,7 +200,7 @@ void CoordinateAdjuster::switchAdjustedPoint(std::vector &pos, const std // ...narrow the range to the new interval float range = axisAdjusters.at(i)->rangeUpperBound - axisAdjusters.at(i)->rangeLowerBound; - currAxis->spinButton->set_range(newBoundaries.at(i).minVal * range + axisAdjusters.at(i)->rangeLowerBound, newBoundaries.at(i).maxVal * range + axisAdjusters.at(i)->rangeLowerBound); + currAxis->spinButton->set_range(newBoundaries.at(i).minVal * static_cast(range) + static_cast(axisAdjusters.at(i)->rangeLowerBound), newBoundaries.at(i).maxVal * static_cast(range) + static_cast(axisAdjusters.at(i)->rangeLowerBound)); // enable events currAxis->spinButtonConn.block(false); diff --git a/rtgui/crop.cc b/rtgui/crop.cc index 3bdcf14cf..48d1e09af 100644 --- a/rtgui/crop.cc +++ b/rtgui/crop.cc @@ -16,6 +16,8 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include + #include "crop.h" #include "options.h" @@ -46,39 +48,82 @@ inline void get_custom_ratio(int w, int h, double &rw, double &rh) } // namespace +class Crop::CropRatios final +{ +public: + CropRatios() : + ratios{ + {M("GENERAL_ASIMAGE"), 0.0}, + {M("GENERAL_CURRENT"), -1.0}, + {"3:2", 3.0 / 2.0}, // L1.5, P0.666... + {"4:3", 4.0 / 3.0}, // L1.333..., P0.75 + {"16:9", 16.0 / 9.0}, // L1.777..., P0.5625 + {"16:10", 16.0 / 10.0}, // L1.6, P0.625 + {"1:1", 1.0 / 1.0}, // L1, P1 + {"2:1", 2.0 / 1.0}, // L2, P0.5 + {"3:1", 3.0 / 1.0}, // L3, P0.333... + {"4:1", 4.0 / 1.0}, // L4, P0.25 + {"5:1", 5.0 / 1.0}, // L5, P0.2 + {"6:1", 6.0 / 1.0}, // L6, P0.1666... + {"7:1", 7.0 / 1.0}, // L7, P0.142... + {"4:5", 4.0 / 5.0}, // L1.25, P0.8 + {"5:7", 5.0 / 7.0}, // L1.4, P0.714... + {"6:7", 6.0 / 7.0}, // L1.166..., P0.857... + {"6:17", 6.0 / 17.0}, // L2.833..., P0.352... + {"24:65 - XPAN", 24.0 / 65.0}, // L2.708..., P0.369... + {"1.414 - DIN EN ISO 216", 1.414}, // L1.414, P0.707... + {"3.5:5", 3.5 / 5.0}, // L1.428..., P0.7 + {"8.5:11 - US Letter", 8.5 / 11.0}, // L1.294..., P0.772... + {"9.5:12", 9.5 / 12.0}, // L1.263..., P0.791... + {"10:12", 10.0 / 12.0}, // L1.2, P0.833... + {"11:14", 11.0 / 14.0}, // L1.272..., P0.785... + {"11:17 - Tabloid", 11.0 / 17.0}, // L1.545..., P0.647... + {"13:19", 13.0 / 19.0}, // L1.461..., P0.684... + {"17:22", 17.0 / 22.0}, // L1.294..., P0.772... + {"45:35 - ePassport", 45.0 / 35.0}, // L1.285,... P0.777... + {"64:27", 64.0 / 27.0}, // L2.370..., P0.421... + } + { + } + + std::vector getLabels() const + { + std::vector res; + + res.reserve(ratios.size()); + + for (const auto& ratio : ratios) { + res.push_back(ratio.label); + } + + return res; + } + + double getValue(std::size_t index) const + { + return + index < ratios.size() + ? ratios[index].value + : ratios[0].value; + } + + void updateCurrentRatio(double value) + { + ratios[1].value = value; + } + +private: + struct CropRatio { + Glib::ustring label; + double value; + }; + + std::vector ratios; +}; + Crop::Crop(): FoldableToolPanel(this, "crop", M("TP_CROP_LABEL"), false, true), - crop_ratios{ - {M("GENERAL_ASIMAGE"), 0.0}, - {M("GENERAL_CURRENT"), -1.0}, - {"3:2", 3.0 / 2.0}, // L1.5, P0.666... - {"4:3", 4.0 / 3.0}, // L1.333..., P0.75 - {"16:9", 16.0 / 9.0}, // L1.777..., P0.5625 - {"16:10", 16.0 / 10.0}, // L1.6, P0.625 - {"1:1", 1.0 / 1.0}, // L1, P1 - {"2:1", 2.0 / 1.0}, // L2, P0.5 - {"3:1", 3.0 / 1.0}, // L3, P0.333... - {"4:1", 4.0 / 1.0}, // L4, P0.25 - {"5:1", 5.0 / 1.0}, // L5, P0.2 - {"6:1", 6.0 / 1.0}, // L6, P0.1666... - {"7:1", 7.0 / 1.0}, // L7, P0.142... - {"4:5", 4.0 / 5.0}, // L1.25, P0.8 - {"5:7", 5.0 / 7.0}, // L1.4, P0.714... - {"6:7", 6.0 / 7.0}, // L1.166..., P0.857... - {"6:17", 6.0 / 17.0}, // L2.833..., P0.352... - {"24:65 - XPAN", 24.0 / 65.0}, // L2.708..., P0.369... - {"1.414 - DIN EN ISO 216", 1.414}, // L1.414, P0.707... - {"3.5:5", 3.5 / 5.0}, // L1.428..., P0.7 - {"8.5:11 - US Letter", 8.5 / 11.0}, // L1.294..., P0.772... - {"9.5:12", 9.5 / 12.0}, // L1.263..., P0.791... - {"10:12", 10.0 / 12.0}, // L1.2, P0.833... - {"11:14", 11.0 / 14.0}, // L1.272..., P0.785... - {"11:17 - Tabloid", 11.0 / 17.0}, // L1.545..., P0.647... - {"13:19", 13.0 / 19.0}, // L1.461..., P0.684... - {"17:22", 17.0 / 22.0}, // L1.294..., P0.772... - {"45:35 - ePassport", 45.0 / 35.0}, // L1.285,... P0.777... - {"64:27", 64.0 / 27.0}, // L2.370..., P0.421... - }, + crop_ratios(new CropRatios), opt(0), wDirty(true), hDirty(true), @@ -229,8 +274,8 @@ Crop::Crop(): // ppigrid END // Populate the combobox - for (const auto& crop_ratio : crop_ratios) { - ratio->append (crop_ratio.label); + for (const auto& label : crop_ratios->getLabels()) { + ratio->append (label); } ratio->set_active (0); @@ -354,7 +399,10 @@ void Crop::read (const ProcParams* pp, const ParamsEdited* pedited) setDimensions (pp->crop.x + pp->crop.w, pp->crop.y + pp->crop.h); } - const bool flip_orientation = pp->crop.fixratio && crop_ratios[ratio->get_active_row_number()].value > 0 && crop_ratios[ratio->get_active_row_number()].value < 1.0; + const bool flip_orientation = + pp->crop.fixratio + && crop_ratios->getValue(ratio->get_active_row_number()) > 0 + && crop_ratios->getValue(ratio->get_active_row_number()) < 1.0; if (pp->crop.orientation == "Landscape") { orientation->set_active (flip_orientation ? 1 : 0); @@ -469,7 +517,10 @@ void Crop::write (ProcParams* pp, ParamsEdited* pedited) } // for historical reasons we store orientation different if ratio is written as 2:3 instead of 3:2, but in GUI 'landscape' is always long side horizontal regardless of the ratio is written short or long side first. - const bool flip_orientation = fixr->get_active() && crop_ratios[ratio->get_active_row_number()].value > 0 && crop_ratios[ratio->get_active_row_number()].value < 1.0; + const bool flip_orientation = + fixr->get_active() + && crop_ratios->getValue(ratio->get_active_row_number()) > 0 + && crop_ratios->getValue(ratio->get_active_row_number()) < 1.0; if (orientation->get_active_row_number() == 0) { pp->crop.orientation = flip_orientation ? "Portrait" : "Landscape"; @@ -561,6 +612,11 @@ void Crop::doresetCrop () yDirty = true; wDirty = true; hDirty = true; + + // Reset ratio, ratio lock and orientation as well + ratio->set_active(0); + orientation->set_active(2); + fixr->set_active(true); int X = 0; int Y = 0; @@ -1006,7 +1062,7 @@ void Crop::cropWidth1Resized (int &X, int &Y, int &W, int &H, float custom_ratio } if (fixr->get_active() || custom_ratio > 0) { - double r = custom_ratio > 0 ? custom_ratio : getRatio(); + double r = custom_ratio > 0.f ? custom_ratio : static_cast(getRatio()); H = (int)round(W / r); int Hmax = min(ny + nh, maxh - ny); @@ -1053,7 +1109,7 @@ void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H, float custom_ratio } if (fixr->get_active() || custom_ratio > 0) { - double r = custom_ratio > 0 ? custom_ratio : getRatio(); + double r = custom_ratio > 0 ? custom_ratio : static_cast(getRatio()); H = (int)round(W / r); int Hmax = min(ny + nh, maxh - ny); @@ -1101,7 +1157,7 @@ void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H, float custom_rati } if (fixr->get_active() || custom_ratio > 0) { - double r = custom_ratio > 0 ? custom_ratio : getRatio(); + double r = custom_ratio > 0 ? custom_ratio : static_cast(getRatio()); W = (int)round(H * r); int Wmax = min(nx + nw, maxw - nx); @@ -1148,7 +1204,7 @@ void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H, float custom_rati } if (fixr->get_active() || custom_ratio > 0) { - double r = custom_ratio > 0 ? custom_ratio : getRatio(); + double r = custom_ratio > 0 ? custom_ratio : static_cast(getRatio()); W = (int)round(H * r); int Wmax = min(nx + nw, maxw - nx); @@ -1205,7 +1261,7 @@ void Crop::cropTopLeftResized (int &X, int &Y, int &W, int &H, float custom_rati } if (fixr->get_active() || custom_ratio > 0) { - double r = custom_ratio > 0 ? custom_ratio : getRatio(); + double r = custom_ratio > 0 ? custom_ratio : static_cast(getRatio()); W = (int)round(H * r); if (W > oldXR) { @@ -1252,7 +1308,7 @@ void Crop::cropTopRightResized (int &X, int &Y, int &W, int &H, float custom_rat } if (fixr->get_active() || custom_ratio > 0) { - double r = custom_ratio > 0 ? custom_ratio : getRatio(); + double r = custom_ratio > 0 ? custom_ratio : static_cast(getRatio()); W = (int)round(H * r); if (W > maxw - nx) { @@ -1298,7 +1354,7 @@ void Crop::cropBottomLeftResized (int &X, int &Y, int &W, int &H, float custom_r } if (fixr->get_active() || custom_ratio > 0) { - double r = custom_ratio > 0 ? custom_ratio : getRatio(); + double r = custom_ratio > 0 ? custom_ratio : static_cast(getRatio()); W = (int)round(H * r); if (W > oldXR) { @@ -1342,7 +1398,7 @@ void Crop::cropBottomRightResized (int &X, int &Y, int &W, int &H, float custom_ } if (fixr->get_active() || custom_ratio > 0) { - double r = custom_ratio > 0 ? custom_ratio : getRatio(); + double r = custom_ratio > 0 ? custom_ratio : static_cast(getRatio()); W = (int)round(H * r); if (W > maxw - nx) { @@ -1501,7 +1557,7 @@ double Crop::getRatio () const return r; } - r = crop_ratios[ratio->get_active_row_number()].value; + r = crop_ratios->getValue(ratio->get_active_row_number()); if (!r) { r = maxh <= maxw ? float(maxh)/float(maxw) : float(maxw)/float(maxh); } @@ -1539,5 +1595,5 @@ void Crop::updateCurrentRatio() double rw, rh; get_custom_ratio(w->get_value(), h->get_value(), rw, rh); customRatioLabel->set_text(Glib::ustring::compose("%1:%2", rw, rh)); - crop_ratios[1].value = double(w->get_value())/double(h->get_value()); + crop_ratios->updateCurrentRatio(static_cast(w->get_value()) / static_cast(h->get_value())); } diff --git a/rtgui/crop.h b/rtgui/crop.h index b9221a803..c6636b917 100644 --- a/rtgui/crop.h +++ b/rtgui/crop.h @@ -18,7 +18,7 @@ */ #pragma once -#include +#include #include @@ -91,16 +91,13 @@ public: void rotateCrop (int deg, bool hflip, bool vflip); private: - struct CropRatio { - Glib::ustring label; - double value; - }; - - std::vector crop_ratios; + class CropRatios; void adjustCropToRatio(); void updateCurrentRatio(); + const std::unique_ptr crop_ratios; + Gtk::CheckButton* fixr; MyComboBoxText* ratio; MyComboBoxText* orientation; diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index edc378700..d87876cec 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -124,7 +124,7 @@ void CropWindow::initZoomSteps() zoomSteps.push_back(ZoomStep(" 8%", 1.0/12.0, 120, true)); char lbl[64]; for (int s = 100; s >= 11; --s) { - float z = 10./float(s); + float z = 10.f / s; sprintf(lbl, "% 2d%%", int(z * 100)); bool is_major = (s == s/10 * 10); zoomSteps.push_back(ZoomStep(lbl, z, s, is_major)); @@ -295,7 +295,7 @@ void CropWindow::flawnOver (bool isFlawnOver) void CropWindow::scroll (int state, GdkScrollDirection direction, int x, int y, double deltaX, double deltaY) { double delta = 0.0; - if (abs(deltaX) > abs(deltaY)) { + if (std::fabs(deltaX) > std::fabs(deltaY)) { delta = deltaX; } else { delta = deltaY; @@ -304,7 +304,7 @@ void CropWindow::scroll (int state, GdkScrollDirection direction, int x, int y, if (direction == GDK_SCROLL_SMOOTH) { scrollAccum += delta; //Only change zoom level if we've accumulated +/- 1.0 of deltas. This conditional handles the previous delta=0.0 case - if (abs(scrollAccum) < 1.0) { + if (std::fabs(scrollAccum) < 1.0) { return; } } diff --git a/rtgui/defringe.cc b/rtgui/defringe.cc index cdec88edc..7aae8377a 100644 --- a/rtgui/defringe.cc +++ b/rtgui/defringe.cc @@ -37,7 +37,7 @@ Defringe::Defringe () : FoldableToolPanel(this, "defringe", M("TP_DEFRINGE_LABEL float R, G, B; for (int i = 0; i < 7; i++) { - float x = float(i) * (1.0f / 6.0); + float x = i / 6.f; Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); bottomMilestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); } diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index eed6c63d3..079a083ea 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -477,13 +477,13 @@ void DiagonalCurveEditorSubGroup::pipetteMouseOver(EditDataProvider *provider, i double pos[3]; shcSelector->getPositions(pos[0], pos[1], pos[2]); - if (pipetteVal >= pos[2]) { + if (static_cast(pipetteVal) >= pos[2]) { editedAdjuster = highlights; paramCurve->setActiveParam(4); - } else if(pipetteVal >= pos[1]) { + } else if(static_cast(pipetteVal) >= pos[1]) { editedAdjuster = lights; paramCurve->setActiveParam(5); - } else if(pipetteVal >= pos[0]) { + } else if(static_cast(pipetteVal) >= pos[0]) { editedAdjuster = darks; paramCurve->setActiveParam(6); } else { diff --git a/rtgui/dirpyrequalizer.cc b/rtgui/dirpyrequalizer.cc index fd0268efa..34aecf095 100644 --- a/rtgui/dirpyrequalizer.cc +++ b/rtgui/dirpyrequalizer.cc @@ -428,7 +428,7 @@ void DirPyrEqualizer::lumacontrastPlusPressed () { for (int i = 0; i < 6; i++) { - float inc = 0.05 * (6 - i); + double inc = 0.05 * (6 - i); multiplier[i]->setValue(multiplier[i]->getValue() + inc); adjusterChanged(multiplier[i], multiplier[i]->getValue()); } @@ -439,7 +439,7 @@ void DirPyrEqualizer::lumacontrastMinusPressed () { for (int i = 0; i < 6; i++) { - float inc = -0.05 * (6 - i); + double inc = -0.05 * (6 - i); multiplier[i]->setValue(multiplier[i]->getValue() + inc); adjusterChanged(multiplier[i], multiplier[i]->getValue()); } diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 9a2ecf316..93e704d57 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -172,7 +172,7 @@ private: const std::vector profiles = rtengine::ICCStore::getInstance()->getProfiles (rtengine::ICCStore::ProfileType::MONITOR); - for (const auto profile : profiles) { + for (const auto& profile : profiles) { profileBox.append (profile); } diff --git a/rtgui/editwidgets.cc b/rtgui/editwidgets.cc index 2928104b7..fccdb874a 100644 --- a/rtgui/editwidgets.cc +++ b/rtgui/editwidgets.cc @@ -126,13 +126,13 @@ void Circle::drawInnerGeometry(Cairo::RefPtr &cr, ObjectMOBuffer if (filled && state != INSENSITIVE) { cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0., 2.*rtengine::RT_PI); - if (innerLineWidth > 0.) { + if (innerLineWidth > 0.f) { cr->fill_preserve(); cr->stroke(); } else { cr->fill(); } - } else if (innerLineWidth > 0.) { + } else if (innerLineWidth > 0.f) { cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0., 2.*rtengine::RT_PI); if (state == INSENSITIVE) { @@ -176,7 +176,7 @@ void Circle::drawToMOChannel (Cairo::RefPtr &cr, unsigned short cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0, 2.*rtengine::RT_PI); if (filled) { - if (innerLineWidth > 0.) { + if (innerLineWidth > 0.f) { cr->fill_preserve(); cr->stroke(); } else { @@ -224,7 +224,7 @@ void Line::drawOuterGeometry(Cairo::RefPtr &cr, ObjectMOBuffer * void Line::drawInnerGeometry(Cairo::RefPtr &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) { - if ((flags & F_VISIBLE) && innerLineWidth > 0.) { + if ((flags & F_VISIBLE) && innerLineWidth > 0.f) { if (state != INSENSITIVE) { RGBColor color; @@ -383,13 +383,13 @@ void Polyline::drawInnerGeometry(Cairo::RefPtr &cr, ObjectMOBuff } } - if (innerLineWidth > 0.) { + if (innerLineWidth > 0.f) { cr->fill_preserve(); cr->stroke(); } else { cr->fill(); } - } else if (innerLineWidth > 0.) { + } else if (innerLineWidth > 0.f) { rtengine::Coord currPos; for (unsigned int i = 0; i < points.size(); ++i) { @@ -459,7 +459,7 @@ void Polyline::drawToMOChannel (Cairo::RefPtr &cr, unsigned shor } if (filled) { - if (innerLineWidth > 0.) { + if (innerLineWidth > 0.f) { cr->fill_preserve(); cr->stroke(); } else { @@ -576,13 +576,13 @@ void Rectangle::drawInnerGeometry(Cairo::RefPtr &cr, ObjectMOBuf if (filled && state != INSENSITIVE) { cr->rectangle(tl.x + 0.5, tl.y + 0.5, br.x - tl.x, br.y - tl.y); - if (innerLineWidth > 0.) { + if (innerLineWidth > 0.f) { cr->fill_preserve(); cr->stroke(); } else { cr->fill(); } - } else if (innerLineWidth > 0.) { + } else if (innerLineWidth > 0.f) { cr->rectangle(tl.x + 0.5, tl.y + 0.5, br.x - tl.x, br.y - tl.y); if (state == INSENSITIVE) { @@ -634,7 +634,7 @@ void Rectangle::drawToMOChannel(Cairo::RefPtr &cr, unsigned shor cr->rectangle(tl.x + 0.5, tl.y + 0.5, br.x - tl.x, br.y - tl.y); if (filled) { - if (innerLineWidth > 0.) { + if (innerLineWidth > 0.f) { cr->fill_preserve(); cr->stroke(); } else { diff --git a/rtgui/epd.cc b/rtgui/epd.cc index b13effba3..d032cf28d 100644 --- a/rtgui/epd.cc +++ b/rtgui/epd.cc @@ -31,8 +31,8 @@ EdgePreservingDecompositionUI::EdgePreservingDecompositionUI () : FoldableToolPa strength = Gtk::manage(new Adjuster (M("TP_EPD_STRENGTH"), -1.0, 2.0, 0.01, 0.5)); gamma = Gtk::manage(new Adjuster (M("TP_EPD_GAMMA"), 0.8, 1.5, 0.01, 1.)); - edgeStopping = Gtk::manage(new Adjuster (M("TP_EPD_EDGESTOPPING"), 0.1, 4.0, 0.01, 0.5)); - scale = Gtk::manage(new Adjuster (M("TP_EPD_SCALE"), 0.1, 10.0, 0.01, 0.1)); + edgeStopping = Gtk::manage(new Adjuster (M("TP_EPD_EDGESTOPPING"), 0.1, 4.0, 0.01, 1.4)); + scale = Gtk::manage(new Adjuster (M("TP_EPD_SCALE"), 0.1, 10.0, 0.01, 1.0)); reweightingIterates = Gtk::manage(new Adjuster (M("TP_EPD_REWEIGHTINGITERATES"), 0, 9, 1, 0)); strength->setAdjusterListener(this); diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 90cedf148..1b105a3ec 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -44,6 +44,17 @@ Adjuster* createExponentAdjuster(AdjusterListener* listener, const Glib::ustring return adj; } +Glib::ustring formatBaseValues(const std::array& rgb) +{ + if (rgb[0] <= 0.f && rgb[1] <= 0.f && rgb[2] <= 0.f) { + return "- - -"; + } else { + return Glib::ustring::format(std::fixed, std::setprecision(1), rgb[0]) + " " + + Glib::ustring::format(std::fixed, std::setprecision(1), rgb[1]) + " " + + Glib::ustring::format(std::fixed, std::setprecision(1), rgb[2]); + } +} + } FilmNegative::FilmNegative() : @@ -51,12 +62,17 @@ FilmNegative::FilmNegative() : EditSubscriber(ET_OBJECTS), evFilmNegativeExponents(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_VALUES")), evFilmNegativeEnabled(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_ENABLED")), + evFilmBaseValues(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_FILMBASE")), + filmBaseValues({0.f, 0.f, 0.f}), fnp(nullptr), greenExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_GREEN"), 0.3, 4, 1.5)), // master exponent (green channel) redRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 0.3, 3, (2.04 / 1.5))), // ratio of red exponent to master exponent blueRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 0.3, 3, (1.29 / 1.5))), // ratio of blue exponent to master exponent spotgrid(Gtk::manage(new Gtk::Grid())), - spotbutton(Gtk::manage(new Gtk::ToggleButton(M("TP_FILMNEGATIVE_PICK")))) + spotbutton(Gtk::manage(new Gtk::ToggleButton(M("TP_FILMNEGATIVE_PICK")))), + filmBaseLabel(Gtk::manage(new Gtk::Label(M("TP_FILMNEGATIVE_FILMBASE_VALUES"), Gtk::ALIGN_START))), + filmBaseValuesLabel(Gtk::manage(new Gtk::Label("- - -"))), + filmBaseSpotButton(Gtk::manage(new Gtk::ToggleButton(M("TP_FILMNEGATIVE_FILMBASE_PICK")))) { spotgrid->get_style_context()->add_class("grid-spacing"); setExpandAlignProperties(spotgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); @@ -64,7 +80,10 @@ FilmNegative::FilmNegative() : setExpandAlignProperties(spotbutton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); spotbutton->get_style_context()->add_class("independent"); spotbutton->set_tooltip_text(M("TP_FILMNEGATIVE_GUESS_TOOLTIP")); - spotbutton->set_image (*Gtk::manage (new RTImage ("color-picker-small.png"))); + spotbutton->set_image(*Gtk::manage(new RTImage("color-picker-small.png"))); + + filmBaseSpotButton->set_tooltip_text(M("TP_FILMNEGATIVE_FILMBASE_TOOLTIP")); + setExpandAlignProperties(filmBaseValuesLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); // TODO make spot size configurable ? @@ -81,7 +100,7 @@ FilmNegative::FilmNegative() : // spotsize->set_active(0); // spotsize->append ("4"); - spotgrid->attach (*spotbutton, 0, 1, 1, 1); + spotgrid->attach(*spotbutton, 0, 1, 1, 1); // spotgrid->attach (*slab, 1, 0, 1, 1); // spotgrid->attach (*wbsizehelper, 2, 0, 1, 1); @@ -90,13 +109,26 @@ FilmNegative::FilmNegative() : pack_start(*blueRatio, Gtk::PACK_SHRINK, 0); pack_start(*spotgrid, Gtk::PACK_SHRINK, 0); + Gtk::HSeparator* const sep = Gtk::manage(new Gtk::HSeparator()); + sep->get_style_context()->add_class("grid-row-separator"); + pack_start(*sep, Gtk::PACK_SHRINK, 0); + + Gtk::Grid* const fbGrid = Gtk::manage(new Gtk::Grid()); + fbGrid->attach(*filmBaseLabel, 0, 0, 1, 1); + fbGrid->attach(*filmBaseValuesLabel, 1, 0, 1, 1); + pack_start(*fbGrid, Gtk::PACK_SHRINK, 0); + + pack_start(*filmBaseSpotButton, Gtk::PACK_SHRINK, 0); + spotbutton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); // spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) ); + filmBaseSpotButton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::baseSpotToggled)); + // Editing geometry; create the spot rectangle Rectangle* const spotRect = new Rectangle(); spotRect->filled = false; - + visibleGeometry.push_back(spotRect); // Stick a dummy rectangle over the whole image in mouseOverGeometry. @@ -134,6 +166,14 @@ void FilmNegative::read(const rtengine::procparams::ProcParams* pp, const Params greenExp->setValue(pp->filmNegative.greenExp); blueRatio->setValue(pp->filmNegative.blueRatio); + filmBaseValues[0] = pp->filmNegative.redBase; + filmBaseValues[1] = pp->filmNegative.greenBase; + filmBaseValues[2] = pp->filmNegative.blueBase; + + // If base values are not set in params, estimated values will be passed in later + // (after processing) via FilmNegListener + filmBaseValuesLabel->set_text(formatBaseValues(filmBaseValues)); + enableListener(); } @@ -142,14 +182,23 @@ void FilmNegative::write(rtengine::procparams::ProcParams* pp, ParamsEdited* ped pp->filmNegative.redRatio = redRatio->getValue(); pp->filmNegative.greenExp = greenExp->getValue(); pp->filmNegative.blueRatio = blueRatio->getValue(); + pp->filmNegative.enabled = getEnabled(); if (pedited) { pedited->filmNegative.redRatio = redRatio->getEditedState(); pedited->filmNegative.greenExp = greenExp->getEditedState(); pedited->filmNegative.blueRatio = blueRatio->getEditedState(); + pedited->filmNegative.baseValues = filmBaseValues[0] != pp->filmNegative.redBase + || filmBaseValues[1] != pp->filmNegative.greenBase + || filmBaseValues[2] != pp->filmNegative.blueBase; pedited->filmNegative.enabled = !get_inconsistent(); } + + pp->filmNegative.redBase = filmBaseValues[0]; + pp->filmNegative.greenBase = filmBaseValues[1]; + pp->filmNegative.blueBase = filmBaseValues[2]; + } void FilmNegative::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) @@ -172,8 +221,8 @@ void FilmNegative::setDefaults(const rtengine::procparams::ProcParams* defParams void FilmNegative::setBatchMode(bool batchMode) { if (batchMode) { - spotConn.disconnect(); removeIfThere(this, spotgrid, false); + removeIfThere(this, filmBaseSpotButton, false); ToolPanel::setBatchMode(batchMode); redRatio->showEditedCB(); greenExp->showEditedCB(); @@ -205,16 +254,20 @@ void FilmNegative::enabledChanged() if (listener) { if (get_inconsistent()) { listener->panelChanged(evFilmNegativeEnabled, M("GENERAL_UNCHANGED")); - } - else if (getEnabled()) { + } else if (getEnabled()) { listener->panelChanged(evFilmNegativeEnabled, M("GENERAL_ENABLED")); - } - else { + } else { listener->panelChanged(evFilmNegativeEnabled, M("GENERAL_DISABLED")); } } } +void FilmNegative::filmBaseValuesChanged(std::array rgb) +{ + filmBaseValues = rgb; + filmBaseValuesLabel->set_text(formatBaseValues(filmBaseValues)); +} + void FilmNegative::setFilmNegProvider(FilmNegProvider* provider) { fnp = provider; @@ -227,7 +280,7 @@ void FilmNegative::setEditProvider(EditDataProvider* provider) CursorShape FilmNegative::getCursor(int objectID) const { - return CSSpotWB; + return CSSpotWB; } bool FilmNegative::mouseOver(int modifierKey) @@ -246,31 +299,57 @@ bool FilmNegative::button1Pressed(int modifierKey) EditSubscriber::action = EditSubscriber::Action::NONE; if (listener) { - refSpotCoords.push_back(provider->posImage); + if (spotbutton->get_active()) { - if (refSpotCoords.size() == 2) { - // User has selected 2 reference gray spots. Calculating new exponents - // from channel values and updating parameters. + refSpotCoords.push_back(provider->posImage); - std::array newExps; - if (fnp->getFilmNegativeExponents(refSpotCoords[0], refSpotCoords[1], newExps)) { + if (refSpotCoords.size() == 2) { + // User has selected 2 reference gray spots. Calculating new exponents + // from channel values and updating parameters. + + std::array newExps; + + if (fnp->getFilmNegativeExponents(refSpotCoords[0], refSpotCoords[1], newExps)) { + disableListener(); + // Leaving green exponent unchanged, setting red and blue exponents based on + // the ratios between newly calculated exponents. + redRatio->setValue(newExps[0] / newExps[1]); + blueRatio->setValue(newExps[2] / newExps[1]); + enableListener(); + + if (listener && getEnabled()) { + listener->panelChanged( + evFilmNegativeExponents, + Glib::ustring::compose( + "Ref=%1\nR=%2\nB=%3", + greenExp->getValue(), + redRatio->getValue(), + blueRatio->getValue() + ) + ); + } + } + + switchOffEditMode(); + } + + } else if (filmBaseSpotButton->get_active()) { + + std::array newBaseLev; + + if (fnp->getRawSpotValues(provider->posImage, 32, newBaseLev)) { disableListener(); - // Leaving green exponent unchanged, setting red and blue exponents based on - // the ratios between newly calculated exponents. - redRatio->setValue(newExps[0] / newExps[1]); - blueRatio->setValue(newExps[2] / newExps[1]); + + filmBaseValues = newBaseLev; + enableListener(); + const Glib::ustring vs = formatBaseValues(filmBaseValues); + + filmBaseValuesLabel->set_text(vs); + if (listener && getEnabled()) { - listener->panelChanged( - evFilmNegativeExponents, - Glib::ustring::compose( - "Ref=%1\nR=%2\nB=%3", - greenExp->getValue(), - redRatio->getValue(), - blueRatio->getValue() - ) - ); + listener->panelChanged(evFilmBaseValues, vs); } } @@ -292,11 +371,38 @@ void FilmNegative::switchOffEditMode() refSpotCoords.clear(); unsubscribe(); spotbutton->set_active(false); + filmBaseSpotButton->set_active(false); } void FilmNegative::editToggled() { if (spotbutton->get_active()) { + + filmBaseSpotButton->set_active(false); + refSpotCoords.clear(); + + subscribe(); + + int w, h; + getEditProvider()->getImageSize(w, h); + + // Stick a dummy rectangle over the whole image in mouseOverGeometry. + // This is to make sure the getCursor() call is fired everywhere. + Rectangle* const imgRect = static_cast(mouseOverGeometry.at(0)); + imgRect->setXYWH(0, 0, w, h); + } else { + refSpotCoords.clear(); + unsubscribe(); + } +} + +void FilmNegative::baseSpotToggled() +{ + if (filmBaseSpotButton->get_active()) { + + spotbutton->set_active(false); + refSpotCoords.clear(); + subscribe(); int w, h; diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index bca155ceb..0810a8c57 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -33,13 +33,15 @@ public: virtual ~FilmNegProvider() = default; virtual bool getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, std::array& newExps) = 0; + virtual bool getRawSpotValues(rtengine::Coord spot, int spotSize, std::array& rawValues) = 0; }; class FilmNegative final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, - public EditSubscriber + public EditSubscriber, + public rtengine::FilmNegListener { public: FilmNegative(); @@ -53,6 +55,8 @@ public: void adjusterChanged(Adjuster* a, double newval) override; void enabledChanged() override; + void filmBaseValuesChanged(std::array rgb) override; + void setFilmNegProvider(FilmNegProvider* provider); void setEditProvider(EditDataProvider* provider) override; @@ -66,12 +70,16 @@ public: private: void editToggled(); + void baseSpotToggled(); const rtengine::ProcEvent evFilmNegativeExponents; const rtengine::ProcEvent evFilmNegativeEnabled; + const rtengine::ProcEvent evFilmBaseValues; std::vector refSpotCoords; + std::array filmBaseValues; + FilmNegProvider* fnp; Adjuster* const greenExp; @@ -80,5 +88,9 @@ private: Gtk::Grid* const spotgrid; Gtk::ToggleButton* const spotbutton; - sigc::connection spotConn; + + Gtk::Label* const filmBaseLabel; + Gtk::Label* const filmBaseValuesLabel; + Gtk::ToggleButton* const filmBaseSpotButton; + }; diff --git a/rtgui/gradient.cc b/rtgui/gradient.cc index fceb6c006..8229e883a 100644 --- a/rtgui/gradient.cc +++ b/rtgui/gradient.cc @@ -166,7 +166,7 @@ void Gradient::updateGeometry(const int centerX, const int centerY, const double const auto decay = feather * rtengine::norm2 (imW, imH) / 200.0; rtengine::Coord origin (imW / 2 + centerX * imW / 200, imH / 2 + centerY * imH / 200); - const auto updateLine = [&](Geometry* geometry, const float radius, const float begin, const float end) + const auto updateLine = [&](Geometry* geometry, const double radius, const double begin, const double end) { const auto line = static_cast(geometry); line->begin = PolarCoord(radius, -degree + begin); @@ -175,7 +175,7 @@ void Gradient::updateGeometry(const int centerX, const int centerY, const double line->end += origin; }; - const auto updateLineWithDecay = [&](Geometry* geometry, const float radius, const float offSetAngle) + const auto updateLineWithDecay = [&](Geometry* geometry, const double radius, const double offSetAngle) { const auto line = static_cast(geometry); line->begin = PolarCoord (radius, -degree + 180.) + PolarCoord (decay, -degree + offSetAngle); diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 9a4e71ab4..d759751c3 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -826,12 +826,6 @@ void MyExpander::set_expanded( bool expanded ) return; } - bool isVisible = expBox->is_visible(); - - if (isVisible == expanded) { - return; - } - if (!useEnabled) { if (expanded ) { statusImage->set(openedImage->get_surface()); diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index dd0cbde46..b8338e4e8 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -518,26 +518,26 @@ void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustrin // Luma cc->set_source_rgb(1.0, 1.0, 1.0); if (options.histogramDrawMode < 2) { - cc->move_to(Lab_L * (winw - 3.*s) / 100.0 + 0.5*s, 0); - cc->line_to(Lab_L * (winw - 3.*s) / 100.0 + 0.5*s, winh - 0); + cc->move_to(static_cast(Lab_L) * (winw - 3. * s) / 100.0 + 0.5 * s, 0); + cc->line_to(static_cast(Lab_L) * (winw - 3. * s) / 100.0 + 0.5 * s, winh - 0); } else { - cc->move_to(HistogramScaling::log (100, Lab_L) * (winw - 1.) / 100.0 + 0.5*s, 0); - cc->line_to(HistogramScaling::log (100, Lab_L) * (winw - 1.) / 100.0 + 0.5*s, winh - 0); + cc->move_to(HistogramScaling::log(100, Lab_L) * (winw - 1.) / 100.0 + 0.5 * s, 0); + cc->line_to(HistogramScaling::log(100, Lab_L) * (winw - 1.) / 100.0 + 0.5 * s, winh - 0); } cc->stroke(); } if (needChroma) { // Chroma - float chromaval = sqrt(Lab_a * Lab_a + Lab_b * Lab_b) / 1.8; + double chromaval = sqrt(Lab_a * Lab_a + Lab_b * Lab_b) / 1.8; // float chromaval = sqrt(Lab_a*Lab_a + Lab_b*Lab_b); cc->set_source_rgb(0.9, 0.9, 0.0); if (options.histogramDrawMode < 2) { - cc->move_to(chromaval * (winw - 1.) / 100.0 + 0.5*s, 0); - cc->line_to(chromaval * (winw - 1.) / 100.0 + 0.5*s, winh - 0); + cc->move_to(chromaval * (winw - 1.) / 100.0 + 0.5 * s, 0); + cc->line_to(chromaval * (winw - 1.) / 100.0 + 0.5 * s, winh - 0); } else { - cc->move_to(HistogramScaling::log (100, chromaval) * (winw - 1.) / 100.0 + 0.5*s, 0); - cc->line_to(HistogramScaling::log (100, chromaval) * (winw - 1.) / 100.0 + 0.5*s, winh - 0); + cc->move_to(HistogramScaling::log(100, chromaval) * (winw - 1.) / 100.0 + 0.5 * s, 0); + cc->line_to(HistogramScaling::log(100, chromaval) * (winw - 1.) / 100.0 + 0.5 * s, winh - 0); } cc->stroke(); } @@ -989,7 +989,7 @@ void HistogramArea::drawCurve(Cairo::RefPtr &cr, cr->set_line_width(s); cr->move_to (0, vsize - 1); - scale = scale <= 0.f ? 0.001f : scale; // avoid division by zero and negative values + scale = scale <= 0.0 ? 0.001 : scale; // avoid division by zero and negative values for (int i = 0; i < 256; i++) { double val = data[i] * (double)vsize / scale; diff --git a/rtgui/hsvequalizer.cc b/rtgui/hsvequalizer.cc index ee3eb90a7..817ba1f4d 100644 --- a/rtgui/hsvequalizer.cc +++ b/rtgui/hsvequalizer.cc @@ -38,7 +38,7 @@ HSVEqualizer::HSVEqualizer () : FoldableToolPanel(this, "hsvequalizer", M("TP_HS // -0.1 rad < Hue < 1.6 rad for (int i = 0; i < 7; i++) { - float x = float(i) * (1.0f / 6.0); + float x = i / 6.0; Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); bottomMilestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); } diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc index 491b02c4c..5f4febc0a 100644 --- a/rtgui/labcurve.cc +++ b/rtgui/labcurve.cc @@ -203,7 +203,7 @@ LCurve::LCurve () : FoldableToolPanel(this, "labcurves", M("TP_LABCURVE_LABEL"), for (int i = 0; i < 7; i++) { float R, G, B; - float x = float(i) * (1.0f / 6.0); + float x = i / 6.0; Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); milestones.emplace_back(x, R, G, B); } diff --git a/rtgui/labgrid.cc b/rtgui/labgrid.cc index 516dbb825..d8a22b1d9 100644 --- a/rtgui/labgrid.cc +++ b/rtgui/labgrid.cc @@ -209,8 +209,8 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) float x, y, z; int ii = i - cells/2; int jj = j - cells/2; - float a = step * (ii + 0.5); - float b = step * (jj + 0.5); + float a = step * (ii + 0.5f); + float b = step * (jj + 0.5f); Color::Lab2XYZ(25000.f, a, b, x, y, z); Color::xyz2srgb(x, y, z, R, G, B); cr->set_source_rgb(R / 65535.f, G / 65535.f, B / 65535.f); @@ -231,10 +231,10 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) // drawing the connection line cr->set_antialias(Cairo::ANTIALIAS_DEFAULT); float loa, hia, lob, hib; - loa = .5f * (width + width * low_a); - hia = .5f * (width + width * high_a); - lob = .5f * (height + height * low_b); - hib = .5f * (height + height * high_b); + loa = .5 * (width + width * low_a); + hia = .5 * (width + width * high_a); + lob = .5 * (height + height * low_b); + hib = .5 * (height + height * high_b); cr->set_line_width(2. * double(s)); cr->set_source_rgb(0.6, 0.6, 0.6); cr->move_to(loa, lob); @@ -319,8 +319,8 @@ bool LabGridArea::on_motion_notify_event(GdkEventMotion *event) int height = get_allocated_height() - 2 * inset * s - padding.get_top() - padding.get_bottom(); const float mouse_x = std::min(double(std::max(event->x - inset * s - padding.get_right(), 0.)), double(width)); const float mouse_y = std::min(double(std::max(get_allocated_height() - 1 - event->y - inset * s - padding.get_bottom(), 0.)), double(height)); - const float ma = (2.0 * mouse_x - width) / (float)width; - const float mb = (2.0 * mouse_y - height) / (float)height; + const float ma = (2.f * mouse_x - width) / width; + const float mb = (2.f * mouse_y - height) / height; if (isDragged) { if (litPoint == LOW) { low_a = ma; diff --git a/rtgui/lockablecolorpicker.cc b/rtgui/lockablecolorpicker.cc index 071847424..0a08bb945 100644 --- a/rtgui/lockablecolorpicker.cc +++ b/rtgui/lockablecolorpicker.cc @@ -37,7 +37,7 @@ void LockableColorPicker::updateBackBuffer () int newW, newH; // -------------------- setting some key constants --------------------- - constexpr float circlePadding = 3.f; // keep this value odd + constexpr double circlePadding = 3.0; // keep this value odd constexpr double opacity = 0.62; // --------------------------------------------------------------------- @@ -121,18 +121,18 @@ void LockableColorPicker::updateBackBuffer () bbcr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); bbcr->set_line_width (0.); - float center = (float)size / 2.f + circlePadding; + double center = static_cast(size) / 2.0 + circlePadding; // black background of the whole color picker bbcr->set_line_width (0.); bbcr->set_source_rgba (0., 0., 0., opacity); - bbcr->arc_negative (center, center, center, 0., (double)rtengine::RT_PI); + bbcr->arc_negative (center, center, center, 0., rtengine::RT_PI); bbcr->line_to (0, 2. * center + textHeight); - bbcr->arc_negative (2. * textPadding, 2. * center + textHeight, 2. * textPadding, (double)rtengine::RT_PI, (double)rtengine::RT_PI / 2.); + bbcr->arc_negative (2. * textPadding, 2. * center + textHeight, 2. * textPadding, rtengine::RT_PI, rtengine::RT_PI / 2.); bbcr->line_to (textWidth, 2. * center + textHeight + 2. * textPadding); - bbcr->arc_negative (textWidth, 2. * center + textHeight, 2. * textPadding, (double)rtengine::RT_PI / 2., 0.); + bbcr->arc_negative (textWidth, 2. * center + textHeight, 2. * textPadding, rtengine::RT_PI / 2., 0.); bbcr->line_to (textWidth + 2. * textPadding, 2. * center + 2. * textPadding); - bbcr->arc_negative (textWidth, 2. * center + 2. * textPadding, 2. * textPadding, 0., (double)rtengine::RT_PI * 1.5); + bbcr->arc_negative (textWidth, 2. * center + 2. * textPadding, 2. * textPadding, 0., rtengine::RT_PI * 1.5); bbcr->line_to (2. * center, 2. * center); bbcr->close_path(); bbcr->set_line_join (Cairo::LINE_JOIN_BEVEL); @@ -222,7 +222,7 @@ void LockableColorPicker::updateBackBuffer () bbcr->set_antialias(Cairo::ANTIALIAS_SUBPIXEL); - float center = (float)size / 2.f + circlePadding; + double center = static_cast(size) / 2. + circlePadding; // light grey circle around the color mark bbcr->arc (center, center, center - circlePadding / 2., 0., 2. * (double)rtengine::RT_PI); diff --git a/rtgui/mycurve.cc b/rtgui/mycurve.cc index 7401570c8..d460713fb 100644 --- a/rtgui/mycurve.cc +++ b/rtgui/mycurve.cc @@ -183,7 +183,7 @@ float MyCurve::getVal(LUTf &curve, int x) if (size_t(graphW) == curve.getSize()) { return curve[x]; } else { - return curve.getVal01(float(x) / graphW); + return curve.getVal01(x / graphW); } } diff --git a/rtgui/mydiagonalcurve.cc b/rtgui/mydiagonalcurve.cc index abd339ce0..ac7976b7e 100644 --- a/rtgui/mydiagonalcurve.cc +++ b/rtgui/mydiagonalcurve.cc @@ -358,14 +358,14 @@ void MyDiagonalCurve::draw (int handle) // draw upper and lower bounds if (curve.type == DCT_Parametric && activeParam > 0 && lpoint.getUpperBound() > 1 && upoint.getUpperBound() > 1) { cr->set_source_rgba (1.0, 1.0, 1.0, 0.1); - cr->move_to (graphX, getVal(upoint, 0) * -graphH + graphY); + cr->move_to (graphX, static_cast(getVal(upoint, 0)) * -graphH + graphY); for (int i = 1; i < graphW - 2; ++i) { - cr->line_to ((double)i + graphX, getVal(upoint, i) * -graphH + graphY); + cr->line_to ((double)i + graphX, static_cast(getVal(upoint, i)) * -graphH + graphY); } for (int i = graphW - 3; i >= 0; --i) { - cr->line_to ((double)i + graphX, getVal(lpoint, i) * -graphH + graphY); + cr->line_to ((double)i + graphX, static_cast(getVal(lpoint, i)) * -graphH + graphY); } cr->fill (); @@ -390,21 +390,21 @@ void MyDiagonalCurve::draw (int handle) if (n > 1) { if (pipetteR > -1.f) { cr->set_source_rgba (1., 0., 0., 0.5); // WARNING: assuming that red values are stored in pipetteR, which might not be the case! - cr->move_to (graphX + graphW*pipetteR, graphY + 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteR), graphY + 1. * s); cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); } if (pipetteG > -1.f) { cr->set_source_rgba (0., 1., 0., 0.5); // WARNING: assuming that green values are stored in pipetteG, which might not be the case! - cr->move_to (graphX + graphW*pipetteG, graphY + 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteG), graphY + 1. * s); cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); } if (pipetteB > -1.f) { cr->set_source_rgba (0., 0., 1., 0.5); // WARNING: assuming that blue values are stored in pipetteB, which might not be the case! - cr->move_to (graphX + graphW*pipetteB, graphY + 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteB), graphY + 1. * s); cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); } @@ -414,7 +414,7 @@ void MyDiagonalCurve::draw (int handle) cr->set_line_width (2. * s); c = style->get_color (state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->move_to (graphX + graphW*pipetteVal, graphY + 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteVal), graphY + 1. * s); cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); cr->set_line_width (1. * s); @@ -460,7 +460,7 @@ void MyDiagonalCurve::draw (int handle) // draw curve cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->move_to (graphX, getVal(point, 0) * -graphH + graphY); + cr->move_to (graphX, static_cast(getVal(point, 0)) * -graphH + graphY); for (int i = 1; i < graphW; ++i) { cr->line_to ((double)i + graphX, (double)getVal(point, i) * -graphH + graphY); diff --git a/rtgui/myflatcurve.cc b/rtgui/myflatcurve.cc index 904b379c2..11d89ebd8 100644 --- a/rtgui/myflatcurve.cc +++ b/rtgui/myflatcurve.cc @@ -248,21 +248,21 @@ void MyFlatCurve::draw () if (n > 1) { if (pipetteR > -1.f) { cr->set_source_rgba (1., 0., 0., 0.5); // WARNING: assuming that red values are stored in pipetteR, which might not be the case! - cr->move_to (graphX + graphW*pipetteR, graphY + 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteR), graphY + 1. * s); cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); } if (pipetteG > -1.f) { cr->set_source_rgba (0., 1., 0., 0.5); // WARNING: assuming that green values are stored in pipetteG, which might not be the case! - cr->move_to (graphX + graphW*pipetteG, graphY + 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteG), graphY + 1. * s); cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); } if (pipetteB > -1.f) { cr->set_source_rgba (0., 0., 1., 0.5); // WARNING: assuming that blue values are stored in pipetteB, which might not be the case! - cr->move_to (graphX + graphW*pipetteB, graphY + 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteB), graphY + 1. * s); cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); } @@ -272,7 +272,7 @@ void MyFlatCurve::draw () cr->set_line_width (2. * s); c = style->get_color (state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->move_to (graphX + graphW*pipetteVal, graphY + 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteVal), graphY + 1. * s); cr->rel_line_to (0, -graphH - 1. * s); cr->stroke (); cr->set_line_width (1. * s); @@ -452,10 +452,10 @@ void MyFlatCurve::draw () // draw curve c = style->get_color(state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->move_to (graphX, getVal(point, 0) * -graphH + graphY); + cr->move_to (graphX, static_cast(getVal(point, 0)) * -graphH + graphY); for (int i = 1; i < graphW; ++i) { - cr->line_to ((double)i + graphX, (double)getVal(point, i) * -graphH + graphY); + cr->line_to ((double)i + graphX, static_cast(getVal(point, i)) * -graphH + graphY); } cr->stroke (); diff --git a/rtgui/options.cc b/rtgui/options.cc index 5798b809b..5a32f604a 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -606,6 +606,15 @@ void Options::setDefaults() rtSettings.cbdlsensi = 1.0;//betwen 0.001 to 1 rtSettings.fftwsigma = true; //choice between sigma^2 or empirical formula + rtSettings.itcwb_thres = 34;//between 10 to 55 + rtSettings.itcwb_sort = false; + rtSettings.itcwb_greenrange = 0;//between 0 to 2 + rtSettings.itcwb_greendeltatemp = 2;//between 0 and 4 + rtSettings.itcwb_forceextra = true; + rtSettings.itcwb_sizereference = 3;//between 1 and 5 + rtSettings.itcwb_delta = 1;//between 0 and 5 + rtSettings.itcwb_stdobserver10 = true; + rtSettings.itcwb_precis = 5;//3 or 5 or 9 // end locallab rtSettings.protectred = 60; @@ -1542,6 +1551,42 @@ void Options::readFromFile(Glib::ustring fname) rtSettings.level123_cbdl = keyFile.get_double("Color Management", "CBDLlevel123"); } + if (keyFile.has_key("Color Management", "Itcwb_thres")) { + rtSettings.itcwb_thres = keyFile.get_integer("Color Management", "Itcwb_thres"); + } + + if (keyFile.has_key("Color Management", "Itcwb_sort")) { + rtSettings.itcwb_sort = keyFile.get_boolean("Color Management", "Itcwb_sort"); + } + + if (keyFile.has_key("Color Management", "Itcwb_forceextra")) { + rtSettings.itcwb_forceextra = keyFile.get_boolean("Color Management", "Itcwb_forceextra"); + } + + if (keyFile.has_key("Color Management", "Itcwb_stdobserver10")) { + rtSettings.itcwb_stdobserver10 = keyFile.get_boolean("Color Management", "Itcwb_stdobserver10"); + } + + if (keyFile.has_key("Color Management", "Itcwb_greenrange")) { + rtSettings.itcwb_greenrange = keyFile.get_integer("Color Management", "Itcwb_greenrange"); + } + + if (keyFile.has_key("Color Management", "Itcwb_greendeltatemp")) { + rtSettings.itcwb_greendeltatemp = keyFile.get_integer("Color Management", "Itcwb_greendeltatemp"); + } + + if (keyFile.has_key("Color Management", "Itcwb_sizereference")) { + rtSettings.itcwb_sizereference = keyFile.get_integer("Color Management", "Itcwb_sizereference"); + } + + if (keyFile.has_key("Color Management", "Itcwb_delta")) { + rtSettings.itcwb_delta = keyFile.get_integer("Color Management", "Itcwb_delta"); + } + + if (keyFile.has_key("Color Management", "Itcwb_precis")) { + rtSettings.itcwb_precis = keyFile.get_integer("Color Management", "Itcwb_precis"); + } + //if (keyFile.has_key ("Color Management", "Colortoningab")) rtSettings.colortoningab = keyFile.get_double("Color Management", "Colortoningab"); //if (keyFile.has_key ("Color Management", "Decaction")) rtSettings.decaction = keyFile.get_double("Color Management", "Decaction"); @@ -2241,6 +2286,16 @@ void Options::saveToFile(Glib::ustring fname) //keyFile.set_boolean ("Color Management", "Ciebadpixgauss", rtSettings.ciebadpixgauss); keyFile.set_double("Color Management", "CBDLlevel0", rtSettings.level0_cbdl); keyFile.set_double("Color Management", "CBDLlevel123", rtSettings.level123_cbdl); + keyFile.set_integer("Color Management", "Itcwb_thres", rtSettings.itcwb_thres); + keyFile.set_boolean("Color Management", "Itcwb_sort", rtSettings.itcwb_sort); + keyFile.set_integer("Color Management", "Itcwb_greenrange", rtSettings.itcwb_greenrange); + keyFile.set_integer("Color Management", "Itcwb_greendeltatemp", rtSettings.itcwb_greendeltatemp); + keyFile.set_boolean("Color Management", "Itcwb_forceextra", rtSettings.itcwb_forceextra); + keyFile.set_integer("Color Management", "Itcwb_sizereference", rtSettings.itcwb_sizereference); + keyFile.set_integer("Color Management", "Itcwb_delta", rtSettings.itcwb_delta); + keyFile.set_boolean("Color Management", "Itcwb_stdobserver10", rtSettings.itcwb_stdobserver10); + keyFile.set_integer("Color Management", "Itcwb_precis", rtSettings.itcwb_precis); + //keyFile.set_double ("Color Management", "Colortoningab", rtSettings.colortoningab); //keyFile.set_double ("Color Management", "Decaction", rtSettings.decaction); keyFile.set_string("Color Management", "ClutsDirectory", clutsDir); @@ -2356,8 +2411,18 @@ void Options::load(bool lightweight) const gchar* path; Glib::ustring dPath; +#ifdef __APPLE__ + // Build Application Support directory path for macOS. + const char* homedir = g_getenv("HOME"); // This returns the current container data dir in ~/Library + std::string homebuf{homedir}; + int homelength = strlen(homebuf.c_str()); + homebuf[homelength-44] = '\0'; // Terminate string after ${HOME}/Library + std::string homeconfig{homebuf}; + std::strcat(&homeconfig[0], "/Application Support/RawTherapee/config"); + path = homeconfig.c_str(); +#else path = g_getenv("RT_SETTINGS"); - +#endif if (path != nullptr) { rtdir = Glib::ustring(path); @@ -2366,6 +2431,7 @@ void Options::load(bool lightweight) throw Error(msg); } } else { + #ifdef WIN32 WCHAR pathW[MAX_PATH] = {0}; @@ -2398,9 +2464,14 @@ void Options::load(bool lightweight) rtdir = Glib::build_filename(argv0, "mysettings"); } - // Modify the path of the cache folder to the one provided in RT_CACHE environment variable + // Modify the path of the cache folder to the one provided in RT_CACHE environment variable. Build the cache folder name in macOS. +#ifdef __APPLE__ + std::string homecache{homebuf}; + std::strcat(&homecache[0], "/Application Support/RawTherapee/cache"); + path = homecache.c_str(); +#else path = g_getenv("RT_CACHE"); - +#endif if (path != nullptr) { cacheBaseDir = Glib::ustring(path); @@ -2409,6 +2480,7 @@ void Options::load(bool lightweight) throw Error(msg); } } + // No environment variable provided, so falling back to the multi user mode, if enabled else if (options.multiUser) { #ifdef WIN32 diff --git a/rtgui/options.h b/rtgui/options.h index b8858f9bd..02d62292c 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -20,7 +20,15 @@ #include #include +#if defined __has_include +#if __has_include() #include +#else +#include +#endif +#else +#include +#endif #include "../rtengine/settings.h" #include diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 8c3434597..ebb2f5081 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -219,6 +219,7 @@ void ParamsEdited::set(bool v) colorappearance.adaplum = v; colorappearance.badpixsl = v; colorappearance.wbmodel = v; + colorappearance.illum = v; colorappearance.algo = v; colorappearance.jlight = v; @@ -243,10 +244,12 @@ void ParamsEdited::set(bool v) colorappearance.curveMode2 = v; colorappearance.curveMode3 = v; colorappearance.tempout = v; + colorappearance.autotempout = v; colorappearance.greenout = v; colorappearance.ybout = v; colorappearance.tempsc = v; colorappearance.greensc = v; + colorappearance.presetcat02 = v; //colorBoost.amount = v; //colorBoost.avoidclip = v; @@ -491,8 +494,19 @@ void ParamsEdited::set(bool v) wavelet.bluemed = v; wavelet.bluelow = v; wavelet.lipst = v; + wavelet.ballum = v; + wavelet.balchrom = v; + wavelet.chromfi = v; + wavelet.chromco = v; + wavelet.mergeL = v; + wavelet.mergeC = v; + wavelet.softrad = v; + wavelet.softradend = v; wavelet.Medgreinf = v; + wavelet.ushamethod = v; wavelet.avoid = v; + wavelet.showmask = v; + wavelet.oldsh = v; wavelet.tmr = v; wavelet.Lmethod = v; wavelet.CLmethod = v; @@ -507,10 +521,17 @@ void ParamsEdited::set(bool v) wavelet.TMmethod = v; wavelet.HSmethod = v; wavelet.Dirmethod = v; - wavelet.rescon = v; + wavelet.sigma = v; + wavelet.sigma = v; + wavelet.offset = v; + wavelet.lowthr = v; wavelet.resconH = v; wavelet.reschro = v; + wavelet.resblur = v; + wavelet.resblurc = v; wavelet.tmrs = v; + wavelet.edgs = v; + wavelet.scale = v; wavelet.gamma = v; wavelet.sup = v; wavelet.sky = v; @@ -526,21 +547,26 @@ void ParamsEdited::set(bool v) wavelet.chro = v; wavelet.contrast = v; wavelet.edgrad = v; + wavelet.edgeffect = v; wavelet.edgval = v; wavelet.edgthresh = v; wavelet.thr = v; wavelet.thrH = v; + wavelet.radius = v; wavelet.skinprotect = v; wavelet.hueskin = v; wavelet.hueskin2 = v; wavelet.hllev = v; wavelet.bllev = v; wavelet.edgcont = v; + wavelet.chrwav = v; + wavelet.bluwav = v; wavelet.level0noise = v; wavelet.level1noise = v; wavelet.level2noise = v; wavelet.level3noise = v; wavelet.ccwcurve = v; + wavelet.blcurve = v; wavelet.opacityCurveRG = v; wavelet.opacityCurveBY = v; wavelet.opacityCurveW = v; @@ -556,9 +582,11 @@ void ParamsEdited::set(bool v) // wavelet.enaedge = v; // wavelet.enares = v; wavelet.expfinal = v; + wavelet.expclari = v; wavelet.expcontrast = v; wavelet.expchroma = v; wavelet.expedge = v; + wavelet.expbl = v; wavelet.expresid = v; wavelet.exptoning = v; wavelet.expnoise = v; @@ -603,6 +631,7 @@ void ParamsEdited::set(bool v) filmNegative.redRatio = v; filmNegative.greenExp = v; filmNegative.blueRatio = v; + filmNegative.baseValues = v; exif = v; iptc = v; @@ -814,6 +843,7 @@ void ParamsEdited::initFrom(const std::vector& colorappearance.adaplum = colorappearance.adaplum && p.colorappearance.adaplum == other.colorappearance.adaplum; colorappearance.badpixsl = colorappearance.badpixsl && p.colorappearance.badpixsl == other.colorappearance.badpixsl; colorappearance.wbmodel = colorappearance.wbmodel && p.colorappearance.wbmodel == other.colorappearance.wbmodel; + colorappearance.illum = colorappearance.illum && p.colorappearance.illum == other.colorappearance.illum; colorappearance.algo = colorappearance.algo && p.colorappearance.algo == other.colorappearance.algo; colorappearance.jlight = colorappearance.jlight && p.colorappearance.jlight == other.colorappearance.jlight; colorappearance.qbright = colorappearance.qbright && p.colorappearance.qbright == other.colorappearance.qbright; @@ -837,10 +867,12 @@ void ParamsEdited::initFrom(const std::vector& colorappearance.curveMode2 = colorappearance.curveMode2 && p.colorappearance.curveMode2 == other.colorappearance.curveMode2; colorappearance.curveMode3 = colorappearance.curveMode3 && p.colorappearance.curveMode3 == other.colorappearance.curveMode3; colorappearance.tempout = colorappearance.tempout && p.colorappearance.tempout == other.colorappearance.tempout; + colorappearance.autotempout = colorappearance.autotempout && p.colorappearance.autotempout == other.colorappearance.autotempout; colorappearance.greenout = colorappearance.greenout && p.colorappearance.greenout == other.colorappearance.greenout; colorappearance.ybout = colorappearance.ybout && p.colorappearance.ybout == other.colorappearance.ybout; colorappearance.tempsc = colorappearance.tempsc && p.colorappearance.tempsc == other.colorappearance.tempsc; colorappearance.greensc = colorappearance.greensc && p.colorappearance.greensc == other.colorappearance.greensc; + colorappearance.presetcat02 = colorappearance.presetcat02 && p.colorappearance.presetcat02 == other.colorappearance.presetcat02; //colorBoost.amount = colorBoost.amount && p.colorBoost.amount == other.colorBoost.amount; //colorBoost.avoidclip = colorBoost.avoidclip && p.colorBoost.avoidclip == other.colorBoost.avoidclip; @@ -1533,8 +1565,19 @@ void ParamsEdited::initFrom(const std::vector& wavelet.greenlow = wavelet.greenlow && p.wavelet.greenlow == other.wavelet.greenlow; wavelet.bluelow = wavelet.bluelow && p.wavelet.bluelow == other.wavelet.bluelow; wavelet.lipst = wavelet.lipst && p.wavelet.lipst == other.wavelet.lipst; - wavelet.Medgreinf = wavelet.Medgreinf && p.wavelet.Medgreinf == other.wavelet.Medgreinf; + wavelet.bluehigh = wavelet.bluehigh && p.wavelet.bluehigh == other.wavelet.bluehigh; + wavelet.ballum = wavelet.ballum && p.wavelet.ballum == other.wavelet.ballum; + wavelet.balchrom = wavelet.balchrom && p.wavelet.balchrom == other.wavelet.balchrom; + wavelet.chromfi = wavelet.chromfi && p.wavelet.chromfi == other.wavelet.chromfi; + wavelet.chromco = wavelet.chromco && p.wavelet.chromco == other.wavelet.chromco; + wavelet.mergeL = wavelet.mergeL && p.wavelet.mergeL == other.wavelet.mergeL; + wavelet.mergeC = wavelet.mergeC && p.wavelet.mergeC == other.wavelet.mergeC; + wavelet.softrad = wavelet.softrad && p.wavelet.softrad == other.wavelet.softrad; + wavelet.softradend = wavelet.softradend && p.wavelet.softradend == other.wavelet.softradend; + wavelet.ushamethod = wavelet.ushamethod && p.wavelet.ushamethod == other.wavelet.ushamethod; wavelet.avoid = wavelet.avoid && p.wavelet.avoid == other.wavelet.avoid; + wavelet.showmask = wavelet.showmask && p.wavelet.showmask == other.wavelet.showmask; + wavelet.oldsh = wavelet.oldsh && p.wavelet.oldsh == other.wavelet.oldsh; wavelet.tmr = wavelet.tmr && p.wavelet.tmr == other.wavelet.tmr; wavelet.Lmethod = wavelet.Lmethod && p.wavelet.Lmethod == other.wavelet.Lmethod; wavelet.CLmethod = wavelet.CLmethod && p.wavelet.CLmethod == other.wavelet.CLmethod; @@ -1549,10 +1592,17 @@ void ParamsEdited::initFrom(const std::vector& wavelet.TMmethod = wavelet.TMmethod && p.wavelet.TMmethod == other.wavelet.TMmethod; wavelet.HSmethod = wavelet.HSmethod && p.wavelet.HSmethod == other.wavelet.HSmethod; wavelet.Dirmethod = wavelet.Dirmethod && p.wavelet.Dirmethod == other.wavelet.Dirmethod; + wavelet.sigma = wavelet.sigma && p.wavelet.sigma == other.wavelet.sigma; + wavelet.offset = wavelet.offset && p.wavelet.offset == other.wavelet.offset; + wavelet.lowthr = wavelet.lowthr && p.wavelet.lowthr == other.wavelet.lowthr; wavelet.rescon = wavelet.rescon && p.wavelet.rescon == other.wavelet.rescon; wavelet.resconH = wavelet.resconH && p.wavelet.resconH == other.wavelet.resconH; wavelet.reschro = wavelet.reschro && p.wavelet.reschro == other.wavelet.reschro; + wavelet.resblur = wavelet.resblur && p.wavelet.resblur == other.wavelet.resblur; + wavelet.resblurc = wavelet.resblurc && p.wavelet.resblurc == other.wavelet.resblurc; wavelet.tmrs = wavelet.tmrs && p.wavelet.tmrs == other.wavelet.tmrs; + wavelet.edgs = wavelet.edgs && p.wavelet.edgs == other.wavelet.edgs; + wavelet.scale = wavelet.scale && p.wavelet.scale == other.wavelet.scale; wavelet.gamma = wavelet.gamma && p.wavelet.gamma == other.wavelet.gamma; wavelet.sup = wavelet.sup && p.wavelet.sup == other.wavelet.sup; wavelet.sky = wavelet.sky && p.wavelet.sky == other.wavelet.sky; @@ -1568,15 +1618,19 @@ void ParamsEdited::initFrom(const std::vector& wavelet.chro = wavelet.chro && p.wavelet.chro == other.wavelet.chro; wavelet.contrast = wavelet.contrast && p.wavelet.contrast == other.wavelet.contrast; wavelet.edgrad = wavelet.edgrad && p.wavelet.edgrad == other.wavelet.edgrad; + wavelet.edgeffect = wavelet.edgeffect && p.wavelet.edgeffect == other.wavelet.edgeffect; wavelet.edgval = wavelet.edgval && p.wavelet.edgval == other.wavelet.edgval; wavelet.edgthresh = wavelet.edgthresh && p.wavelet.edgthresh == other.wavelet.edgthresh; wavelet.thr = wavelet.thr && p.wavelet.thr == other.wavelet.thr; wavelet.thrH = wavelet.thrH && p.wavelet.thrH == other.wavelet.thrH; + wavelet.radius = wavelet.radius && p.wavelet.radius == other.wavelet.radius; wavelet.hueskin = wavelet.hueskin && p.wavelet.hueskin == other.wavelet.hueskin; wavelet.hueskin2 = wavelet.hueskin2 && p.wavelet.hueskin2 == other.wavelet.hueskin2; wavelet.hllev = wavelet.hllev && p.wavelet.hllev == other.wavelet.hllev; wavelet.bllev = wavelet.bllev && p.wavelet.bllev == other.wavelet.bllev; wavelet.edgcont = wavelet.edgcont && p.wavelet.edgcont == other.wavelet.edgcont; + wavelet.chrwav = wavelet.chrwav && p.wavelet.chrwav == other.wavelet.chrwav; + wavelet.bluwav = wavelet.bluwav && p.wavelet.bluwav == other.wavelet.bluwav; wavelet.level0noise = wavelet.level0noise && p.wavelet.level0noise == other.wavelet.level0noise; wavelet.level1noise = wavelet.level1noise && p.wavelet.level1noise == other.wavelet.level1noise; wavelet.level2noise = wavelet.level2noise && p.wavelet.level2noise == other.wavelet.level2noise; @@ -1584,6 +1638,7 @@ void ParamsEdited::initFrom(const std::vector& wavelet.pastlev = wavelet.pastlev && p.wavelet.pastlev == other.wavelet.pastlev; wavelet.satlev = wavelet.satlev && p.wavelet.satlev == other.wavelet.satlev; wavelet.ccwcurve = wavelet.ccwcurve && p.wavelet.ccwcurve == other.wavelet.ccwcurve; + wavelet.blcurve = wavelet.blcurve && p.wavelet.blcurve == other.wavelet.blcurve; wavelet.opacityCurveRG = wavelet.opacityCurveRG && p.wavelet.opacityCurveRG == other.wavelet.opacityCurveRG; wavelet.opacityCurveBY = wavelet.opacityCurveBY && p.wavelet.opacityCurveBY == other.wavelet.opacityCurveBY; wavelet.opacityCurveW = wavelet.opacityCurveW && p.wavelet.opacityCurveW == other.wavelet.opacityCurveW; @@ -1596,10 +1651,12 @@ void ParamsEdited::initFrom(const std::vector& wavelet.expcontrast = wavelet.expcontrast && p.wavelet.expcontrast == other.wavelet.expcontrast; wavelet.expchroma = wavelet.expchroma && p.wavelet.expchroma == other.wavelet.expchroma; wavelet.expedge = wavelet.expedge && p.wavelet.expedge == other.wavelet.expedge; + wavelet.expbl = wavelet.expbl && p.wavelet.expbl == other.wavelet.expbl; wavelet.expresid = wavelet.expresid && p.wavelet.expresid == other.wavelet.expresid; wavelet.expfinal = wavelet.expfinal && p.wavelet.expfinal == other.wavelet.expfinal; wavelet.exptoning = wavelet.exptoning && p.wavelet.exptoning == other.wavelet.exptoning; wavelet.expnoise = wavelet.expnoise && p.wavelet.expnoise == other.wavelet.expnoise; + wavelet.expclari = wavelet.expclari && p.wavelet.expclari == other.wavelet.expclari; for (int level = 0; level < 9; ++level) { wavelet.c[level] = wavelet.c[level] && p.wavelet.c[level] == other.wavelet.c[level]; @@ -1637,6 +1694,9 @@ void ParamsEdited::initFrom(const std::vector& filmNegative.redRatio = filmNegative.redRatio && p.filmNegative.redRatio == other.filmNegative.redRatio; filmNegative.greenExp = filmNegative.greenExp && p.filmNegative.greenExp == other.filmNegative.greenExp; filmNegative.blueRatio = filmNegative.blueRatio && p.filmNegative.blueRatio == other.filmNegative.blueRatio; + filmNegative.baseValues = filmNegative.baseValues && p.filmNegative.redBase == other.filmNegative.redBase + && p.filmNegative.greenBase == other.filmNegative.greenBase + && p.filmNegative.blueBase == other.filmNegative.blueBase; // How the hell can we handle that??? // exif = exif && p.exif==other.exif @@ -2452,6 +2512,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.colorappearance.wbmodel = mods.colorappearance.wbmodel; } + if (colorappearance.illum) { + toEdit.colorappearance.illum = mods.colorappearance.illum; + } + if (colorappearance.algo) { toEdit.colorappearance.algo = mods.colorappearance.algo; } @@ -2460,6 +2524,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.colorappearance.tempout = mods.colorappearance.tempout; } + if (colorappearance.autotempout) { + toEdit.colorappearance.autotempout = mods.colorappearance.autotempout; + } + if (colorappearance.greenout) { toEdit.colorappearance.greenout = mods.colorappearance.greenout; } @@ -2529,6 +2597,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.colorappearance.tonecie = mods.colorappearance.tonecie; } + if (colorappearance.presetcat02) { + toEdit.colorappearance.presetcat02 = mods.colorappearance.presetcat02; + } + // if (colorappearance.sharpcie) toEdit.colorappearance.sharpcie = mods.colorappearance.sharpcie; if (impulseDenoise.enabled) { toEdit.impulseDenoise.enabled = mods.impulseDenoise.enabled; @@ -5025,6 +5097,38 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.bluelow = mods.wavelet.bluelow; } + if (wavelet.ballum) { + toEdit.wavelet.ballum = mods.wavelet.ballum; + } + + if (wavelet.balchrom) { + toEdit.wavelet.balchrom = mods.wavelet.balchrom; + } + + if (wavelet.chromfi) { + toEdit.wavelet.chromfi = mods.wavelet.chromfi; + } + + if (wavelet.chromco) { + toEdit.wavelet.chromco = mods.wavelet.chromco; + } + + if (wavelet.mergeL) { + toEdit.wavelet.mergeL = mods.wavelet.mergeL; + } + + if (wavelet.mergeC) { + toEdit.wavelet.mergeC = mods.wavelet.mergeC; + } + + if (wavelet.softrad) { + toEdit.wavelet.softrad = mods.wavelet.softrad; + } + + if (wavelet.softradend) { + toEdit.wavelet.softradend = mods.wavelet.softradend; + } + if (wavelet.lipst) { toEdit.wavelet.lipst = mods.wavelet.lipst; } @@ -5033,10 +5137,22 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.Medgreinf = mods.wavelet.Medgreinf; } + if (wavelet.ushamethod) { + toEdit.wavelet.ushamethod = mods.wavelet.ushamethod; + } + if (wavelet.avoid) { toEdit.wavelet.avoid = mods.wavelet.avoid; } + if (wavelet.showmask) { + toEdit.wavelet.showmask = mods.wavelet.showmask; + } + + if (wavelet.oldsh) { + toEdit.wavelet.oldsh = mods.wavelet.oldsh; + } + if (wavelet.tmr) { toEdit.wavelet.tmr = mods.wavelet.tmr; } @@ -5109,6 +5225,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.thrH = dontforceSet && options.baBehav[ADDSET_WA_THRRH] ? toEdit.wavelet.thrH + mods.wavelet.thrH : mods.wavelet.thrH; } + if (wavelet.radius) { + toEdit.wavelet.radius = dontforceSet && options.baBehav[ADDSET_WA_RADIUS] ? toEdit.wavelet.radius + mods.wavelet.radius : mods.wavelet.radius; + } + if (wavelet.sup) { toEdit.wavelet.sup = mods.wavelet.sup; } @@ -5125,6 +5245,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.edgcont = mods.wavelet.edgcont; } + if (wavelet.chrwav) { + toEdit.wavelet.chrwav = mods.wavelet.chrwav; + } + + if (wavelet.bluwav) { + toEdit.wavelet.bluwav = mods.wavelet.bluwav; + } + if (wavelet.level0noise) { toEdit.wavelet.level0noise = mods.wavelet.level0noise; } @@ -5153,6 +5281,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.ccwcurve = mods.wavelet.ccwcurve; } + if (wavelet.blcurve) { + toEdit.wavelet.blcurve = mods.wavelet.blcurve; + } + if (wavelet.opacityCurveRG) { toEdit.wavelet.opacityCurveRG = mods.wavelet.opacityCurveRG; } @@ -5194,6 +5326,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.expedge = mods.wavelet.expedge; } + if (wavelet.expbl) { + toEdit.wavelet.expbl = mods.wavelet.expbl; + } + if (wavelet.expresid) { toEdit.wavelet.expresid = mods.wavelet.expresid; } @@ -5202,6 +5338,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.expfinal = mods.wavelet.expfinal; } + if (wavelet.expclari) { + toEdit.wavelet.expclari = mods.wavelet.expclari; + } + if (wavelet.exptoning) { toEdit.wavelet.exptoning = mods.wavelet.exptoning; } @@ -5242,6 +5382,30 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.edgeampli = mods.wavelet.edgeampli; } + if (wavelet.sigma) { + toEdit.wavelet.sigma = mods.wavelet.sigma; + } + + if (wavelet.offset) { + toEdit.wavelet.offset = mods.wavelet.offset; + } + + if (wavelet.lowthr) { + toEdit.wavelet.lowthr = mods.wavelet.lowthr; + } + + if (wavelet.resblur) { + toEdit.wavelet.resblur = mods.wavelet.resblur; + } + + if (wavelet.edgeffect) { + toEdit.wavelet.edgeffect = mods.wavelet.edgeffect; + } + + if (wavelet.resblurc) { + toEdit.wavelet.resblurc = mods.wavelet.resblurc; + } + if (wavelet.resconH) { toEdit.wavelet.resconH = dontforceSet && options.baBehav[ADDSET_WA_RESCONH] ? toEdit.wavelet.resconH + mods.wavelet.resconH : mods.wavelet.resconH; } @@ -5254,6 +5418,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.tmrs = dontforceSet && options.baBehav[ADDSET_WA_TMRS] ? toEdit.wavelet.tmrs + mods.wavelet.tmrs : mods.wavelet.tmrs; } + if (wavelet.edgs) { + toEdit.wavelet.edgs = dontforceSet && options.baBehav[ADDSET_WA_EDGS] ? toEdit.wavelet.edgs + mods.wavelet.edgs : mods.wavelet.edgs; + } + + if (wavelet.scale) { + toEdit.wavelet.scale = dontforceSet && options.baBehav[ADDSET_WA_SCALE] ? toEdit.wavelet.scale + mods.wavelet.scale : mods.wavelet.scale; + } + if (wavelet.gamma) { toEdit.wavelet.gamma = dontforceSet && options.baBehav[ADDSET_WA_GAMMA] ? toEdit.wavelet.gamma + mods.wavelet.gamma : mods.wavelet.gamma; } @@ -5418,6 +5590,12 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.filmNegative.blueRatio = mods.filmNegative.blueRatio; } + if (filmNegative.baseValues) { + toEdit.filmNegative.redBase = mods.filmNegative.redBase; + toEdit.filmNegative.greenBase = mods.filmNegative.greenBase; + toEdit.filmNegative.blueBase = mods.filmNegative.blueBase; + } + // Exif changes are added to the existing ones if (exif) { for (procparams::ExifPairs::const_iterator i = mods.exif.begin(); i != mods.exif.end(); ++i) { @@ -5464,7 +5642,7 @@ bool RetinexParamsEdited::isUnchanged() const bool FilmNegativeParamsEdited::isUnchanged() const { - return enabled && redRatio && greenExp && blueRatio; + return enabled && redRatio && greenExp && blueRatio && baseValues; } LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 98b0cd4a2..cdd2f51ab 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -279,6 +279,7 @@ struct ColorAppearanceParamsEdited { bool ybscen; bool badpixsl; bool wbmodel; + bool illum; bool algo; bool jlight; bool qbright; @@ -294,10 +295,12 @@ struct ColorAppearanceParamsEdited { bool datacie; bool tonecie; bool tempout; + bool autotempout; bool greenout; bool ybout; bool tempsc; bool greensc; + bool presetcat02; }; struct DirPyrDenoiseParamsEdited { @@ -947,7 +950,10 @@ struct WaveletParamsEdited { bool cbenab; bool lipst; bool Medgreinf; + bool ushamethod; bool avoid; + bool showmask; + bool oldsh; bool tmr; bool c[9]; bool ch[9]; @@ -964,10 +970,17 @@ struct WaveletParamsEdited { bool Tilesmethod; bool daubcoeffmethod; bool Dirmethod; + bool sigma; + bool offset; + bool lowthr; bool rescon; bool resconH; bool reschro; + bool resblur; + bool resblurc; bool tmrs; + bool edgs; + bool scale; bool gamma; bool sup; bool sky; @@ -983,21 +996,26 @@ struct WaveletParamsEdited { bool chroma; bool contrast; bool edgrad; + bool edgeffect; bool edgval; bool edgthresh; bool thr; bool thrH; + bool radius; bool skinprotect; bool hueskin; bool hueskin2; bool hllev; bool bllev; bool edgcont; + bool chrwav; + bool bluwav; bool level0noise; bool level1noise; bool level2noise; bool level3noise; bool ccwcurve; + bool blcurve; bool opacityCurveBY; bool opacityCurveRG; bool opacityCurveW; @@ -1013,13 +1031,23 @@ struct WaveletParamsEdited { bool bluemed; bool greenhigh; bool bluehigh; + bool ballum; + bool balchrom; + bool chromfi; + bool chromco; + bool mergeL; + bool mergeC; + bool softrad; + bool softradend; bool expcontrast; bool expchroma; bool expedge; + bool expbl; bool expresid; bool expfinal; bool exptoning; bool expnoise; + bool expclari; }; struct DirPyrEqualizerParamsEdited { @@ -1144,6 +1172,7 @@ struct FilmNegativeParamsEdited { bool redRatio; bool greenExp; bool blueRatio; + bool baseValues; bool isUnchanged() const; }; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index d264b5187..d3f95fa79 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -1177,6 +1177,7 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param filterPE.filmNegative.redRatio = falsePE.filmNegative.redRatio; filterPE.filmNegative.greenExp = falsePE.filmNegative.greenExp; filterPE.filmNegative.blueRatio = falsePE.filmNegative.blueRatio; + filterPE.filmNegative.baseValues = falsePE.filmNegative.baseValues; } if (!captureSharpening->get_active ()) { diff --git a/rtgui/ppversion.h b/rtgui/ppversion.h index 4343cc209..5aef01806 100644 --- a/rtgui/ppversion.h +++ b/rtgui/ppversion.h @@ -1,13 +1,15 @@ #pragma once // This number has to be incremented whenever the PP3 file format is modified or the behaviour of a tool changes -#define PPVERSION 347 +#define PPVERSION 348 #define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified /* Log of version changes - 347 2018-09-25 + 348 2018-09-25 Added Locallab tool parameters + 347 2019-11-17 + added special values in filmNegative for backwards compatibility with previous channel scaling method 346 2019-01-01 changed microcontrast uniformity 345 2018-10-21 diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 9fbb8c7ad..c283fb824 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -389,8 +389,11 @@ Gtk::Widget* Preferences::getBatchProcPanel() appendBehavList(mi, M("TP_WAVELET_THR"), ADDSET_WA_THRR, true); appendBehavList(mi, M("TP_WAVELET_RESCONH"), ADDSET_WA_RESCONH, true); appendBehavList(mi, M("TP_WAVELET_THRH"), ADDSET_WA_THRRH, true); + appendBehavList (mi, M ("TP_WAVELET_RADIUS"), ADDSET_WA_RADIUS, true); appendBehavList(mi, M("TP_WAVELET_RESCHRO"), ADDSET_WA_RESCHRO, true); appendBehavList(mi, M("TP_WAVELET_TMSTRENGTH"), ADDSET_WA_TMRS, true); + appendBehavList (mi, M ("TP_WAVELET_TMEDGS"), ADDSET_WA_EDGS, true); + appendBehavList (mi, M ("TP_WAVELET_TMSCALE"), ADDSET_WA_SCALE, true); appendBehavList(mi, M("TP_WAVELET_SKY"), ADDSET_WA_SKYPROTECT, true); appendBehavList(mi, M("TP_WAVELET_CONTRA"), ADDSET_WA_CONTRAST, true); appendBehavList(mi, M("TP_WAVELET_STRENGTH"), ADDSET_WA_STRENGTH, true); @@ -779,7 +782,7 @@ Gtk::Widget* Preferences::getColorManPanel () const std::vector profiles = rtengine::ICCStore::getInstance()->getProfiles(rtengine::ICCStore::ProfileType::MONITOR); - for (const auto profile : profiles) { + for (const auto& profile : profiles) { if (profile.find("file:") != 0) { std::string fileis_RTv4 = profile.substr(0, 4); @@ -848,7 +851,7 @@ Gtk::Widget* Preferences::getColorManPanel () const std::vector prtprofiles = rtengine::ICCStore::getInstance()->getProfiles(rtengine::ICCStore::ProfileType::PRINTER); - for (const auto prtprofile : prtprofiles) { + for (const auto& prtprofile : prtprofiles) { prtProfile->append(prtprofile); } diff --git a/rtgui/profilestorecombobox.cc b/rtgui/profilestorecombobox.cc index bb294189f..a6085e7a9 100644 --- a/rtgui/profilestorecombobox.cc +++ b/rtgui/profilestorecombobox.cc @@ -182,7 +182,7 @@ Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry (const ProfileStoreEntry *p Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath_ (Gtk::TreeModel::Children childs, int parentFolderId, const Glib::ustring &name) const { - for (const auto iter : childs) { + for (const auto& iter : childs) { const Gtk::TreeModel::Row row = *iter; // Hombre: is there a smarter way of knowing if this row has childs? const ProfileStoreEntry *pse = row[methodColumns.profileStoreEntry]; @@ -309,7 +309,7 @@ Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel (const Glib::ustring &name) const Gtk::TreeModel::Children childs = refTreeModel->children(); if (!name.empty()) { - for (const auto iter : childs) { + for (const auto& iter : childs) { const Gtk::TreeModel::Row currRow = *iter; const ProfileStoreEntry *pse = currRow[methodColumns.profileStoreEntry]; diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index c78be375f..2fdd8f319 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -278,7 +278,7 @@ Retinex::Retinex () : FoldableToolPanel (this, "retinex", M ("TP_RETINEX_LABEL") for (int i = 0; i < 7; i++) { float R, G, B; - float x = float (i) * (1.0f / 6.0); + float x = i / 6.0; Color::hsv2rgb01 (x, 0.5f, 0.5f, R, G, B); milestones.push_back ( GradientMilestone (double (x), double (R), double (G), double (B)) ); } @@ -659,10 +659,16 @@ void Retinex::writeOptions (std::vector &tpOpen) tpOpen.push_back (expsettings->get_expanded ()); } -void Retinex::updateToolState (std::vector &tpOpen) +void Retinex::updateToolState(const std::vector& tpOpen) { + if (tpOpen.empty()) { + expsettings->set_expanded(false); + + return; + } + if (tpOpen.size() >= 10) { - expsettings->set_expanded (tpOpen.at (9)); + expsettings->set_expanded(tpOpen[9]); } } diff --git a/rtgui/retinex.h b/rtgui/retinex.h index ff524f854..dea65daab 100644 --- a/rtgui/retinex.h +++ b/rtgui/retinex.h @@ -104,32 +104,32 @@ protected: sigc::connection medianmapConn; public: - Retinex (); - ~Retinex () override; + Retinex(); + ~Retinex() override; - void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; - void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; - void setBatchMode (bool batchMode) override; - void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; - void trimValues (rtengine::procparams::ProcParams* pp) override; - void adjusterChanged (Adjuster* a, double newval) override; - void autoOpenCurve () override; - void medianmapChanged (); - void minmaxChanged (double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax) override; - void updateLabel (); - void updateTrans (); - void neutral_pressed (); + void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; + void write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; + void setBatchMode(bool batchMode) override; + void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; + void trimValues(rtengine::procparams::ProcParams* pp) override; + void adjusterChanged(Adjuster* a, double newval) override; + void autoOpenCurve() override; + void medianmapChanged(); + void minmaxChanged(double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax) override; + void updateLabel(); + void updateTrans(); + void neutral_pressed(); - void enabledChanged () override; - void curveChanged (CurveEditor* ce) override; + void enabledChanged() override; + void curveChanged(CurveEditor* ce) override; void retinexMethodChanged(); void mapMethodChanged(); void viewMethodChanged(); void retinexColorSpaceChanged(); void gammaretinexChanged(); void ColorSpaceUpdateUI(); - void writeOptions (std::vector &tpOpen); - void updateToolState (std::vector &tpOpen); + void writeOptions(std::vector &tpOpen); + void updateToolState(const std::vector& tpOpen); void setAdjusterBehavior (bool strAdd, bool neighAdd, bool limdAdd, bool offsAdd, bool vartAdd, bool gamAdd, bool slopeAdd); void updateCurveBackgroundHistogram( const LUTu& histToneCurve, @@ -144,9 +144,8 @@ public: const LUTu& histLRETI ); - void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) override; + void colorForValue(double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) override; private: - void foldAllButMe (GdkEventButton* event, MyExpander *expander); - + void foldAllButMe(GdkEventButton* event, MyExpander *expander); }; diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index a48a95fd2..78202326a 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -68,7 +68,7 @@ double RTScalable::getDPI () double RTScalable::getTweakedDPI () { - return dpi * fontScale; + return dpi * static_cast(fontScale); } int RTScalable::getScale () diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index b63ad9297..a543c383c 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -99,6 +99,8 @@ RTWindow::RTWindow () , bpanel (nullptr) , splash (nullptr) , btn_fullscreen (nullptr) + , iFullscreen (nullptr) + , iFullscreen_exit (nullptr) , epanel (nullptr) , fpanel (nullptr) { @@ -179,7 +181,7 @@ RTWindow::RTWindow () fontScale = options.fontSize / (float)RTScalable::baseFontSize; } if (rtengine::settings->verbose) { - printf("\"Non-Default\" font size(%d) * scale(%d) / fontScale(%.3f)\n", options.fontSize, (int)initialGdkScale, fontScale); + printf("\"Non-Default\" font size(%d) * scale(%d) / fontScale(%.3f)\n", options.fontSize, (int)initialGdkScale, static_cast(fontScale)); } } else { Glib::RefPtr style = Gtk::StyleContext::create(); @@ -209,7 +211,7 @@ RTWindow::RTWindow () if ((int)initialGdkScale > 1 || pt != RTScalable::baseFontSize) { css = Glib::ustring::compose ("* { font-size: %1pt}", pt * (int)initialGdkScale); if (rtengine::settings->verbose) { - printf("\"Default\" font size(%d) * scale(%d) / fontScale(%.3f)\n", pt, (int)initialGdkScale, fontScale); + printf("\"Default\" font size(%d) * scale(%d) / fontScale(%.3f)\n", pt, (int)initialGdkScale, static_cast(fontScale)); } } } diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index bf043cf82..c5ae27c95 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -217,7 +217,7 @@ const ProcParams& Thumbnail::getProcParamsU () double ct; getCamWB (ct, pparams->wb.green); pparams->wb.temperature = ct; - } else if (pparams->wb.method == "Auto") { + } else if (pparams->wb.method == "autold") { double ct; getAutoWB (ct, pparams->wb.green, pparams->wb.equal, pparams->wb.tempBias); pparams->wb.temperature = ct; @@ -889,11 +889,6 @@ void Thumbnail::_loadThumbnail(bool firstTrial) } if ( cfs.thumbImgType == CacheImageData::FULL_THUMBNAIL ) { - if(!tpp->isAeValid()) { - // load aehistogram - tpp->readAEHistogram (getCacheFileName ("aehistograms", "")); - } - // load embedded profile tpp->readEmbProfile (getCacheFileName ("embprofiles", ".icc")); @@ -939,10 +934,6 @@ void Thumbnail::_saveThumbnail () // save thumbnail image tpp->writeImage (getCacheFileName ("images", "")); - if(!tpp->isAeValid()) { - // save aehistogram - tpp->writeAEHistogram (getCacheFileName ("aehistograms", "")); - } // save embedded profile tpp->writeEmbProfile (getCacheFileName ("embprofiles", ".icc")); diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 628ad70ef..b6d9325a0 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -719,6 +719,7 @@ void ToolPanelCoordinator::initImage(rtengine::StagedImageProcessor* ipc_, bool ipc->setSizeListener(resize); ipc->setLocallabListener(locallab); ipc->setImageTypeListener(this); + ipc->setFilmNegListener (filmNegative); flatfield->setShortcutPath(Glib::path_get_dirname(ipc->getInitialImage()->getFileName())); icm->setRawMeta(raw, (const rtengine::FramesData*)pMetaData); @@ -742,36 +743,48 @@ void ToolPanelCoordinator::closeImage() void ToolPanelCoordinator::closeAllTools() { - - for (size_t i = 0; i < options.tpOpen.size(); i++) + for (size_t i = 0; i < options.tpOpen.size(); ++i) { if (i < expList.size()) { - expList.at(i)->set_expanded(false); + expList[i]->set_expanded(false); } + } } void ToolPanelCoordinator::openAllTools() { - - for (size_t i = 0; i < options.tpOpen.size(); i++) + for (size_t i = 0; i < options.tpOpen.size(); ++i) { if (i < expList.size()) { - expList.at(i)->set_expanded(true); + expList[i]->set_expanded(true); } + } } void ToolPanelCoordinator::updateToolState() { - - for (size_t i = 0; i < options.tpOpen.size(); i++) - if (i < expList.size()) { - expList.at(i)->set_expanded(options.tpOpen.at(i)); + if (options.tpOpen.empty()) { + for (auto expander : expList) { + expander->set_expanded(false); } + wavelet->updateToolState({}); + retinex->updateToolState({}); + + return; + } + + for (size_t i = 0; i < options.tpOpen.size(); ++i) { + if (i < expList.size()) { + expList[i]->set_expanded(options.tpOpen[i]); + } + } + if (options.tpOpen.size() > expList.size()) { - size_t sizeWavelet = options.tpOpen.size() - expList.size(); + const size_t sizeWavelet = options.tpOpen.size() - expList.size(); + std::vector temp; - for (size_t i = 0; i < sizeWavelet; i++) { - temp.push_back(options.tpOpen.at(i + expList.size())); + for (size_t i = 0; i < sizeWavelet; ++i) { + temp.push_back(options.tpOpen[i + expList.size()]); } wavelet->updateToolState(temp); @@ -1189,3 +1202,8 @@ bool ToolPanelCoordinator::getFilmNegativeExponents(rtengine::Coord spotA, rteng { return ipc && ipc->getFilmNegativeExponents(spotA.x, spotA.y, spotB.x, spotB.y, newExps); } + +bool ToolPanelCoordinator::getRawSpotValues(rtengine::Coord spot, int spotSize, std::array& rawValues) +{ + return ipc && ipc->getRawSpotValues(spot.x, spot.y, spotSize, rawValues); +} \ No newline at end of file diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 93c4faee9..741883454 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -306,6 +306,7 @@ public: // FilmNegProvider interface bool getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, std::array& newExps) override; + bool getRawSpotValues(rtengine::Coord spot, int spotSize, std::array& rawValues) override; // rotatelistener interface void straightenRequested () override; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 3981457e6..af159d480 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . * - * 2014 Jacques Desmis + * 2014 - 2019Jacques Desmis */ #include "wavelet.h" @@ -26,6 +26,7 @@ #include "guiutils.h" #include "rtimage.h" #include "options.h" +#include "eventmapper.h" #include "../rtengine/color.h" using namespace rtengine; @@ -34,27 +35,27 @@ using namespace rtengine::procparams; namespace { - GradientMilestone makeHsvGm(double position, float h, float s, float v) - { - float r; - float g; - float b; - Color::hsv2rgb01(h, s, v, r, g, b); - return GradientMilestone(position, r, g, b); +GradientMilestone makeHsvGm(double position, float h, float s, float v) +{ + float r; + float g; + float b; + Color::hsv2rgb01(h, s, v, r, g, b); + return GradientMilestone(position, r, g, b); +} + +std::vector makeWholeHueRange() +{ + std::vector res; + res.reserve(7); + + for (int i = 0; i < 7; ++i) { + const float x = static_cast(i) / 6.0f; + res.push_back(makeHsvGm(x, x, 0.5f, 0.5f)); } - std::vector makeWholeHueRange() - { - std::vector res; - res.reserve(7); - - for (int i = 0; i < 7; ++i) { - const float x = static_cast(i) / 6.0f; - res.push_back(makeHsvGm(x, x, 0.5f, 0.5f)); - } - - return res; - } + return res; +} } @@ -62,6 +63,7 @@ Wavelet::Wavelet() : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), true, true), curveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CONTEDIT"))), CCWcurveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CCURVE"))), + curveEditorbl(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_BLCURVE"))), curveEditorRES(new CurveEditorGroup(options.lastWaveletCurvesDir)), curveEditorGAM(new CurveEditorGroup(options.lastWaveletCurvesDir)), separatorNeutral(Gtk::manage(new Gtk::HSeparator())), @@ -77,11 +79,21 @@ Wavelet::Wavelet() : lipst(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_LIPST")))), avoid(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_AVOID")))), tmr(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_BALCHRO")))), + showmask(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_SHOWMASK")))), + oldsh(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_OLDSH")))), neutralchButton(Gtk::manage(new Gtk::Button(M("TP_WAVELET_NEUTRAL")))), + sigma(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMA"), 0.05, 2.5, 0.01, 1.))), + offset(Gtk::manage(new Adjuster(M("TP_WAVELET_WAVOFFSET"), 0.33, 1.66, 0.01, 1., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), + lowthr(Gtk::manage(new Adjuster(M("TP_WAVELET_WAVLOWTHR"), 20., 100., 0.5, 40.))), rescon(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCON"), -100, 100, 1, 0))), resconH(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCONH"), -100, 100, 1, 0))), reschro(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCHRO"), -100, 100, 1, 0))), + resblur(Gtk::manage(new Adjuster(M("TP_WAVELET_RESBLUR"), 0, 100, 1, 0))), + resblurc(Gtk::manage(new Adjuster(M("TP_WAVELET_RESBLURC"), 0, 100, 1, 0))), + bluwav(Gtk::manage(new Adjuster(M("TP_WAVELET_BLUWAV"), 0.05, 2.5, 0.5, 1.))), tmrs(Gtk::manage(new Adjuster(M("TP_WAVELET_TMSTRENGTH"), -1.0, 2.0, 0.01, 0.0))), + edgs(Gtk::manage(new Adjuster(M("TP_WAVELET_TMEDGS"), 0.1, 4.0, 0.01, 1.4))), + scale(Gtk::manage(new Adjuster(M("TP_WAVELET_TMSCALE"), 0.1, 10.0, 0.01, 1.0))), gamma(Gtk::manage(new Adjuster(M("TP_WAVELET_COMPGAMMA"), 0.4, 2.0, 0.01, 1.0))), sup(Gtk::manage(new Adjuster(M("TP_WAVELET_SUPE"), -100, 350, 1, 0))), sky(Gtk::manage(new Adjuster(M("TP_WAVELET_SKY"), -100., 100.0, 1., 0.))), @@ -89,12 +101,14 @@ Wavelet::Wavelet() : chroma(Gtk::manage(new Adjuster(M("TP_WAVELET_CHRO"), 1, 9, 1, 5))), chro(Gtk::manage(new Adjuster(M("TP_WAVELET_CHR"), 0., 100., 1., 0.))), contrast(Gtk::manage(new Adjuster(M("TP_WAVELET_CONTRA"), -100, 100, 1, 0))), - thr(Gtk::manage(new Adjuster(M("TP_WAVELET_THR"), 0, 100, 1, 35))), - thrH(Gtk::manage(new Adjuster(M("TP_WAVELET_THRH"), 0, 100, 1, 65))), - skinprotect(Gtk::manage( new Adjuster(M("TP_WAVELET_SKIN"), -100, 100, 1, 0.) )), - edgrad(Gtk::manage( new Adjuster(M("TP_WAVELET_EDRAD"), 0, 100, 1, 15) )), - edgval(Gtk::manage( new Adjuster(M("TP_WAVELET_EDVAL"), 0, 100, 1, 0) )), - edgthresh(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGTHRESH"), -50, 100, 1, 10 ))), + thr(Gtk::manage(new Adjuster(M("TP_WAVELET_THR"), 0, 100, 1, 30))), + thrH(Gtk::manage(new Adjuster(M("TP_WAVELET_THRH"), 0, 100, 1, 70))), + radius(Gtk::manage(new Adjuster(M("TP_WAVELET_RADIUS"), 0, 100, 1, 40))), + skinprotect(Gtk::manage(new Adjuster(M("TP_WAVELET_SKIN"), -100, 100, 1, 0.))), + edgrad(Gtk::manage(new Adjuster(M("TP_WAVELET_EDRAD"), 0, 100, 1, 15))), + edgeffect(Gtk::manage(new Adjuster(M("TP_WAVELET_EDEFFECT"), 0.05, 2.5, 0.01, 1.))), + edgval(Gtk::manage(new Adjuster(M("TP_WAVELET_EDVAL"), 0, 100, 1, 0))), + edgthresh(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGTHRESH"), -50, 100, 1, 10))), strength(Gtk::manage(new Adjuster(M("TP_WAVELET_STRENGTH"), 0, 100, 1, 100))), balance(Gtk::manage(new Adjuster(M("TP_WAVELET_BALANCE"), -30, 100, 1, 0))), iter(Gtk::manage(new Adjuster(M("TP_WAVELET_ITER"), -3, 3, 1, 0))), @@ -116,6 +130,15 @@ Wavelet::Wavelet() : edgedetectthr2(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEDETECTTHR2"), -10, 100, 1, 0))), edgesensi(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGESENSI"), 0, 100, 1, 60))), edgeampli(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEAMPLI"), 0, 100, 1, 10))), + ballum(Gtk::manage(new Adjuster(M("TP_WAVELET_BALLUM"), -2., 10., 0.5, 7., Gtk::manage(new RTImage("circle-white-small.png")), Gtk::manage(new RTImage("circle-black-small.png"))))), + balchrom(Gtk::manage(new Adjuster(M("TP_WAVELET_BALCHROM"), -100., 100., 1., 0., Gtk::manage(new RTImage("circle-blue-small.png")), Gtk::manage(new RTImage("circle-red-small.png"))))), + chromfi(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMFI"), 0.0, 150., 0.01, 0.))), + chromco(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMCO"), 0, 100., 0.01, 0.))), + mergeL(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEL"), -50, 100, 1, 40))), + mergeC(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEC"), -50, 100, 1, 20))), + softrad(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 100., 0.5, 0.))), + softradend(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 100., 0.5, 0.))), + chrwav(Gtk::manage(new Adjuster(M("TP_WAVELET_CHRWAV"), 0., 100., 0.5, 0.))), Lmethod(Gtk::manage(new MyComboBoxText())), CHmethod(Gtk::manage(new MyComboBoxText())), CHSLmethod(Gtk::manage(new MyComboBoxText())), @@ -130,12 +153,19 @@ Wavelet::Wavelet() : daubcoeffmethod(Gtk::manage(new MyComboBoxText())), Dirmethod(Gtk::manage(new MyComboBoxText())), Medgreinf(Gtk::manage(new MyComboBoxText())), + ushamethod(Gtk::manage(new MyComboBoxText())), chanMixerHLFrame(Gtk::manage(new Gtk::Frame(M("TP_COLORTONING_HIGHLIGHT")))), chanMixerMidFrame(Gtk::manage(new Gtk::Frame(M("TP_COLORTONING_MIDTONES")))), chanMixerShadowsFrame(Gtk::manage(new Gtk::Frame(M("TP_COLORTONING_SHADOWS")))), + shFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_SHFRAME")))), + contFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CONTFRAME")))), + blurFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_BLURFRAME")))), + chromaFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CHROMAFRAME")))), + chroFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CHROFRAME")))), wavLabels(Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER))), labmC(Gtk::manage(new Gtk::Label(M("TP_WAVELET_CTYPE") + ":"))), labmNP(Gtk::manage(new Gtk::Label(M("TP_WAVELET_NPTYPE") + ":"))), + usharpLabel(Gtk::manage(new Gtk::Label(M("TP_WAVELET_USHARP") + ":"))), expchroma(Gtk::manage(new MyExpander(true, M("TP_WAVELET_LEVCH")))), expcontrast(Gtk::manage(new MyExpander(true, M("TP_WAVELET_LEVF")))), expedge(Gtk::manage(new MyExpander(true, M("TP_WAVELET_EDGE")))), @@ -145,106 +175,139 @@ Wavelet::Wavelet() : expresid(Gtk::manage(new MyExpander(true, M("TP_WAVELET_RESID")))), expsettings(Gtk::manage(new MyExpander(false, M("TP_WAVELET_SETTINGS")))), exptoning(Gtk::manage(new MyExpander(true, M("TP_WAVELET_TON")))), - neutrHBox(Gtk::manage(new Gtk::HBox())) + expclari(Gtk::manage(new MyExpander(true, M("TP_WAVELET_CLARI")))), + expbl(Gtk::manage(new MyExpander(true, M("TP_WAVELET_BL")))), + neutrHBox(Gtk::manage(new Gtk::HBox())), + usharpHBox(Gtk::manage(new Gtk::HBox())) { CurveListener::setMulti(true); + auto m = ProcEventMapper::getInstance(); + EvWavenaclari = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVCLARI"); + EvWavushamet = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVUSHAMET"); + EvWavballum = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVBALLUM"); + EvWavbalchrom = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVBALCHROM"); + EvWavchromfi = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVCHROMFI"); + EvWavchromco = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVCHROMCO"); + EvWavmergeL = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVMERGEL"); + EvWavmergeC = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVMERGEC"); + EvWavsoftrad = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSOFTRAD"); + EvWavsoftradend = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSOFTRADEND"); + EvWavshowmask = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSHOWMASK"); + EvWavedgs = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVEDGS"); + EvWavscale = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSCALE"); + EvWavradius = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVRADIUS"); + EvWavsigma = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSIGMA"); + EvWavenabl = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVBL"); + EvWavchrwav = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_chrwav"); + EvWavoldsh = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVOLDSH"); + EvWavoffset = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVOFFSET"); + EvWavlowthr = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVLOWTHR"); + EvWavbluwav = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLUWAV"); + EvWavblshape = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLSHAPE"); + EvWavresblur = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLURWAV"); + EvWavresblurc = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLURCWAV"); + EvWavedgeffect = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_EDGEFFECT"); + expsettings->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings)); - expsettings->signal_button_release_event().connect_notify( sigc::bind( sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings) ); + expcontrast->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expcontrast)); + enableContrastConn = expcontrast->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Wavelet::enableToggled), expcontrast)); - expcontrast->signal_button_release_event().connect_notify( sigc::bind( sigc::mem_fun(this, &Wavelet::foldAllButMe), expcontrast) ); - enableContrastConn = expcontrast->signal_enabled_toggled().connect ( sigc::bind( sigc::mem_fun(this, &Wavelet::enableToggled), expcontrast) ); + expchroma->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expchroma)); + enableChromaConn = expchroma->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Wavelet::enableToggled), expchroma)); - expchroma->signal_button_release_event().connect_notify( sigc::bind ( sigc::mem_fun(this, &Wavelet::foldAllButMe), expchroma) ); - enableChromaConn = expchroma->signal_enabled_toggled().connect ( sigc::bind( sigc::mem_fun(this, &Wavelet::enableToggled), expchroma) ); + exptoning->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), exptoning)); + enableToningConn = exptoning->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Wavelet::enableToggled), exptoning)); - exptoning->signal_button_release_event().connect_notify( sigc::bind ( sigc::mem_fun(this, &Wavelet::foldAllButMe), exptoning) ); - enableToningConn = exptoning->signal_enabled_toggled().connect ( sigc::bind( sigc::mem_fun(this, &Wavelet::enableToggled), exptoning) ); + expnoise->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expnoise)); + enableNoiseConn = expnoise->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Wavelet::enableToggled), expnoise)); - expnoise->signal_button_release_event().connect_notify( sigc::bind ( sigc::mem_fun(this, &Wavelet::foldAllButMe), expnoise) ); - enableNoiseConn = expnoise->signal_enabled_toggled().connect ( sigc::bind( sigc::mem_fun(this, &Wavelet::enableToggled), expnoise) ); + expedge->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expedge)); + enableEdgeConn = expedge->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Wavelet::enableToggled), expedge)); - expedge->signal_button_release_event().connect_notify( sigc::bind ( sigc::mem_fun(this, &Wavelet::foldAllButMe), expedge) ); - enableEdgeConn = expedge->signal_enabled_toggled().connect ( sigc::bind( sigc::mem_fun(this, &Wavelet::enableToggled), expedge) ); + expbl->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expbl)); + enabletmConn = expbl->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Wavelet::enableToggled), expbl)); - expgamut->signal_button_release_event().connect_notify( sigc::bind ( sigc::mem_fun(this, &Wavelet::foldAllButMe), expgamut) ); + expgamut->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expgamut)); - expresid->signal_button_release_event().connect_notify( sigc::bind ( sigc::mem_fun(this, &Wavelet::foldAllButMe), expresid) ); - enableResidConn = expresid->signal_enabled_toggled().connect ( sigc::bind( sigc::mem_fun(this, &Wavelet::enableToggled), expresid) ); + expresid->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expresid)); + enableResidConn = expresid->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Wavelet::enableToggled), expresid)); - expfinal->signal_button_release_event().connect_notify( sigc::bind ( sigc::mem_fun(this, &Wavelet::foldAllButMe), expfinal) ); - enableFinalConn = expfinal->signal_enabled_toggled().connect ( sigc::bind( sigc::mem_fun(this, &Wavelet::enableToggled), expfinal) ); + expfinal->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expfinal)); + enableFinalConn = expfinal->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Wavelet::enableToggled), expfinal)); + + expclari->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expclari)); + enableclariConn = expclari->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Wavelet::enableToggled), expclari)); // Wavelet Settings - ToolParamBlock* const settingsBox = Gtk::manage (new ToolParamBlock()); + ToolParamBlock* const settingsBox = Gtk::manage(new ToolParamBlock()); - strength->setAdjusterListener (this); + strength->setAdjusterListener(this); - thres->set_tooltip_text (M("TP_WAVELET_LEVELS_TOOLTIP")); - thres->setAdjusterListener (this); + thres->set_tooltip_text(M("TP_WAVELET_LEVELS_TOOLTIP")); + thres->setAdjusterListener(this); - Tilesmethod->append (M("TP_WAVELET_TILESFULL")); - Tilesmethod->append (M("TP_WAVELET_TILESBIG")); - Tilesmethod->append (M("TP_WAVELET_TILESLIT")); - Tilesmethodconn = Tilesmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::TilesmethodChanged) ); - Tilesmethod->set_tooltip_text (M("TP_WAVELET_TILES_TOOLTIP")); + Tilesmethod->append(M("TP_WAVELET_TILESFULL")); + Tilesmethod->append(M("TP_WAVELET_TILESBIG")); +// Tilesmethod->append(M("TP_WAVELET_TILESLIT")); + Tilesmethodconn = Tilesmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::TilesmethodChanged)); + Tilesmethod->set_tooltip_text(M("TP_WAVELET_TILES_TOOLTIP")); Gtk::HBox* const tilesizeHBox = Gtk::manage(new Gtk::HBox()); Gtk::Label* const tilesizeLabel = Gtk::manage(new Gtk::Label(M("TP_WAVELET_TILESIZE") + ":")); tilesizeHBox->pack_start(*tilesizeLabel, Gtk::PACK_SHRINK, 4); tilesizeHBox->pack_start(*Tilesmethod); daubcoeffmethod->set_sensitive(true); - daubcoeffmethod->append (M("TP_WAVELET_DAUB2")); - daubcoeffmethod->append (M("TP_WAVELET_DAUB4")); - daubcoeffmethod->append (M("TP_WAVELET_DAUB6")); - daubcoeffmethod->append (M("TP_WAVELET_DAUB10")); - daubcoeffmethod->append (M("TP_WAVELET_DAUB14")); - daubcoeffmethodconn = daubcoeffmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::daubcoeffmethodChanged) ); - daubcoeffmethod->set_tooltip_text (M("TP_WAVELET_DAUB_TOOLTIP")); + daubcoeffmethod->append(M("TP_WAVELET_DAUB2")); + daubcoeffmethod->append(M("TP_WAVELET_DAUB4")); + daubcoeffmethod->append(M("TP_WAVELET_DAUB6")); + daubcoeffmethod->append(M("TP_WAVELET_DAUB10")); + daubcoeffmethod->append(M("TP_WAVELET_DAUB14")); + daubcoeffmethodconn = daubcoeffmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::daubcoeffmethodChanged)); + daubcoeffmethod->set_tooltip_text(M("TP_WAVELET_DAUB_TOOLTIP")); Gtk::Label* const daubcoeffLabel = Gtk::manage(new Gtk::Label(M("TP_WAVELET_DAUB") + ":")); Gtk::HBox* const daubcoeffHBox = Gtk::manage(new Gtk::HBox()); daubcoeffHBox->pack_start(*daubcoeffLabel, Gtk::PACK_SHRINK, 4); daubcoeffHBox->pack_start(*daubcoeffmethod); - Backmethod->append (M("TP_WAVELET_B0")); - Backmethod->append (M("TP_WAVELET_B1")); - Backmethod->append (M("TP_WAVELET_B2")); - Backmethodconn = Backmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::BackmethodChanged) ); + Backmethod->append(M("TP_WAVELET_B0")); + Backmethod->append(M("TP_WAVELET_B1")); + Backmethod->append(M("TP_WAVELET_B2")); + Backmethodconn = Backmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::BackmethodChanged)); Gtk::HBox* const backgroundHBox = Gtk::manage(new Gtk::HBox()); Gtk::Label* const backgroundLabel = Gtk::manage(new Gtk::Label(M("TP_WAVELET_BACKGROUND") + ":")); backgroundHBox->pack_start(*backgroundLabel, Gtk::PACK_SHRINK, 4); backgroundHBox->pack_start(*Backmethod); - CLmethod->append (M("TP_WAVELET_LEVDIR_ONE")); - CLmethod->append (M("TP_WAVELET_LEVDIR_INF")); - CLmethod->append (M("TP_WAVELET_LEVDIR_SUP")); - CLmethod->append (M("TP_WAVELET_LEVDIR_ALL")); - CLmethodconn = CLmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::CLmethodChanged) ); + CLmethod->append(M("TP_WAVELET_LEVDIR_ONE")); + CLmethod->append(M("TP_WAVELET_LEVDIR_INF")); + CLmethod->append(M("TP_WAVELET_LEVDIR_SUP")); + CLmethod->append(M("TP_WAVELET_LEVDIR_ALL")); + CLmethodconn = CLmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::CLmethodChanged)); Gtk::HBox* const levdirMainHBox = Gtk::manage(new Gtk::HBox()); Gtk::Label* const levdirMainLabel = Gtk::manage(new Gtk::Label(M("TP_WAVELET_PROC") + ":")); levdirMainHBox->pack_start(*levdirMainLabel, Gtk::PACK_SHRINK, 4); levdirMainHBox->pack_start(*CLmethod); //same Lmethod->set_sensitive(false); - Lmethod->set_sensitive(false); - Lmethod->append (M("TP_WAVELET_1")); - Lmethod->append (M("TP_WAVELET_2")); - Lmethod->append (M("TP_WAVELET_3")); - Lmethod->append (M("TP_WAVELET_4")); - Lmethod->append (M("TP_WAVELET_5")); - Lmethod->append (M("TP_WAVELET_6")); - Lmethod->append (M("TP_WAVELET_7")); - Lmethod->append (M("TP_WAVELET_8")); - Lmethod->append (M("TP_WAVELET_9")); - Lmethod->append (M("TP_WAVELET_SUPE")); - Lmethod->append (M("TP_WAVELET_RESID")); + Lmethod->append(M("TP_WAVELET_1")); + Lmethod->append(M("TP_WAVELET_2")); + Lmethod->append(M("TP_WAVELET_3")); + Lmethod->append(M("TP_WAVELET_4")); + Lmethod->append(M("TP_WAVELET_5")); + Lmethod->append(M("TP_WAVELET_6")); + Lmethod->append(M("TP_WAVELET_7")); + Lmethod->append(M("TP_WAVELET_8")); + Lmethod->append(M("TP_WAVELET_9")); + Lmethod->append(M("TP_WAVELET_SUPE")); + Lmethod->append(M("TP_WAVELET_RESID")); Lmethod->set_active(0); Dirmethod->set_sensitive(false); - Dirmethod->append (M("TP_WAVELET_DONE")); - Dirmethod->append (M("TP_WAVELET_DTWO")); - Dirmethod->append (M("TP_WAVELET_DTHR")); - Dirmethod->append (M("TP_WAVELET_DALL")); - Lmethodconn = Lmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::LmethodChanged) ); - Dirmethodconn = Dirmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::DirmethodChanged) ); + Dirmethod->append(M("TP_WAVELET_DONE")); + Dirmethod->append(M("TP_WAVELET_DTWO")); + Dirmethod->append(M("TP_WAVELET_DTHR")); + Dirmethod->append(M("TP_WAVELET_DALL")); + Lmethodconn = Lmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::LmethodChanged)); + Dirmethodconn = Dirmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::DirmethodChanged)); Gtk::HBox* const levdirSubHBox = Gtk::manage(new Gtk::HBox()); levdirSubHBox->pack_start(*Lmethod); levdirSubHBox->pack_start(*Dirmethod, Gtk::PACK_EXPAND_WIDGET, 2); // same, but 2 not 4? @@ -258,74 +321,86 @@ Wavelet::Wavelet() : settingsBox->pack_start(*levdirSubHBox); // Contrast - ToolParamBlock* const levBox = Gtk::manage (new ToolParamBlock()); + ToolParamBlock* const levBox = Gtk::manage(new ToolParamBlock()); - Gtk::HBox* const buttonBox = Gtk::manage (new Gtk::HBox(true, 10)); + Gtk::HBox* const buttonBox = Gtk::manage(new Gtk::HBox(true, 10)); levBox->pack_start(*buttonBox, Gtk::PACK_SHRINK, 2); - Gtk::Button* const contrastMinusButton = Gtk::manage (new Gtk::Button(M("TP_WAVELET_CONTRAST_MINUS"))); + Gtk::Button* const contrastMinusButton = Gtk::manage(new Gtk::Button(M("TP_WAVELET_CONTRAST_MINUS"))); buttonBox->pack_start(*contrastMinusButton); - contrastMinusPressedConn = contrastMinusButton->signal_pressed().connect( sigc::mem_fun(*this, &Wavelet::contrastMinusPressed)); + contrastMinusPressedConn = contrastMinusButton->signal_pressed().connect(sigc::mem_fun(*this, &Wavelet::contrastMinusPressed)); - Gtk::Button* const neutralButton = Gtk::manage (new Gtk::Button(M("TP_WAVELET_NEUTRAL"))); + Gtk::Button* const neutralButton = Gtk::manage(new Gtk::Button(M("TP_WAVELET_NEUTRAL"))); buttonBox->pack_start(*neutralButton); - neutralPressedConn = neutralButton->signal_pressed().connect( sigc::mem_fun(*this, &Wavelet::neutralPressed)); + neutralPressedConn = neutralButton->signal_pressed().connect(sigc::mem_fun(*this, &Wavelet::neutralPressed)); - Gtk::Button* const contrastPlusButton = Gtk::manage (new Gtk::Button(M("TP_WAVELET_CONTRAST_PLUS"))); + Gtk::Button* const contrastPlusButton = Gtk::manage(new Gtk::Button(M("TP_WAVELET_CONTRAST_PLUS"))); buttonBox->pack_start(*contrastPlusButton); - contrastPlusPressedConn = contrastPlusButton->signal_pressed().connect( sigc::mem_fun(*this, &Wavelet::contrastPlusPressed)); + contrastPlusPressedConn = contrastPlusButton->signal_pressed().connect(sigc::mem_fun(*this, &Wavelet::contrastPlusPressed)); buttonBox->show_all_children(); - for(int i = 0; i < 9; i++) { + for (int i = 0; i < 9; i++) { Glib::ustring ss; - switch( i ) { - case 0: - ss = Glib::ustring::compose( "%1 (%2)", (i + 1), M("TP_WAVELET_FINEST")); - break; + switch (i) { + case 0: + ss = Glib::ustring::compose("%1 (%2)", (i + 1), M("TP_WAVELET_FINEST")); + break; - case 8: - ss = Glib::ustring::compose( "%1 (%2)", (i + 1), M("TP_WAVELET_LARGEST")); - break; + case 8: + ss = Glib::ustring::compose("%1 (%2)", (i + 1), M("TP_WAVELET_LARGEST")); + break; - default: - ss = Glib::ustring::compose( "%1", (i + 1)); + default: + ss = Glib::ustring::compose("%1", (i + 1)); } correction[i] = Gtk::manage(new Adjuster(std::move(ss), -100, 350, 1, 0)); correction[i]->setAdjusterListener(this); levBox->pack_start(*correction[i]); } - levBox->pack_start(*sup); - sup->setAdjusterListener (this); + sup->setAdjusterListener(this); + Gtk::HSeparator* const separatorcont = Gtk::manage(new Gtk::HSeparator()); + levBox->pack_start(*separatorcont); + + sigma->setAdjusterListener(this); + levBox->pack_start(*sigma, Gtk::PACK_SHRINK); + offset->setAdjusterListener(this); + levBox->pack_start(*offset, Gtk::PACK_SHRINK); + sigma->set_tooltip_text(M("TP_WAVELET_SIGMA_TOOLTIP")); + offset->set_tooltip_text(M("TP_WAVELET_OFFSET_TOOLTIP")); + lowthr->setAdjusterListener(this); + lowthr->set_tooltip_text(M("TP_WAVELET_LOWTHR_TOOLTIP")); + levBox->pack_start(*lowthr, Gtk::PACK_SHRINK); + wavLabels->show(); - levBox->pack_start (*wavLabels); + levBox->pack_start(*wavLabels); Gtk::VBox* const contrastSHVBox = Gtk::manage(new Gtk::VBox); contrastSHVBox->set_spacing(2); - HSmethod->append (M("TP_WAVELET_HS1")); - HSmethod->append (M("TP_WAVELET_HS2")); - HSmethodconn = HSmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::HSmethodChanged) ); + HSmethod->append(M("TP_WAVELET_HS1")); + HSmethod->append(M("TP_WAVELET_HS2")); + HSmethodconn = HSmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::HSmethodChanged)); const std::vector milestones2 = { GradientMilestone(0.0, 0.0, 0.0, 0.0), GradientMilestone(1.0, 1.0, 1.0, 1.0) }; - hllev->setAdjusterListener (this); + hllev->setAdjusterListener(this); hllev->setBgGradient(milestones2); - threshold->setAdjusterListener (this); - threshold->set_tooltip_text (M("TP_WAVELET_THRESHOLD_TOOLTIP")); + threshold->setAdjusterListener(this); + threshold->set_tooltip_text(M("TP_WAVELET_THRESHOLD_TOOLTIP")); - bllev->setAdjusterListener (this); + bllev->setAdjusterListener(this); bllev->setBgGradient(milestones2); - threshold2->setAdjusterListener (this); - threshold2->set_tooltip_text (M("TP_WAVELET_THRESHOLD2_TOOLTIP")); + threshold2->setAdjusterListener(this); + threshold2->set_tooltip_text(M("TP_WAVELET_THRESHOLD2_TOOLTIP")); contrastSHVBox->pack_start(*HSmethod); contrastSHVBox->pack_start(*hllev); @@ -337,68 +412,68 @@ Wavelet::Wavelet() : levBox->pack_start(*contrastSHFrame); // Chromaticity - ToolParamBlock* const chBox = Gtk::manage (new ToolParamBlock()); + ToolParamBlock* const chBox = Gtk::manage(new ToolParamBlock()); Gtk::Label* const labmch = Gtk::manage(new Gtk::Label(M("TP_WAVELET_CHTYPE") + ":")); Gtk::HBox* const ctboxch = Gtk::manage(new Gtk::HBox()); - ctboxch->pack_start (*labmch, Gtk::PACK_SHRINK, 1); + ctboxch->pack_start(*labmch, Gtk::PACK_SHRINK, 1); - CHmethod->append (M("TP_WAVELET_CH1")); - CHmethod->append (M("TP_WAVELET_CH2")); - CHmethod->append (M("TP_WAVELET_CH3")); - CHmethodconn = CHmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::CHmethodChanged) ); + CHmethod->append(M("TP_WAVELET_CH1")); + CHmethod->append(M("TP_WAVELET_CH2")); + CHmethod->append(M("TP_WAVELET_CH3")); + CHmethodconn = CHmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::CHmethodChanged)); ctboxch->pack_start(*CHmethod); chBox->pack_start(*ctboxch); Gtk::HBox* const ctboxCH = Gtk::manage(new Gtk::HBox()); - ctboxCH->pack_start (*labmC, Gtk::PACK_SHRINK, 1); + ctboxCH->pack_start(*labmC, Gtk::PACK_SHRINK, 1); - CHSLmethod->append (M("TP_WAVELET_CHSL")); - CHSLmethod->append (M("TP_WAVELET_CHCU")); - CHSLmethodconn = CHSLmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::CHSLmethodChanged) ); + CHSLmethod->append(M("TP_WAVELET_CHSL")); + CHSLmethod->append(M("TP_WAVELET_CHCU")); + CHSLmethodconn = CHSLmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::CHSLmethodChanged)); ctboxCH->pack_start(*CHSLmethod); - Gtk::HSeparator* const separatorChromaMethod = Gtk::manage (new Gtk::HSeparator()); + Gtk::HSeparator* const separatorChromaMethod = Gtk::manage(new Gtk::HSeparator()); chBox->pack_start(*separatorChromaMethod, Gtk::PACK_SHRINK, 2); - chroma->set_tooltip_text (M("TP_WAVELET_CHRO_TOOLTIP")); + chroma->set_tooltip_text(M("TP_WAVELET_CHRO_TOOLTIP")); chBox->pack_start(*chroma); - chroma->setAdjusterListener (this); + chroma->setAdjusterListener(this); - satlev->setAdjusterListener (this); + satlev->setAdjusterListener(this); satlev->setBgGradient(milestones2); - pastlev->setAdjusterListener (this); + pastlev->setAdjusterListener(this); pastlev->setBgGradient(milestones2); chBox->pack_start(*pastlev); chBox->pack_start(*satlev); - chro->set_tooltip_text (M("TP_WAVELET_CHR_TOOLTIP")); + chro->set_tooltip_text(M("TP_WAVELET_CHR_TOOLTIP")); chBox->pack_start(*chro); - chro->setAdjusterListener (this); + chro->setAdjusterListener(this); - Gtk::HBox* const buttonchBox = Gtk::manage (new Gtk::HBox(true, 10)); - neutralchPressedConn = neutralchButton->signal_pressed().connect( sigc::mem_fun(*this, &Wavelet::neutralchPressed)); + Gtk::HBox* const buttonchBox = Gtk::manage(new Gtk::HBox(true, 10)); + neutralchPressedConn = neutralchButton->signal_pressed().connect(sigc::mem_fun(*this, &Wavelet::neutralchPressed)); chBox->pack_start(*separatorNeutral, Gtk::PACK_SHRINK, 2); buttonchBox->pack_start(*neutralchButton); buttonchBox->show_all_children(); chBox->pack_start(*buttonchBox, Gtk::PACK_SHRINK, 2); - for(int i = 0; i < 9; i++) { + for (int i = 0; i < 9; i++) { Glib::ustring ss; - switch( i ) { - case 0: - ss = Glib::ustring::compose( "%1 (%2)", (i + 1), M("TP_WAVELET_FINEST")); - break; + switch (i) { + case 0: + ss = Glib::ustring::compose("%1 (%2)", (i + 1), M("TP_WAVELET_FINEST")); + break; - case 8: - ss = Glib::ustring::compose( "%1 (%2)", (i + 1), M("TP_WAVELET_LARGEST")); - break; + case 8: + ss = Glib::ustring::compose("%1 (%2)", (i + 1), M("TP_WAVELET_LARGEST")); + break; - default: - ss = Glib::ustring::compose( "%1", (i + 1)); + default: + ss = Glib::ustring::compose("%1", (i + 1)); } correctionch[i] = Gtk::manage(new Adjuster(std::move(ss), -100, 100, 1, 0)); @@ -407,9 +482,9 @@ Wavelet::Wavelet() : } // Toning - ToolParamBlock* const tonBox = Gtk::manage (new ToolParamBlock()); + ToolParamBlock* const tonBox = Gtk::manage(new ToolParamBlock()); - opaCurveEditorG->setCurveListener (this); + opaCurveEditorG->setCurveListener(this); const WaveletParams default_params; @@ -420,9 +495,9 @@ Wavelet::Wavelet() : opaCurveEditorG->curveListComplete(); opaCurveEditorG->show(); - tonBox->pack_start( *opaCurveEditorG, Gtk::PACK_SHRINK, 2); + tonBox->pack_start(*opaCurveEditorG, Gtk::PACK_SHRINK, 2); - opacityCurveEditorG->setCurveListener (this); + opacityCurveEditorG->setCurveListener(this); opacityShapeBY = static_cast(opacityCurveEditorG->addCurve(CT_Flat, "", nullptr, false, false)); opacityShapeBY->setIdentityValue(0.); @@ -431,77 +506,118 @@ Wavelet::Wavelet() : opacityCurveEditorG->curveListComplete(); opacityCurveEditorG->show(); - tonBox->pack_start( *opacityCurveEditorG, Gtk::PACK_SHRINK, 2); + tonBox->pack_start(*opacityCurveEditorG, Gtk::PACK_SHRINK, 2); // Denoise and Refine - ToolParamBlock* const noiseBox = Gtk::manage (new ToolParamBlock()); + ToolParamBlock* const noiseBox = Gtk::manage(new ToolParamBlock()); - linkedg->set_active (true); - linkedgConn = linkedg->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::linkedgToggled) ); + linkedg->set_active(true); + linkedgConn = linkedg->signal_toggled().connect(sigc::mem_fun(*this, &Wavelet::linkedgToggled)); noiseBox->pack_start(*linkedg); - level0noise->setAdjusterListener (this); + level0noise->setAdjusterListener(this); level0noise->setUpdatePolicy(RTUP_DYNAMIC); - level1noise->setAdjusterListener (this); + level1noise->setAdjusterListener(this); level1noise->setUpdatePolicy(RTUP_DYNAMIC); - level2noise->setAdjusterListener (this); + level2noise->setAdjusterListener(this); level2noise->setUpdatePolicy(RTUP_DYNAMIC); - level3noise->setAdjusterListener (this); + level3noise->setAdjusterListener(this); level3noise->setUpdatePolicy(RTUP_DYNAMIC); + ballum->setAdjusterListener(this); - noiseBox->pack_start( *level0noise, Gtk::PACK_SHRINK, 0); - noiseBox->pack_start( *level1noise, Gtk::PACK_SHRINK, 0); - noiseBox->pack_start( *level2noise, Gtk::PACK_SHRINK, 0); - noiseBox->pack_start( *level3noise, Gtk::PACK_SHRINK, 0); + noiseBox->pack_start(*ballum); + noiseBox->pack_start(*level0noise, Gtk::PACK_SHRINK, 0); + noiseBox->pack_start(*level1noise, Gtk::PACK_SHRINK, 0); + noiseBox->pack_start(*level2noise, Gtk::PACK_SHRINK, 0); + noiseBox->pack_start(*level3noise, Gtk::PACK_SHRINK, 0); + + balchrom->setAdjusterListener(this); + chromfi->setAdjusterListener(this); + chromco->setAdjusterListener(this); + + chroFrame->set_label_align(0.025, 0.5); + ToolParamBlock* const chroBox = Gtk::manage(new ToolParamBlock()); + chroBox->pack_start(*balchrom); + chroBox->pack_start(*chromfi); + chroBox->pack_start(*chromco); + chroFrame->add(*chroBox); + noiseBox->pack_start(*chroFrame); + + +//Clarity + mergeL->setAdjusterListener(this); + mergeC->setAdjusterListener(this); + softrad->setAdjusterListener(this); + showmask->set_active(false); + showmaskConn = showmask->signal_toggled().connect(sigc::mem_fun(*this, &Wavelet::showmaskToggled)); + + ToolParamBlock* const clariBox = Gtk::manage(new ToolParamBlock()); + // ushamethod->append(M("TP_WAVELET_USH")); + ushamethod->append(M("TP_WAVELET_SHA")); + ushamethod->append(M("TP_WAVELET_CLA")); + ushamethodconn = ushamethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::ushamethodChanged)); + ushamethod->set_tooltip_text(M("TP_WAVELET_USH_TOOLTIP")); + usharpHBox->pack_start(*usharpLabel, Gtk::PACK_SHRINK, 0); + usharpHBox->pack_start(*ushamethod); + + clariBox->pack_start(*usharpHBox); + clariBox->pack_start(*mergeL); + clariBox->pack_start(*mergeC); + clariBox->pack_start(*softrad); + clariBox->pack_start(*showmask); // Edge Sharpness - ToolParamBlock* const edgBox = Gtk::manage (new ToolParamBlock()); + ToolParamBlock* const edgBox = Gtk::manage(new ToolParamBlock()); + edgeffect->setAdjusterListener(this); + edgBox->pack_start(*edgeffect); + edgeffect->set_tooltip_markup(M("TP_WAVELET_EDEFFECT_TOOLTIP")); edgval->setAdjusterListener(this); edgBox->pack_start(*edgval); + edgrad->setAdjusterListener(this); edgBox->pack_start(*edgrad); - edgrad->set_tooltip_markup (M("TP_WAVELET_EDRAD_TOOLTIP")); + edgrad->set_tooltip_markup(M("TP_WAVELET_EDRAD_TOOLTIP")); - edgthresh->setAdjusterListener (this); - edgthresh->set_tooltip_markup (M("TP_WAVELET_EDGTHRESH_TOOLTIP")); - edgBox->pack_start (*edgthresh); + edgthresh->setAdjusterListener(this); + edgthresh->set_tooltip_markup(M("TP_WAVELET_EDGTHRESH_TOOLTIP")); + edgBox->pack_start(*edgthresh); Gtk::Label* const labmedgr = Gtk::manage(new Gtk::Label(M("TP_WAVELET_MEDGREINF") + ":")); Gtk::HBox* const edbox = Gtk::manage(new Gtk::HBox()); - edbox->pack_start (*labmedgr, Gtk::PACK_SHRINK, 1); + edbox->pack_start(*labmedgr, Gtk::PACK_SHRINK, 1); - Medgreinf->append (M("TP_WAVELET_RE1")); - Medgreinf->append (M("TP_WAVELET_RE2")); - Medgreinf->append (M("TP_WAVELET_RE3")); - MedgreinfConn = Medgreinf->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::MedgreinfChanged) ); - Medgreinf->set_tooltip_markup (M("TP_WAVELET_EDGREINF_TOOLTIP")); + Medgreinf->append(M("TP_WAVELET_RE1")); + Medgreinf->append(M("TP_WAVELET_RE2")); + Medgreinf->append(M("TP_WAVELET_RE3")); + MedgreinfConn = Medgreinf->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::MedgreinfChanged)); + Medgreinf->set_tooltip_markup(M("TP_WAVELET_EDGREINF_TOOLTIP")); edbox->pack_start(*Medgreinf); edgBox->pack_start(*edbox); - Gtk::HSeparator* const separatorlc = Gtk::manage (new Gtk::HSeparator()); + Gtk::HSeparator* const separatorlc = Gtk::manage(new Gtk::HSeparator()); edgBox->pack_start(*separatorlc, Gtk::PACK_SHRINK, 2); Gtk::Label* const labmED = Gtk::manage(new Gtk::Label(M("TP_WAVELET_EDTYPE") + ":")); Gtk::HBox* const ctboxED = Gtk::manage(new Gtk::HBox()); - ctboxED->pack_start (*labmED, Gtk::PACK_SHRINK, 1); + ctboxED->pack_start(*labmED, Gtk::PACK_SHRINK, 1); - EDmethod->append (M("TP_WAVELET_EDSL")); - EDmethod->append (M("TP_WAVELET_EDCU")); - EDmethodconn = EDmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::EDmethodChanged) ); + EDmethod->append(M("TP_WAVELET_EDSL")); + EDmethod->append(M("TP_WAVELET_EDCU")); + EDmethodconn = EDmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::EDmethodChanged)); ctboxED->pack_start(*EDmethod); - edgBox->pack_start (*ctboxED); + edgBox->pack_start(*ctboxED); - edgcont->setAdjusterListener (this); + edgcont->setAdjusterListener(this); edgcont->setBgGradient(milestones2); - edgcont->set_tooltip_markup (M("TP_WAVELET_EDGCONT_TOOLTIP")); + edgcont->set_tooltip_markup(M("TP_WAVELET_EDGCONT_TOOLTIP")); // <-- Edge Sharpness Local Contrast curve - CCWcurveEditorG->setCurveListener (this); + CCWcurveEditorG->setCurveListener(this); ccshape = static_cast(CCWcurveEditorG->addCurve(CT_Flat, "", nullptr, false, false)); @@ -513,70 +629,94 @@ Wavelet::Wavelet() : CCWcurveEditorG->show(); // --> - edgBox->pack_start (*edgcont); + edgBox->pack_start(*edgcont); edgBox->pack_start(*CCWcurveEditorG, Gtk::PACK_SHRINK, 4); - medianlev->set_active (true); - medianlevConn = medianlev->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::medianlevToggled) ); - medianlev->set_tooltip_text (M("TP_WAVELET_MEDILEV_TOOLTIP")); + medianlev->set_active(true); + medianlevConn = medianlev->signal_toggled().connect(sigc::mem_fun(*this, &Wavelet::medianlevToggled)); + medianlev->set_tooltip_text(M("TP_WAVELET_MEDILEV_TOOLTIP")); - Gtk::HSeparator* const separatored1 = Gtk::manage (new Gtk::HSeparator()); + Gtk::HSeparator* const separatored1 = Gtk::manage(new Gtk::HSeparator()); edgBox->pack_start(*separatored1, Gtk::PACK_SHRINK, 2); Gtk::HBox* const eddebox = Gtk::manage(new Gtk::HBox()); - edgBox->pack_start (*eddebox); + edgBox->pack_start(*eddebox); edgBox->pack_start(*medianlev); - edgedetect->setAdjusterListener (this); - edgedetect->set_tooltip_text (M("TP_WAVELET_EDGEDETECT_TOOLTIP")); + edgedetect->setAdjusterListener(this); + edgedetect->set_tooltip_text(M("TP_WAVELET_EDGEDETECT_TOOLTIP")); edgBox->pack_start(*edgedetect); - edgedetectthr->setAdjusterListener (this); - edgedetectthr->set_tooltip_text (M("TP_WAVELET_EDGEDETECTTHR_TOOLTIP")); + edgedetectthr->setAdjusterListener(this); + edgedetectthr->set_tooltip_text(M("TP_WAVELET_EDGEDETECTTHR_TOOLTIP")); edgBox->pack_start(*edgedetectthr); - edgedetectthr2->setAdjusterListener (this); + edgedetectthr2->setAdjusterListener(this); edgBox->pack_start(*edgedetectthr2); edgBox->pack_start(*separatoredge, Gtk::PACK_SHRINK, 2); - lipst->set_active (true); - lipstConn = lipst->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::lipstToggled) ); + lipst->set_active(true); + lipstConn = lipst->signal_toggled().connect(sigc::mem_fun(*this, &Wavelet::lipstToggled)); // lipst->set_tooltip_text (M("TP_WAVELET_LIPST_TOOLTIP")); edgBox->pack_start(*lipst); - edgesensi->setAdjusterListener (this); + edgesensi->setAdjusterListener(this); edgBox->pack_start(*edgesensi); - edgeampli->setAdjusterListener (this); + edgeampli->setAdjusterListener(this); edgBox->pack_start(*edgeampli); - Gtk::VBox* const ctboxES = Gtk::manage (new Gtk::VBox()); + Gtk::VBox* const ctboxES = Gtk::manage(new Gtk::VBox()); ctboxES->set_spacing(2); Gtk::HBox* const ctboxNP = Gtk::manage(new Gtk::HBox()); - ctboxNP->pack_start (*labmNP, Gtk::PACK_SHRINK, 1); + ctboxNP->pack_start(*labmNP, Gtk::PACK_SHRINK, 1); - NPmethod->append (M("TP_WAVELET_NPNONE")); - NPmethod->append (M("TP_WAVELET_NPLOW")); - NPmethod->append (M("TP_WAVELET_NPHIGH")); - NPmethodconn = NPmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::NPmethodChanged) ); - NPmethod->set_tooltip_text (M("TP_WAVELET_NPTYPE_TOOLTIP")); + NPmethod->append(M("TP_WAVELET_NPNONE")); + NPmethod->append(M("TP_WAVELET_NPLOW")); + NPmethod->append(M("TP_WAVELET_NPHIGH")); + NPmethodconn = NPmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::NPmethodChanged)); + NPmethod->set_tooltip_text(M("TP_WAVELET_NPTYPE_TOOLTIP")); ctboxNP->pack_start(*NPmethod); ctboxES->pack_start(*ctboxNP); edgBox->pack_start(*ctboxES); -// Gamut - ToolParamBlock* const conBox = Gtk::manage (new ToolParamBlock()); +//Blur Wavelet + ToolParamBlock* const blBox = Gtk::manage(new ToolParamBlock()); + + curveEditorbl->setCurveListener(this); - median->set_active (true); - medianConn = median->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::medianToggled) ); + blshape = static_cast(curveEditorbl->addCurve(CT_Flat, "", nullptr, false, false)); + + blshape->setIdentityValue(0.); + blshape->setResetCurve(FlatCurveType(default_params.blcurve.at(0)), default_params.blcurve); + blshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_CC_TOOLTIP")); + + curveEditorbl->curveListComplete(); + curveEditorbl->show(); + + blBox->pack_start(*bluwav); + bluwav->setAdjusterListener(this); + blBox->pack_start(*curveEditorbl, Gtk::PACK_SHRINK, 4); + + + chrwav->setAdjusterListener(this); + blBox->pack_start(*chrwav); + + + +// Gamut + ToolParamBlock* const conBox = Gtk::manage(new ToolParamBlock()); + + median->set_active(true); + medianConn = median->signal_toggled().connect(sigc::mem_fun(*this, &Wavelet::medianToggled)); conBox->pack_start(*median); - hueskin->set_tooltip_markup (M("TP_WAVELET_HUESKIN_TOOLTIP")); + hueskin->set_tooltip_markup(M("TP_WAVELET_HUESKIN_TOOLTIP")); //from -PI to +PI (radians) convert to hsv and draw bottombar const std::vector milestones = { @@ -599,13 +739,13 @@ Wavelet::Wavelet() : hueskin->setBgGradient(milestones); conBox->pack_start(*hueskin); - hueskin->setAdjusterListener (this); + hueskin->setAdjusterListener(this); skinprotect->setAdjusterListener(this); conBox->pack_start(*skinprotect); - skinprotect->set_tooltip_markup (M("TP_WAVELET_SKIN_TOOLTIP")); + skinprotect->set_tooltip_markup(M("TP_WAVELET_SKIN_TOOLTIP")); - curveEditorGAM->setCurveListener (this); + curveEditorGAM->setCurveListener(this); Chshape = static_cast(curveEditorGAM->addCurve(CT_Flat, M("TP_WAVELET_CURVEEDITOR_CH"))); Chshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_CH_TOOLTIP")); @@ -613,74 +753,116 @@ Wavelet::Wavelet() : curveEditorGAM->curveListComplete(); Chshape->setBottomBarBgGradient(milestones); - conBox->pack_start (*curveEditorGAM, Gtk::PACK_SHRINK, 4); + conBox->pack_start(*curveEditorGAM, Gtk::PACK_SHRINK, 4); - avoid->set_active (true); - avoidConn = avoid->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::avoidToggled) ); + avoid->set_active(true); + avoidConn = avoid->signal_toggled().connect(sigc::mem_fun(*this, &Wavelet::avoidToggled)); conBox->pack_start(*avoid); // Residual Image - ToolParamBlock* const resBox = Gtk::manage (new ToolParamBlock()); + ToolParamBlock* const resBox = Gtk::manage(new ToolParamBlock()); + oldsh->set_active(true); + oldshConn = oldsh->signal_toggled().connect(sigc::mem_fun(*this, &Wavelet::oldshToggled)); - rescon->setAdjusterListener (this); - resBox->pack_start(*rescon, Gtk::PACK_SHRINK); - resBox->pack_start(*thr); - thr->setAdjusterListener (this); + rescon->setAdjusterListener(this); - resconH->setAdjusterListener (this); - resBox->pack_start(*resconH, Gtk::PACK_SHRINK); + thr->setAdjusterListener(this); - thrH->setAdjusterListener (this); - resBox->pack_start(*thrH, Gtk::PACK_SHRINK); + resconH->setAdjusterListener(this); - contrast->set_tooltip_text (M("TP_WAVELET_CONTRA_TOOLTIP")); - contrast->setAdjusterListener (this); - resBox->pack_start(*contrast); //keep the possibility to reinstall + thrH->setAdjusterListener(this); - reschro->setAdjusterListener (this); - resBox->pack_start(*reschro); + radius->setAdjusterListener(this); + radius->hide(); + shFrame->set_label_align(0.025, 0.5); + ToolParamBlock* const shBox = Gtk::manage(new ToolParamBlock()); + shBox->pack_start(*oldsh); + shBox->pack_start(*rescon, Gtk::PACK_SHRINK); + shBox->pack_start(*thr); + shBox->pack_start(*resconH, Gtk::PACK_SHRINK); + shBox->pack_start(*thrH, Gtk::PACK_SHRINK); + shBox->pack_start(*radius, Gtk::PACK_SHRINK); + shFrame->add(*shBox); + resBox->pack_start(*shFrame); + + + contrast->set_tooltip_text(M("TP_WAVELET_CONTRA_TOOLTIP")); + contrast->setAdjusterListener(this); + + reschro->setAdjusterListener(this); + resblur->setAdjusterListener(this); + resblurc->setAdjusterListener(this); + + blurFrame->set_label_align(0.025, 0.5); + ToolParamBlock* const blurBox = Gtk::manage(new ToolParamBlock()); + blurBox->pack_start(*resblur); + blurBox->pack_start(*resblurc); + blurFrame->add(*blurBox); + + chromaFrame->set_label_align(0.025, 0.5); + ToolParamBlock* const chromaBox = Gtk::manage(new ToolParamBlock()); + chromaBox->pack_start(*reschro); + chromaBox->pack_start(*hueskin2); + chromaBox->pack_start(*sky); + chromaFrame->add(*chromaBox); Gtk::Label* const labmTM = Gtk::manage(new Gtk::Label(M("TP_WAVELET_TMTYPE") + ":")); Gtk::HBox* const ctboxTM = Gtk::manage(new Gtk::HBox()); - ctboxTM->pack_start (*labmTM, Gtk::PACK_SHRINK, 1); + ctboxTM->pack_start(*labmTM, Gtk::PACK_SHRINK, 1); - Gtk::HSeparator* const separatorR0 = Gtk::manage (new Gtk::HSeparator()); - resBox->pack_start(*separatorR0, Gtk::PACK_SHRINK, 2); +// Gtk::HSeparator* const separatorR0 = Gtk::manage(new Gtk::HSeparator()); +// resBox->pack_start(*separatorR0, Gtk::PACK_SHRINK, 2); - TMmethod->append (M("TP_WAVELET_COMPCONT")); - TMmethod->append (M("TP_WAVELET_COMPTM")); - TMmethodconn = TMmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::TMmethodChanged) ); + TMmethod->append(M("TP_WAVELET_COMPCONT")); + TMmethod->append(M("TP_WAVELET_COMPTM")); + TMmethodconn = TMmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::TMmethodChanged)); ctboxTM->pack_start(*TMmethod); - resBox->pack_start (*ctboxTM); - tmrs->set_tooltip_text (M("TP_WAVELET_TMSTRENGTH_TOOLTIP")); + tmrs->set_tooltip_text(M("TP_WAVELET_TMSTRENGTH_TOOLTIP")); - resBox->pack_start(*tmrs); - tmrs->setAdjusterListener (this); + tmrs->setAdjusterListener(this); - gamma->set_tooltip_text (M("TP_WAVELET_COMPGAMMA_TOOLTIP")); - resBox->pack_start(*gamma); - gamma->setAdjusterListener (this); + gamma->set_tooltip_text(M("TP_WAVELET_COMPGAMMA_TOOLTIP")); + gamma->setAdjusterListener(this); - Gtk::HSeparator* const separatorR1 = Gtk::manage (new Gtk::HSeparator()); - resBox->pack_start(*separatorR1, Gtk::PACK_SHRINK, 2); + //edgs->set_tooltip_text(M("TP_WAVELET_TMEDGS_TOOLTIP")); - hueskin2->set_tooltip_markup (M("TP_WAVELET_HUESKY_TOOLTIP")); + edgs->setAdjusterListener(this); + + //scale->set_tooltip_text(M("TP_WAVELET_TMSCALE_TOOLTIP")); + + scale->setAdjusterListener(this); + + contFrame->set_label_align(0.025, 0.5); + ToolParamBlock* const contBox = Gtk::manage(new ToolParamBlock()); + contBox->pack_start(*contrast); //keep the possibility to reinstall + contBox->pack_start(*ctboxTM); + contBox->pack_start(*tmrs); + contBox->pack_start(*gamma); + contBox->pack_start(*edgs); + contBox->pack_start(*scale); + contFrame->add(*contBox); + resBox->pack_start(*contFrame); + +// Gtk::HSeparator* const separatorR1 = Gtk::manage(new Gtk::HSeparator()); +// resBox->pack_start(*separatorR1, Gtk::PACK_SHRINK, 2); + + hueskin2->set_tooltip_markup(M("TP_WAVELET_HUESKY_TOOLTIP")); hueskin2->setBgGradient(milestones); - resBox->pack_start(*hueskin2); - hueskin2->setAdjusterListener (this); + hueskin2->setAdjusterListener(this); - sky->set_tooltip_text (M("TP_WAVELET_SKY_TOOLTIP")); - sky->setAdjusterListener (this); + sky->set_tooltip_text(M("TP_WAVELET_SKY_TOOLTIP")); + sky->setAdjusterListener(this); - resBox->pack_start(*sky); // whole hue range const std::vector milestones3 = makeWholeHueRange(); - curveEditorRES->setCurveListener (this); + curveEditorRES->setCurveListener(this); + resBox->pack_start(*blurFrame); + resBox->pack_start(*chromaFrame); hhshape = static_cast(curveEditorRES->addCurve(CT_Flat, M("TP_WAVELET_CURVEEDITOR_HH"))); hhshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_HH_TOOLTIP")); @@ -688,54 +870,54 @@ Wavelet::Wavelet() : curveEditorRES->curveListComplete(); hhshape->setBottomBarBgGradient(milestones3); - resBox->pack_start (*curveEditorRES, Gtk::PACK_SHRINK, 4); + resBox->pack_start(*curveEditorRES, Gtk::PACK_SHRINK, 4); // Toning and Color Balance - Gtk::HSeparator* const separatorCB = Gtk::manage (new Gtk::HSeparator()); + Gtk::HSeparator* const separatorCB = Gtk::manage(new Gtk::HSeparator()); - Gtk::VBox* const chanMixerHLBox = Gtk::manage (new Gtk::VBox()); - Gtk::VBox* const chanMixerMidBox = Gtk::manage (new Gtk::VBox()); - Gtk::VBox* const chanMixerShadowsBox = Gtk::manage (new Gtk::VBox()); + Gtk::VBox* const chanMixerHLBox = Gtk::manage(new Gtk::VBox()); + Gtk::VBox* const chanMixerMidBox = Gtk::manage(new Gtk::VBox()); + Gtk::VBox* const chanMixerShadowsBox = Gtk::manage(new Gtk::VBox()); - cbenab->set_active (true); - cbenabConn = cbenab->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::cbenabToggled) ); - cbenab->set_tooltip_text (M("TP_WAVELET_CB_TOOLTIP")); + cbenab->set_active(true); + cbenabConn = cbenab->signal_toggled().connect(sigc::mem_fun(*this, &Wavelet::cbenabToggled)); + cbenab->set_tooltip_text(M("TP_WAVELET_CB_TOOLTIP")); - Gtk::Image* const iblueR = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* const iyelL = Gtk::manage (new RTImage ("circle-yellow-small.png")); - Gtk::Image* const imagL = Gtk::manage (new RTImage ("circle-magenta-small.png")); - Gtk::Image* const igreenR = Gtk::manage (new RTImage ("circle-green-small.png")); + Gtk::Image* const iblueR = Gtk::manage(new RTImage("circle-blue-small.png")); + Gtk::Image* const iyelL = Gtk::manage(new RTImage("circle-yellow-small.png")); + Gtk::Image* const imagL = Gtk::manage(new RTImage("circle-magenta-small.png")); + Gtk::Image* const igreenR = Gtk::manage(new RTImage("circle-green-small.png")); - Gtk::Image* const iblueRm = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* const iyelLm = Gtk::manage (new RTImage ("circle-yellow-small.png")); - Gtk::Image* const imagLm = Gtk::manage (new RTImage ("circle-magenta-small.png")); - Gtk::Image* const igreenRm = Gtk::manage (new RTImage ("circle-green-small.png")); + Gtk::Image* const iblueRm = Gtk::manage(new RTImage("circle-blue-small.png")); + Gtk::Image* const iyelLm = Gtk::manage(new RTImage("circle-yellow-small.png")); + Gtk::Image* const imagLm = Gtk::manage(new RTImage("circle-magenta-small.png")); + Gtk::Image* const igreenRm = Gtk::manage(new RTImage("circle-green-small.png")); - Gtk::Image* const iblueRh = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* const iyelLh = Gtk::manage (new RTImage ("circle-yellow-small.png")); - Gtk::Image* const imagLh = Gtk::manage (new RTImage ("circle-magenta-small.png")); - Gtk::Image* const igreenRh = Gtk::manage (new RTImage ("circle-green-small.png")); + Gtk::Image* const iblueRh = Gtk::manage(new RTImage("circle-blue-small.png")); + Gtk::Image* const iyelLh = Gtk::manage(new RTImage("circle-yellow-small.png")); + Gtk::Image* const imagLh = Gtk::manage(new RTImage("circle-magenta-small.png")); + Gtk::Image* const igreenRh = Gtk::manage(new RTImage("circle-green-small.png")); - greenhigh = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., igreenRh, imagLh)); - bluehigh = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., iblueRh, iyelLh)); - greenmed = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., igreenRm, imagLm)); - bluemed = Gtk::manage (new Adjuster ("", -100., 100., 1., 0. , iblueRm , iyelLm)); - greenlow = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., igreenR, imagL)); - bluelow = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., iblueR , iyelL)); + greenhigh = Gtk::manage(new Adjuster("", -100., 100., 1., 0., igreenRh, imagLh)); + bluehigh = Gtk::manage(new Adjuster("", -100., 100., 1., 0., iblueRh, iyelLh)); + greenmed = Gtk::manage(new Adjuster("", -100., 100., 1., 0., igreenRm, imagLm)); + bluemed = Gtk::manage(new Adjuster("", -100., 100., 1., 0., iblueRm, iyelLm)); + greenlow = Gtk::manage(new Adjuster("", -100., 100., 1., 0., igreenR, imagL)); + bluelow = Gtk::manage(new Adjuster("", -100., 100., 1., 0., iblueR, iyelL)); - chanMixerHLBox->pack_start (*greenhigh); - chanMixerHLBox->pack_start (*bluehigh); - chanMixerMidBox->pack_start (*greenmed); - chanMixerMidBox->pack_start (*bluemed); - chanMixerShadowsBox->pack_start (*greenlow); - chanMixerShadowsBox->pack_start (*bluelow); + chanMixerHLBox->pack_start(*greenhigh); + chanMixerHLBox->pack_start(*bluehigh); + chanMixerMidBox->pack_start(*greenmed); + chanMixerMidBox->pack_start(*bluemed); + chanMixerShadowsBox->pack_start(*greenlow); + chanMixerShadowsBox->pack_start(*bluelow); - greenlow->setAdjusterListener (this); - bluelow->setAdjusterListener (this); - greenmed->setAdjusterListener (this); - bluemed->setAdjusterListener (this); - greenhigh->setAdjusterListener (this); - bluehigh->setAdjusterListener (this); + greenlow->setAdjusterListener(this); + bluelow->setAdjusterListener(this); + greenmed->setAdjusterListener(this); + bluemed->setAdjusterListener(this); + greenhigh->setAdjusterListener(this); + bluehigh->setAdjusterListener(this); resBox->pack_start(*separatorCB, Gtk::PACK_SHRINK); @@ -751,15 +933,15 @@ Wavelet::Wavelet() : //RTImage *resetImg = Gtk::manage (new RTImage ("undo-small.png", "redo-small.png")); //neutral->set_image(*resetImg); Gtk::Button* const neutral = Gtk::manage(new Gtk::Button(M("TP_COLORTONING_NEUTRAL"))); - neutral->set_tooltip_text (M("TP_COLORTONING_NEUTRAL_TIP")); - neutralconn = neutral->signal_pressed().connect( sigc::mem_fun(*this, &Wavelet::neutral_pressed) ); + neutral->set_tooltip_text(M("TP_COLORTONING_NEUTRAL_TIP")); + neutralconn = neutral->signal_pressed().connect(sigc::mem_fun(*this, &Wavelet::neutral_pressed)); neutral->show(); - neutrHBox->pack_start (*neutral, Gtk::PACK_EXPAND_WIDGET); + neutrHBox->pack_start(*neutral, Gtk::PACK_EXPAND_WIDGET); - resBox->pack_start (*neutrHBox); + resBox->pack_start(*neutrHBox); // Final Touchup - Gtk::VBox* const ctboxBA = Gtk::manage (new Gtk::VBox()); + Gtk::VBox* const ctboxBA = Gtk::manage(new Gtk::VBox()); ctboxBA->set_spacing(2); @@ -767,19 +949,20 @@ Wavelet::Wavelet() : //ctboxBA->pack_start(*separatorfin, Gtk::PACK_SHRINK, 2); Gtk::Label* const labmBA = Gtk::manage(new Gtk::Label(M("TP_WAVELET_BATYPE") + ":")); Gtk::HBox* const ctboxFI = Gtk::manage(new Gtk::HBox()); - ctboxFI->pack_start (*labmBA, Gtk::PACK_SHRINK, 1); + ctboxFI->pack_start(*labmBA, Gtk::PACK_SHRINK, 1); - BAmethod->append (M("TP_WAVELET_BANONE")); - BAmethod->append (M("TP_WAVELET_BASLI")); - BAmethod->append (M("TP_WAVELET_BACUR")); - BAmethodconn = BAmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::BAmethodChanged) ); + BAmethod->append(M("TP_WAVELET_BANONE")); + BAmethod->append(M("TP_WAVELET_BASLI")); + BAmethod->append(M("TP_WAVELET_BACUR")); + BAmethodconn = BAmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::BAmethodChanged)); ctboxFI->pack_start(*BAmethod); ctboxBA->pack_start(*ctboxFI); - balance->setAdjusterListener (this); - balance->set_tooltip_text (M("TP_WAVELET_BALANCE_TOOLTIP")); + balance->setAdjusterListener(this); + balance->set_tooltip_text(M("TP_WAVELET_BALANCE_TOOLTIP")); + softradend->setAdjusterListener(this); - opacityCurveEditorW->setCurveListener (this); + opacityCurveEditorW->setCurveListener(this); opacityShape = static_cast(opacityCurveEditorW->addCurve(CT_Flat, "", nullptr, false, false)); opacityShape->setIdentityValue(0.); @@ -790,12 +973,12 @@ Wavelet::Wavelet() : opacityCurveEditorW->curveListComplete(); opacityCurveEditorW->show(); - iter->setAdjusterListener (this); - iter->set_tooltip_text (M("TP_WAVELET_ITER_TOOLTIP")); + iter->setAdjusterListener(this); + iter->set_tooltip_text(M("TP_WAVELET_ITER_TOOLTIP")); - Gtk::HSeparator* const separatorbalend = Gtk::manage (new Gtk::HSeparator()); + Gtk::HSeparator* const separatorbalend = Gtk::manage(new Gtk::HSeparator()); - opacityCurveEditorWL->setCurveListener (this); + opacityCurveEditorWL->setCurveListener(this); opacityShapeWL = static_cast(opacityCurveEditorWL->addCurve(CT_Flat, "", nullptr, false, false)); opacityShapeWL->setIdentityValue(0.); @@ -806,7 +989,7 @@ Wavelet::Wavelet() : opacityCurveEditorWL->curveListComplete(); opacityCurveEditorWL->show(); - curveEditorG->setCurveListener (this); + curveEditorG->setCurveListener(this); clshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_WAVELET_CURVEEDITOR_CL"))); clshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_CL_TOOLTIP")); @@ -815,54 +998,66 @@ Wavelet::Wavelet() : curveEditorG->curveListComplete(); - tmr->set_active (true); - tmr->set_tooltip_text (M("TP_WAVELET_BALCHRO_TOOLTIP")); - tmrConn = tmr->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::tmrToggled) ); + tmr->set_active(true); + tmr->set_tooltip_text(M("TP_WAVELET_BALCHRO_TOOLTIP")); + tmrConn = tmr->signal_toggled().connect(sigc::mem_fun(*this, &Wavelet::tmrToggled)); - ToolParamBlock* const finalBox = Gtk::manage (new ToolParamBlock()); + ToolParamBlock* const finalBox = Gtk::manage(new ToolParamBlock()); - finalBox->pack_start (*ctboxBA); + finalBox->pack_start(*ctboxBA); finalBox->pack_start(*balance); - finalBox->pack_start( *opacityCurveEditorW, Gtk::PACK_SHRINK, 2); + finalBox->pack_start(*opacityCurveEditorW, Gtk::PACK_SHRINK, 2); finalBox->pack_start(*iter); finalBox->pack_start(*tmr); finalBox->pack_start(*separatorbalend, Gtk::PACK_SHRINK, 2); - finalBox->pack_start( *opacityCurveEditorWL, Gtk::PACK_SHRINK, 2); + finalBox->pack_start(*opacityCurveEditorWL, Gtk::PACK_SHRINK, 2); - finalBox->pack_start (*curveEditorG, Gtk::PACK_SHRINK, 4); + finalBox->pack_start(*curveEditorG, Gtk::PACK_SHRINK, 4); + finalBox->pack_start(*softradend); //----------------------------- + + expsettings->add(*settingsBox, false); expsettings->setLevel(2); - pack_start (*expsettings); + pack_start(*expsettings); expcontrast->add(*levBox, false); expcontrast->setLevel(2); - pack_start (*expcontrast); + pack_start(*expcontrast); expchroma->add(*chBox, false); expchroma->setLevel(2); - pack_start (*expchroma); - - exptoning->add(*tonBox, false); - exptoning->setLevel(2); - pack_start (*exptoning); - - expnoise->add(*noiseBox, false); - expnoise->setLevel(2); - pack_start (*expnoise); - - expedge->add(*edgBox, false); - expedge->setLevel(2); - pack_start (*expedge); + pack_start(*expchroma); expgamut->add(*conBox, false); expgamut->setLevel(2); - pack_start (*expgamut); + pack_start(*expgamut); + + exptoning->add(*tonBox, false); + exptoning->setLevel(2); + pack_start(*exptoning); + + expnoise->add(*noiseBox, false); + expnoise->setLevel(2); + pack_start(*expnoise); + + expedge->add(*edgBox, false); + expedge->setLevel(2); + pack_start(*expedge); + + expbl->add(*blBox, false); + expbl->setLevel(2); + pack_start(*expbl); + + expclari->add(*clariBox, false); + expclari->setLevel(2); + pack_start(*expclari); + expresid->add(*resBox, false); expresid->setLevel(2); @@ -873,12 +1068,13 @@ Wavelet::Wavelet() : pack_start(*expfinal); } -Wavelet::~Wavelet () +Wavelet::~Wavelet() { idle_register.destroy(); delete opaCurveEditorG; delete opacityCurveEditorG; + delete curveEditorbl; delete CCWcurveEditorG; delete curveEditorRES; delete curveEditorGAM; @@ -888,27 +1084,26 @@ Wavelet::~Wavelet () } -void Wavelet::wavChanged (double nlevel) +void Wavelet::wavChanged(double nlevel) { if (!batchMode) { idle_register.add( - [this, nlevel]() -> bool - { - wavLabels->set_text( - Glib::ustring::compose( - M("TP_WAVELET_LEVLABEL"), - Glib::ustring::format(std::fixed, std::setprecision(0), nlevel) - ) - ); - return false; - } + [this, nlevel]() -> bool { + wavLabels->set_text( + Glib::ustring::compose( + M("TP_WAVELET_LEVLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), nlevel) + ) + ); + return false; + } ); } } // Will only reset the channel mixer // WARNING! In mutiImage mode, and for sliders in ADD mode, this will reset the slider to 0, but not to the default value as in SET mode. -void Wavelet::neutral_pressed () +void Wavelet::neutral_pressed() { disableListener(); greenlow->resetValue(false); @@ -921,11 +1116,11 @@ void Wavelet::neutral_pressed () enableListener(); if (listener && getEnabled()) { - listener->panelChanged (EvWavNeutral, M("GENERAL_RESET")); + listener->panelChanged(EvWavNeutral, M("GENERAL_RESET")); } } -void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) +void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) { /***************************************************************************************************** @@ -934,7 +1129,7 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) * *****************************************************************************************************/ - disableListener (); + disableListener(); Lmethodconn.block(true); CLmethodconn.block(true); Backmethodconn.block(true); @@ -949,6 +1144,7 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) TMmethodconn.block(true); HSmethodconn.block(true); MedgreinfConn.block(true); + ushamethodconn.block(true); cbenabConn.block(true); enableChromaConn.block(true); enableContrastConn.block(true); @@ -966,65 +1162,75 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) //HSmethod->set_active (1); // Note: default values are controlled in rtengine::ProcParams::SetDefaults if (pp->wavelet.HSmethod == "without") { - HSmethod->set_active (0); + HSmethod->set_active(0); } else if (pp->wavelet.HSmethod == "with") { - HSmethod->set_active (1); + HSmethod->set_active(1); } //CHmethod->set_active (1); if (pp->wavelet.CHmethod == "without") { - CHmethod->set_active (0); + CHmethod->set_active(0); } else if (pp->wavelet.CHmethod == "with") { - CHmethod->set_active (1); + CHmethod->set_active(1); } else if (pp->wavelet.CHmethod == "link") { - CHmethod->set_active (2); + CHmethod->set_active(2); } //Medgreinf->set_active (1); if (pp->wavelet.Medgreinf == "more") { - Medgreinf->set_active (0); + Medgreinf->set_active(0); } else if (pp->wavelet.Medgreinf == "none") { - Medgreinf->set_active (1); + Medgreinf->set_active(1); } else if (pp->wavelet.Medgreinf == "less") { - Medgreinf->set_active (2); + Medgreinf->set_active(2); + } + + //ushamethod +// if (pp->wavelet.ushamethod == "none") { +// ushamethod->set_active(0); +// } else + if (pp->wavelet.ushamethod == "sharp") { + ushamethod->set_active(0); + } else if (pp->wavelet.ushamethod == "clari") { + ushamethod->set_active(1); } //CHSLmethod->set_active (1); if (pp->wavelet.CHSLmethod == "SL") { - CHSLmethod->set_active (0); + CHSLmethod->set_active(0); } else if (pp->wavelet.CHSLmethod == "CU") { - CHSLmethod->set_active (1); + CHSLmethod->set_active(1); } //EDmethod->set_active (1); if (pp->wavelet.EDmethod == "SL") { - EDmethod->set_active (0); + EDmethod->set_active(0); } else if (pp->wavelet.EDmethod == "CU") { - EDmethod->set_active (1); + EDmethod->set_active(1); } if (pp->wavelet.NPmethod == "none") { - NPmethod->set_active (0); + NPmethod->set_active(0); } else if (pp->wavelet.NPmethod == "low") { - NPmethod->set_active (1); + NPmethod->set_active(1); } else if (pp->wavelet.NPmethod == "high") { - NPmethod->set_active (2); + NPmethod->set_active(2); } //BAmethod->set_active (0); if (pp->wavelet.BAmethod == "none") { - BAmethod->set_active (0); + BAmethod->set_active(0); } else if (pp->wavelet.BAmethod == "sli") { - BAmethod->set_active (1); + BAmethod->set_active(1); } else if (pp->wavelet.BAmethod == "cur") { - BAmethod->set_active (2); + BAmethod->set_active(2); } //TMmethod->set_active (1); if (pp->wavelet.TMmethod == "cont") { - TMmethod->set_active (0); + TMmethod->set_active(0); } else if (pp->wavelet.TMmethod == "tm") { - TMmethod->set_active (1); + TMmethod->set_active(1); } // else if (pp->wavelet.TMmethod=="both") @@ -1032,99 +1238,108 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) //Backmethod->set_active (3); if (pp->wavelet.Backmethod == "black") { - Backmethod->set_active (0); + Backmethod->set_active(0); } else if (pp->wavelet.Backmethod == "grey") { - Backmethod->set_active (1); + Backmethod->set_active(1); } else if (pp->wavelet.Backmethod == "resid") { - Backmethod->set_active (2); + Backmethod->set_active(2); } //CLmethod->set_active (3); if (pp->wavelet.CLmethod == "one") { - CLmethod->set_active (0); + CLmethod->set_active(0); } else if (pp->wavelet.CLmethod == "inf") { - CLmethod->set_active (1); + CLmethod->set_active(1); } else if (pp->wavelet.CLmethod == "sup") { - CLmethod->set_active (2); + CLmethod->set_active(2); } else if (pp->wavelet.CLmethod == "all") { - CLmethod->set_active (3); + CLmethod->set_active(3); } //Tilesmethod->set_active (2); if (pp->wavelet.Tilesmethod == "full") { - Tilesmethod->set_active (0); + Tilesmethod->set_active(0); } else if (pp->wavelet.Tilesmethod == "big") { - Tilesmethod->set_active (1); - } else if (pp->wavelet.Tilesmethod == "lit") { - Tilesmethod->set_active (2); + Tilesmethod->set_active(1); +// } else if (pp->wavelet.Tilesmethod == "lit") { +// Tilesmethod->set_active(2); } //daubcoeffmethod->set_active (4); if (pp->wavelet.daubcoeffmethod == "2_") { - daubcoeffmethod->set_active (0); + daubcoeffmethod->set_active(0); } else if (pp->wavelet.daubcoeffmethod == "4_") { - daubcoeffmethod->set_active (1); + daubcoeffmethod->set_active(1); } else if (pp->wavelet.daubcoeffmethod == "6_") { - daubcoeffmethod->set_active (2); + daubcoeffmethod->set_active(2); } else if (pp->wavelet.daubcoeffmethod == "10_") { - daubcoeffmethod->set_active (3); + daubcoeffmethod->set_active(3); } else if (pp->wavelet.daubcoeffmethod == "14_") { - daubcoeffmethod->set_active (4); + daubcoeffmethod->set_active(4); } //Dirmethod->set_active (3); if (pp->wavelet.Dirmethod == "one") { - Dirmethod->set_active (0); + Dirmethod->set_active(0); } else if (pp->wavelet.Dirmethod == "two") { - Dirmethod->set_active (1); + Dirmethod->set_active(1); } else if (pp->wavelet.Dirmethod == "thr") { - Dirmethod->set_active (2); + Dirmethod->set_active(2); } else if (pp->wavelet.Dirmethod == "all") { - Dirmethod->set_active (3); + Dirmethod->set_active(3); } int selectedLevel = pp->wavelet.Lmethod - 1; - Lmethod->set_active (selectedLevel == -1 ? 4 : selectedLevel); + Lmethod->set_active(selectedLevel == -1 ? 4 : selectedLevel); - ccshape->setCurve (pp->wavelet.ccwcurve); - opacityShapeRG->setCurve (pp->wavelet.opacityCurveRG); - opacityShapeBY->setCurve (pp->wavelet.opacityCurveBY); - opacityShape->setCurve (pp->wavelet.opacityCurveW); - opacityShapeWL->setCurve (pp->wavelet.opacityCurveWL); - hhshape->setCurve (pp->wavelet.hhcurve); - Chshape->setCurve (pp->wavelet.Chcurve); - clshape->setCurve (pp->wavelet.wavclCurve); - expcontrast->setEnabled (pp->wavelet.expcontrast); - expchroma->setEnabled (pp->wavelet.expchroma); - expedge->setEnabled (pp->wavelet.expedge); - expresid->setEnabled (pp->wavelet.expresid); - expfinal->setEnabled (pp->wavelet.expfinal); - exptoning->setEnabled (pp->wavelet.exptoning); - expnoise->setEnabled (pp->wavelet.expnoise); + ccshape->setCurve(pp->wavelet.ccwcurve); + blshape->setCurve(pp->wavelet.blcurve); + opacityShapeRG->setCurve(pp->wavelet.opacityCurveRG); + opacityShapeBY->setCurve(pp->wavelet.opacityCurveBY); + opacityShape->setCurve(pp->wavelet.opacityCurveW); + opacityShapeWL->setCurve(pp->wavelet.opacityCurveWL); + hhshape->setCurve(pp->wavelet.hhcurve); + Chshape->setCurve(pp->wavelet.Chcurve); + clshape->setCurve(pp->wavelet.wavclCurve); + expcontrast->setEnabled(pp->wavelet.expcontrast); + expchroma->setEnabled(pp->wavelet.expchroma); + expedge->setEnabled(pp->wavelet.expedge); + expbl->setEnabled(pp->wavelet.expbl); + expresid->setEnabled(pp->wavelet.expresid); + expfinal->setEnabled(pp->wavelet.expfinal); + exptoning->setEnabled(pp->wavelet.exptoning); + expnoise->setEnabled(pp->wavelet.expnoise); + expclari->setEnabled(pp->wavelet.expclari); setEnabled(pp->wavelet.enabled); - avoidConn.block (true); - avoid->set_active (pp->wavelet.avoid); - avoidConn.block (false); - tmrConn.block (true); - tmr->set_active (pp->wavelet.tmr); - tmrConn.block (false); - medianConn.block (true); - median->set_active (pp->wavelet.median); - medianConn.block (false); - medianlevConn.block (true); - medianlev->set_active (pp->wavelet.medianlev); - medianlevConn.block (false); - linkedgConn.block (true); - linkedg->set_active (pp->wavelet.linkedg); - linkedgConn.block (false); - cbenabConn.block (true); - cbenab->set_active (pp->wavelet.cbenab); - cbenabConn.block (false); + avoidConn.block(true); + avoid->set_active(pp->wavelet.avoid); + avoidConn.block(false); + showmaskConn.block(true); + showmask->set_active(pp->wavelet.showmask); + showmaskConn.block(false); + oldshConn.block(true); + oldsh->set_active(pp->wavelet.oldsh); + oldshConn.block(false); + tmrConn.block(true); + tmr->set_active(pp->wavelet.tmr); + tmrConn.block(false); + medianConn.block(true); + median->set_active(pp->wavelet.median); + medianConn.block(false); + medianlevConn.block(true); + medianlev->set_active(pp->wavelet.medianlev); + medianlevConn.block(false); + linkedgConn.block(true); + linkedg->set_active(pp->wavelet.linkedg); + linkedgConn.block(false); + cbenabConn.block(true); + cbenab->set_active(pp->wavelet.cbenab); + cbenabConn.block(false); - lipstConn.block (true); - lipst->set_active (pp->wavelet.lipst); - lipstConn.block (false); + lipstConn.block(true); + lipst->set_active(pp->wavelet.lipst); + lipstConn.block(false); //edgreinfConn.block (true); //edgreinf->set_active (pp->wavelet.edgreinf); //edgreinfConn.block (false); @@ -1135,23 +1350,34 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) lastcbenab = pp->wavelet.cbenab; lastlipst = pp->wavelet.lipst; lastavoid = pp->wavelet.avoid; + lastshowmask = pp->wavelet.showmask; + lastoldsh = pp->wavelet.oldsh; lasttmr = pp->wavelet.tmr; - rescon->setValue (pp->wavelet.rescon); - resconH->setValue (pp->wavelet.resconH); - reschro->setValue (pp->wavelet.reschro); - tmrs->setValue (pp->wavelet.tmrs); - gamma->setValue (pp->wavelet.gamma); - sup->setValue (pp->wavelet.sup); - sky->setValue (pp->wavelet.sky); - thres->setValue (pp->wavelet.thres); - chroma->setValue (pp->wavelet.chroma); - chro->setValue (pp->wavelet.chro); - contrast->setValue (pp->wavelet.contrast); - edgrad->setValue (pp->wavelet.edgrad); - edgval->setValue (pp->wavelet.edgval); - edgthresh->setValue (pp->wavelet.edgthresh); - thr->setValue (pp->wavelet.thr); - thrH->setValue (pp->wavelet.thrH); + sigma->setValue(pp->wavelet.sigma); + offset->setValue(pp->wavelet.offset); + lowthr->setValue(pp->wavelet.lowthr); + rescon->setValue(pp->wavelet.rescon); + resconH->setValue(pp->wavelet.resconH); + reschro->setValue(pp->wavelet.reschro); + resblur->setValue(pp->wavelet.resblur); + resblurc->setValue(pp->wavelet.resblurc); + tmrs->setValue(pp->wavelet.tmrs); + edgs->setValue(pp->wavelet.edgs); + scale->setValue(pp->wavelet.scale); + gamma->setValue(pp->wavelet.gamma); + sup->setValue(pp->wavelet.sup); + sky->setValue(pp->wavelet.sky); + thres->setValue(pp->wavelet.thres); + chroma->setValue(pp->wavelet.chroma); + chro->setValue(pp->wavelet.chro); + contrast->setValue(pp->wavelet.contrast); + edgrad->setValue(pp->wavelet.edgrad); + edgeffect->setValue(pp->wavelet.edgeffect); + edgval->setValue(pp->wavelet.edgval); + edgthresh->setValue(pp->wavelet.edgthresh); + thr->setValue(pp->wavelet.thr); + thrH->setValue(pp->wavelet.thrH); + radius->setValue(pp->wavelet.radius); skinprotect->setValue(pp->wavelet.skinprotect); hueskin->setValue(pp->wavelet.hueskin); hueskin2->setValue(pp->wavelet.hueskin2); @@ -1167,14 +1393,24 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) pastlev->setValue(pp->wavelet.pastlev); satlev->setValue(pp->wavelet.satlev); edgcont->setValue(pp->wavelet.edgcont); + chrwav->setValue(pp->wavelet.chrwav); + bluwav->setValue(pp->wavelet.bluwav); - greenlow->setValue (pp->wavelet.greenlow); - bluelow->setValue (pp->wavelet.bluelow); - greenmed->setValue (pp->wavelet.greenmed); - bluemed->setValue (pp->wavelet.bluemed); - greenhigh->setValue (pp->wavelet.greenhigh); - bluehigh->setValue (pp->wavelet.bluehigh); + greenlow->setValue(pp->wavelet.greenlow); + bluelow->setValue(pp->wavelet.bluelow); + greenmed->setValue(pp->wavelet.greenmed); + bluemed->setValue(pp->wavelet.bluemed); + greenhigh->setValue(pp->wavelet.greenhigh); + bluehigh->setValue(pp->wavelet.bluehigh); + mergeL->setValue(pp->wavelet.mergeL); + mergeC->setValue(pp->wavelet.mergeC); + softrad->setValue(pp->wavelet.softrad); + softradend->setValue(pp->wavelet.softradend); + ballum->setValue(pp->wavelet.ballum); + balchrom->setValue(pp->wavelet.balchrom); + chromfi->setValue(pp->wavelet.chromfi); + chromco->setValue(pp->wavelet.chromco); level0noise->setValue(pp->wavelet.level0noise); level1noise->setValue(pp->wavelet.level1noise); level2noise->setValue(pp->wavelet.level2noise); @@ -1254,83 +1490,112 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) Medgreinf->set_active_text(M("GENERAL_UNCHANGED")); } - set_inconsistent (multiImage && !pedited->wavelet.enabled); - ccshape->setUnChanged (!pedited->wavelet.ccwcurve); - expcontrast->set_inconsistent (!pedited->wavelet.expcontrast); - expchroma->set_inconsistent (!pedited->wavelet.expchroma); - expedge->set_inconsistent (!pedited->wavelet.expedge); - expresid->set_inconsistent (!pedited->wavelet.expresid); - expfinal->set_inconsistent (!pedited->wavelet.expfinal); - exptoning->set_inconsistent (!pedited->wavelet.exptoning); - expnoise->set_inconsistent (!pedited->wavelet.expnoise); - opacityShapeRG->setCurve (pp->wavelet.opacityCurveRG); - opacityShapeBY->setCurve (pp->wavelet.opacityCurveBY); - opacityShape->setCurve (pp->wavelet.opacityCurveW); - opacityShapeWL->setCurve (pp->wavelet.opacityCurveWL); - hhshape->setUnChanged (!pedited->wavelet.hhcurve); - Chshape->setUnChanged (!pedited->wavelet.Chcurve); - clshape->setUnChanged (!pedited->wavelet.wavclCurve); - avoid->set_inconsistent (!pedited->wavelet.avoid); - tmr->set_inconsistent (!pedited->wavelet.tmr); - edgthresh->setEditedState (pedited->wavelet.edgthresh ? Edited : UnEdited); - rescon->setEditedState (pedited->wavelet.rescon ? Edited : UnEdited); - resconH->setEditedState (pedited->wavelet.resconH ? Edited : UnEdited); - reschro->setEditedState (pedited->wavelet.reschro ? Edited : UnEdited); - tmrs->setEditedState (pedited->wavelet.tmrs ? Edited : UnEdited); - gamma->setEditedState (pedited->wavelet.gamma ? Edited : UnEdited); - sup->setEditedState (pedited->wavelet.sup ? Edited : UnEdited); - sky->setEditedState (pedited->wavelet.sky ? Edited : UnEdited); - thres->setEditedState (pedited->wavelet.thres ? Edited : UnEdited); - balance->setEditedState (pedited->wavelet.balance ? Edited : UnEdited); - iter->setEditedState (pedited->wavelet.iter ? Edited : UnEdited); - threshold->setEditedState (pedited->wavelet.threshold ? Edited : UnEdited); - threshold2->setEditedState (pedited->wavelet.threshold2 ? Edited : UnEdited); - edgedetect->setEditedState (pedited->wavelet.edgedetect ? Edited : UnEdited); - edgedetectthr->setEditedState (pedited->wavelet.edgedetectthr ? Edited : UnEdited); - edgedetectthr2->setEditedState (pedited->wavelet.edgedetectthr2 ? Edited : UnEdited); - edgesensi->setEditedState (pedited->wavelet.edgesensi ? Edited : UnEdited); - edgeampli->setEditedState (pedited->wavelet.edgeampli ? Edited : UnEdited); - chroma->setEditedState (pedited->wavelet.chroma ? Edited : UnEdited); - chro->setEditedState (pedited->wavelet.chro ? Edited : UnEdited); - - greenlow->setEditedState (pedited->wavelet.greenlow ? Edited : UnEdited); - bluelow->setEditedState (pedited->wavelet.bluelow ? Edited : UnEdited); - greenmed->setEditedState (pedited->wavelet.greenmed ? Edited : UnEdited); - bluemed->setEditedState (pedited->wavelet.bluemed ? Edited : UnEdited); - greenhigh->setEditedState (pedited->wavelet.greenhigh ? Edited : UnEdited); - bluehigh->setEditedState (pedited->wavelet.bluehigh ? Edited : UnEdited); - - median->set_inconsistent (!pedited->wavelet.median); - medianlev->set_inconsistent (!pedited->wavelet.medianlev); - linkedg->set_inconsistent (!pedited->wavelet.linkedg); -// edgreinf->set_inconsistent (!pedited->wavelet.edgreinf); - cbenab->set_inconsistent (!pedited->wavelet.cbenab); - lipst->set_inconsistent (!pedited->wavelet.lipst); - contrast->setEditedState (pedited->wavelet.contrast ? Edited : UnEdited); - edgrad->setEditedState (pedited->wavelet.edgrad ? Edited : UnEdited); - edgval->setEditedState (pedited->wavelet.edgval ? Edited : UnEdited); - thr->setEditedState (pedited->wavelet.thr ? Edited : UnEdited); - thrH->setEditedState (pedited->wavelet.thrH ? Edited : UnEdited); - skinprotect->setEditedState (pedited->wavelet.skinprotect ? Edited : UnEdited); - hueskin->setEditedState (pedited->wavelet.hueskin ? Edited : UnEdited); - hueskin2->setEditedState (pedited->wavelet.hueskin2 ? Edited : UnEdited); - hllev->setEditedState (pedited->wavelet.hllev ? Edited : UnEdited); - bllev->setEditedState (pedited->wavelet.bllev ? Edited : UnEdited); - pastlev->setEditedState (pedited->wavelet.pastlev ? Edited : UnEdited); - satlev->setEditedState (pedited->wavelet.satlev ? Edited : UnEdited); - strength->setEditedState(pedited->wavelet.strength ? Edited : UnEdited); - edgcont->setEditedState (pedited->wavelet.edgcont ? Edited : UnEdited); - level0noise->setEditedState (pedited->wavelet.level0noise ? Edited : UnEdited); - level1noise->setEditedState (pedited->wavelet.level1noise ? Edited : UnEdited); - level2noise->setEditedState (pedited->wavelet.level2noise ? Edited : UnEdited); - level3noise->setEditedState (pedited->wavelet.level3noise ? Edited : UnEdited); - - for(int i = 0; i < 9; i++) { - correction[i]->setEditedState (pedited->wavelet.c[i] ? Edited : UnEdited); + if (!pedited->wavelet.ushamethod) { + ushamethod->set_active_text(M("GENERAL_UNCHANGED")); } - for(int i = 0; i < 9; i++) { - correctionch[i]->setEditedState (pedited->wavelet.ch[i] ? Edited : UnEdited); + set_inconsistent(multiImage && !pedited->wavelet.enabled); + ccshape->setUnChanged(!pedited->wavelet.ccwcurve); + blshape->setUnChanged(!pedited->wavelet.blcurve); + expcontrast->set_inconsistent(!pedited->wavelet.expcontrast); + expchroma->set_inconsistent(!pedited->wavelet.expchroma); + expedge->set_inconsistent(!pedited->wavelet.expedge); + expbl->set_inconsistent(!pedited->wavelet.expbl); + expresid->set_inconsistent(!pedited->wavelet.expresid); + expfinal->set_inconsistent(!pedited->wavelet.expfinal); + expclari->set_inconsistent(!pedited->wavelet.expclari); + exptoning->set_inconsistent(!pedited->wavelet.exptoning); + expnoise->set_inconsistent(!pedited->wavelet.expnoise); + opacityShapeRG->setCurve(pp->wavelet.opacityCurveRG); + opacityShapeBY->setCurve(pp->wavelet.opacityCurveBY); + opacityShape->setCurve(pp->wavelet.opacityCurveW); + opacityShapeWL->setCurve(pp->wavelet.opacityCurveWL); + hhshape->setUnChanged(!pedited->wavelet.hhcurve); + Chshape->setUnChanged(!pedited->wavelet.Chcurve); + clshape->setUnChanged(!pedited->wavelet.wavclCurve); + avoid->set_inconsistent(!pedited->wavelet.avoid); + showmask->set_inconsistent(!pedited->wavelet.showmask); + oldsh->set_inconsistent(!pedited->wavelet.oldsh); + tmr->set_inconsistent(!pedited->wavelet.tmr); + edgthresh->setEditedState(pedited->wavelet.edgthresh ? Edited : UnEdited); + rescon->setEditedState(pedited->wavelet.rescon ? Edited : UnEdited); + sigma->setEditedState(pedited->wavelet.sigma ? Edited : UnEdited); + offset->setEditedState(pedited->wavelet.offset ? Edited : UnEdited); + lowthr->setEditedState(pedited->wavelet.lowthr ? Edited : UnEdited); + resconH->setEditedState(pedited->wavelet.resconH ? Edited : UnEdited); + reschro->setEditedState(pedited->wavelet.reschro ? Edited : UnEdited); + resblur->setEditedState(pedited->wavelet.resblur ? Edited : UnEdited); + resblurc->setEditedState(pedited->wavelet.resblurc ? Edited : UnEdited); + tmrs->setEditedState(pedited->wavelet.tmrs ? Edited : UnEdited); + edgs->setEditedState(pedited->wavelet.edgs ? Edited : UnEdited); + scale->setEditedState(pedited->wavelet.scale ? Edited : UnEdited); + gamma->setEditedState(pedited->wavelet.gamma ? Edited : UnEdited); + sup->setEditedState(pedited->wavelet.sup ? Edited : UnEdited); + sky->setEditedState(pedited->wavelet.sky ? Edited : UnEdited); + thres->setEditedState(pedited->wavelet.thres ? Edited : UnEdited); + balance->setEditedState(pedited->wavelet.balance ? Edited : UnEdited); + iter->setEditedState(pedited->wavelet.iter ? Edited : UnEdited); + threshold->setEditedState(pedited->wavelet.threshold ? Edited : UnEdited); + threshold2->setEditedState(pedited->wavelet.threshold2 ? Edited : UnEdited); + edgedetect->setEditedState(pedited->wavelet.edgedetect ? Edited : UnEdited); + edgedetectthr->setEditedState(pedited->wavelet.edgedetectthr ? Edited : UnEdited); + edgedetectthr2->setEditedState(pedited->wavelet.edgedetectthr2 ? Edited : UnEdited); + edgesensi->setEditedState(pedited->wavelet.edgesensi ? Edited : UnEdited); + edgeampli->setEditedState(pedited->wavelet.edgeampli ? Edited : UnEdited); + chroma->setEditedState(pedited->wavelet.chroma ? Edited : UnEdited); + chro->setEditedState(pedited->wavelet.chro ? Edited : UnEdited); + + greenlow->setEditedState(pedited->wavelet.greenlow ? Edited : UnEdited); + bluelow->setEditedState(pedited->wavelet.bluelow ? Edited : UnEdited); + greenmed->setEditedState(pedited->wavelet.greenmed ? Edited : UnEdited); + bluemed->setEditedState(pedited->wavelet.bluemed ? Edited : UnEdited); + greenhigh->setEditedState(pedited->wavelet.greenhigh ? Edited : UnEdited); + bluehigh->setEditedState(pedited->wavelet.bluehigh ? Edited : UnEdited); + mergeL->setEditedState(pedited->wavelet.mergeL ? Edited : UnEdited); + mergeC->setEditedState(pedited->wavelet.mergeC ? Edited : UnEdited); + softrad->setEditedState(pedited->wavelet.softrad ? Edited : UnEdited); + softradend->setEditedState(pedited->wavelet.softradend ? Edited : UnEdited); + + ballum->setEditedState(pedited->wavelet.ballum ? Edited : UnEdited); + balchrom->setEditedState(pedited->wavelet.balchrom ? Edited : UnEdited); + chromfi->setEditedState(pedited->wavelet.chromfi ? Edited : UnEdited); + chromco->setEditedState(pedited->wavelet.chromco ? Edited : UnEdited); + + median->set_inconsistent(!pedited->wavelet.median); + medianlev->set_inconsistent(!pedited->wavelet.medianlev); + linkedg->set_inconsistent(!pedited->wavelet.linkedg); +// edgreinf->set_inconsistent (!pedited->wavelet.edgreinf); + cbenab->set_inconsistent(!pedited->wavelet.cbenab); + lipst->set_inconsistent(!pedited->wavelet.lipst); + contrast->setEditedState(pedited->wavelet.contrast ? Edited : UnEdited); + edgrad->setEditedState(pedited->wavelet.edgrad ? Edited : UnEdited); + edgeffect->setEditedState(pedited->wavelet.edgeffect ? Edited : UnEdited); + edgval->setEditedState(pedited->wavelet.edgval ? Edited : UnEdited); + thr->setEditedState(pedited->wavelet.thr ? Edited : UnEdited); + thrH->setEditedState(pedited->wavelet.thrH ? Edited : UnEdited); + radius->setEditedState(pedited->wavelet.radius ? Edited : UnEdited); + skinprotect->setEditedState(pedited->wavelet.skinprotect ? Edited : UnEdited); + hueskin->setEditedState(pedited->wavelet.hueskin ? Edited : UnEdited); + hueskin2->setEditedState(pedited->wavelet.hueskin2 ? Edited : UnEdited); + hllev->setEditedState(pedited->wavelet.hllev ? Edited : UnEdited); + bllev->setEditedState(pedited->wavelet.bllev ? Edited : UnEdited); + pastlev->setEditedState(pedited->wavelet.pastlev ? Edited : UnEdited); + satlev->setEditedState(pedited->wavelet.satlev ? Edited : UnEdited); + strength->setEditedState(pedited->wavelet.strength ? Edited : UnEdited); + edgcont->setEditedState(pedited->wavelet.edgcont ? Edited : UnEdited); + chrwav->setEditedState(pedited->wavelet.chrwav ? Edited : UnEdited); + bluwav->setEditedState(pedited->wavelet.bluwav ? Edited : UnEdited); + level0noise->setEditedState(pedited->wavelet.level0noise ? Edited : UnEdited); + level1noise->setEditedState(pedited->wavelet.level1noise ? Edited : UnEdited); + level2noise->setEditedState(pedited->wavelet.level2noise ? Edited : UnEdited); + level3noise->setEditedState(pedited->wavelet.level3noise ? Edited : UnEdited); + + for (int i = 0; i < 9; i++) { + correction[i]->setEditedState(pedited->wavelet.c[i] ? Edited : UnEdited); + } + + for (int i = 0; i < 9; i++) { + correctionch[i]->setEditedState(pedited->wavelet.ch[i] ? Edited : UnEdited); } } @@ -1345,20 +1610,20 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) y = thres->getValue(); int z; - for(z = y; z < 9; z++) { + for (z = y; z < 9; z++) { correction[z]->hide(); } - for(z = 0; z < y; z++) { + for (z = 0; z < y; z++) { correction[z]->show(); } if (pp->wavelet.CHSLmethod == "SL") { - for(z = y; z < 9; z++) { + for (z = y; z < 9; z++) { correctionch[z]->hide(); } - for(z = 0; z < y; z++) { + for (z = 0; z < y; z++) { correctionch[z]->show(); } } @@ -1374,16 +1639,17 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) TMmethodUpdateUI(); //BackmethodUpdateUI(); CLmethodUpdateUI(); - lipstUpdateUI (); + lipstUpdateUI(); + oldshToggled(); //TilesmethodUpdateUI(); //daubcoeffmethodUpdateUI(); //DirmethodUpdateUI(); //LmethodUpdateUI(); - enabledUpdateUI (); - medianlevUpdateUI (); - cbenabUpdateUI (); + enabledUpdateUI(); + medianlevUpdateUI(); + cbenabUpdateUI(); - if(z == 9) { + if (z == 9) { sup->show(); } else { sup->hide(); @@ -1410,6 +1676,7 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) HSmethodconn.block(false); Dirmethodconn.block(false); MedgreinfConn.block(false); + ushamethodconn.block(false); enableChromaConn.block(false); enableContrastConn.block(false); enableEdgeConn.block(false); @@ -1418,12 +1685,13 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) enableResidConn.block(false); enableToningConn.block(false); - enableListener (); + enableListener(); } -void Wavelet::setEditProvider (EditDataProvider *provider) +void Wavelet::setEditProvider(EditDataProvider *provider) { ccshape->setEditProvider(provider); + blshape->setEditProvider(provider); opacityShapeRG->setEditProvider(provider); opacityShapeBY->setEditProvider(provider); opacityShape->setEditProvider(provider); @@ -1433,41 +1701,53 @@ void Wavelet::setEditProvider (EditDataProvider *provider) clshape->setEditProvider(provider); } -void Wavelet::autoOpenCurve () +void Wavelet::autoOpenCurve() { ccshape->openIfNonlinear(); + blshape->openIfNonlinear(); //opacityShapeRG->openIfNonlinear(); //opacityShapeBY->openIfNonlinear(); } -void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) +void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) { pp->wavelet.enabled = getEnabled(); - pp->wavelet.avoid = avoid->get_active (); - pp->wavelet.tmr = tmr->get_active (); + pp->wavelet.avoid = avoid->get_active(); + pp->wavelet.showmask = showmask->get_active(); + pp->wavelet.oldsh = oldsh->get_active(); + pp->wavelet.tmr = tmr->get_active(); + pp->wavelet.sigma = sigma->getValue(); + pp->wavelet.offset = offset->getValue(); + pp->wavelet.lowthr = lowthr->getValue(); pp->wavelet.rescon = rescon->getValue(); pp->wavelet.resconH = resconH->getValue(); pp->wavelet.reschro = reschro->getValue(); + pp->wavelet.resblur = resblur->getValue(); + pp->wavelet.resblurc = resblurc->getValue(); pp->wavelet.tmrs = tmrs->getValue(); + pp->wavelet.edgs = edgs->getValue(); + pp->wavelet.scale = scale->getValue(); pp->wavelet.gamma = gamma->getValue(); pp->wavelet.sup = sup->getValue(); pp->wavelet.sky = sky->getValue(); pp->wavelet.thres = thres->getValue(); pp->wavelet.chroma = chroma->getValue(); pp->wavelet.chro = chro->getValue(); - pp->wavelet.median = median->get_active (); - pp->wavelet.medianlev = medianlev->get_active (); - pp->wavelet.linkedg = linkedg->get_active (); + pp->wavelet.median = median->get_active(); + pp->wavelet.medianlev = medianlev->get_active(); + pp->wavelet.linkedg = linkedg->get_active(); // pp->wavelet.edgreinf = edgreinf->get_active (); - pp->wavelet.cbenab = cbenab->get_active (); - pp->wavelet.lipst = lipst->get_active (); + pp->wavelet.cbenab = cbenab->get_active(); + pp->wavelet.lipst = lipst->get_active(); pp->wavelet.contrast = contrast->getValue(); pp->wavelet.edgrad = edgrad->getValue(); + pp->wavelet.edgeffect = edgeffect->getValue(); pp->wavelet.edgval = edgval->getValue(); pp->wavelet.edgthresh = edgthresh->getValue(); pp->wavelet.thr = thr->getValue(); pp->wavelet.thrH = thrH->getValue(); + pp->wavelet.radius = radius->getValue(); pp->wavelet.hueskin = hueskin->getValue (); pp->wavelet.hueskin2 = hueskin2->getValue (); pp->wavelet.skinprotect = skinprotect->getValue(); @@ -1481,38 +1761,51 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) pp->wavelet.hllev = hllev->getValue (); pp->wavelet.bllev = bllev->getValue (); pp->wavelet.edgcont = edgcont->getValue (); + pp->wavelet.chrwav = chrwav->getValue(); + pp->wavelet.bluwav = bluwav->getValue(); pp->wavelet.level0noise = level0noise->getValue (); pp->wavelet.level1noise = level1noise->getValue (); pp->wavelet.level2noise = level2noise->getValue (); pp->wavelet.level3noise = level3noise->getValue (); - pp->wavelet.ccwcurve = ccshape->getCurve (); - pp->wavelet.opacityCurveRG = opacityShapeRG->getCurve (); - pp->wavelet.opacityCurveBY = opacityShapeBY->getCurve (); - pp->wavelet.opacityCurveW = opacityShape->getCurve (); - pp->wavelet.opacityCurveWL = opacityShapeWL->getCurve (); - pp->wavelet.hhcurve = hhshape->getCurve (); - pp->wavelet.Chcurve = Chshape->getCurve (); + pp->wavelet.ccwcurve = ccshape->getCurve(); + pp->wavelet.blcurve = blshape->getCurve(); + pp->wavelet.opacityCurveRG = opacityShapeRG->getCurve(); + pp->wavelet.opacityCurveBY = opacityShapeBY->getCurve(); + pp->wavelet.opacityCurveW = opacityShape->getCurve(); + pp->wavelet.opacityCurveWL = opacityShapeWL->getCurve(); + pp->wavelet.hhcurve = hhshape->getCurve(); + pp->wavelet.Chcurve = Chshape->getCurve(); pp->wavelet.pastlev = pastlev->getValue (); pp->wavelet.satlev = satlev->getValue (); pp->wavelet.strength = (int) strength->getValue(); pp->wavelet.balance = (int) balance->getValue(); + pp->wavelet.balchrom = balchrom->getValue(); + pp->wavelet.ballum = ballum->getValue(); + pp->wavelet.chromfi = chromfi->getValue(); + pp->wavelet.chromco = chromco->getValue(); - pp->wavelet.greenlow = greenlow->getValue (); - pp->wavelet.bluelow = bluelow->getValue (); - pp->wavelet.greenmed = greenmed->getValue (); - pp->wavelet.bluemed = bluemed->getValue (); - pp->wavelet.greenhigh = greenhigh->getValue (); - pp->wavelet.bluehigh = bluehigh->getValue (); + pp->wavelet.greenlow = greenlow->getValue(); + pp->wavelet.bluelow = bluelow->getValue(); + pp->wavelet.greenmed = greenmed->getValue(); + pp->wavelet.bluemed = bluemed->getValue(); + pp->wavelet.greenhigh = greenhigh->getValue(); + pp->wavelet.bluehigh = bluehigh->getValue(); + pp->wavelet.mergeL = mergeL->getValue(); + pp->wavelet.mergeC = mergeC->getValue(); + pp->wavelet.softrad = softrad->getValue(); + pp->wavelet.softradend = softradend->getValue(); pp->wavelet.expcontrast = expcontrast->getEnabled(); pp->wavelet.expchroma = expchroma->getEnabled(); pp->wavelet.expedge = expedge->getEnabled(); + pp->wavelet.expbl = expbl->getEnabled(); pp->wavelet.expresid = expresid->getEnabled(); pp->wavelet.expfinal = expfinal->getEnabled(); pp->wavelet.exptoning = exptoning->getEnabled(); pp->wavelet.expnoise = expnoise->getEnabled(); + pp->wavelet.expclari = expclari->getEnabled(); pp->wavelet.iter = (int) iter->getValue(); - pp->wavelet.wavclCurve = clshape->getCurve (); + pp->wavelet.wavclCurve = clshape->getCurve(); for (int i = 0; i < 9; i++) { pp->wavelet.c[i] = (int) correction[i]->getValue(); @@ -1525,6 +1818,8 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) if (pedited) { pedited->wavelet.enabled = !get_inconsistent(); pedited->wavelet.avoid = !avoid->get_inconsistent(); + pedited->wavelet.showmask = !showmask->get_inconsistent(); + pedited->wavelet.oldsh = !oldsh->get_inconsistent(); pedited->wavelet.tmr = !tmr->get_inconsistent(); pedited->wavelet.median = !median->get_inconsistent(); pedited->wavelet.medianlev = !medianlev->get_inconsistent(); @@ -1532,6 +1827,7 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.cbenab = !cbenab->get_inconsistent(); pedited->wavelet.lipst = !lipst->get_inconsistent(); pedited->wavelet.Medgreinf = Medgreinf->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->wavelet.ushamethod = ushamethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.Lmethod = Lmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.CLmethod = CLmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.Backmethod = Backmethod->get_active_text() != M("GENERAL_UNCHANGED"); @@ -1546,10 +1842,17 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.HSmethod = HSmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.Dirmethod = Dirmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.edgthresh = edgthresh->getEditedState(); + pedited->wavelet.sigma = sigma->getEditedState(); + pedited->wavelet.offset = offset->getEditedState(); + pedited->wavelet.lowthr = lowthr->getEditedState(); pedited->wavelet.rescon = rescon->getEditedState(); pedited->wavelet.resconH = resconH->getEditedState(); pedited->wavelet.reschro = reschro->getEditedState(); + pedited->wavelet.resblur = resblur->getEditedState(); + pedited->wavelet.resblurc = resblurc->getEditedState(); pedited->wavelet.tmrs = tmrs->getEditedState(); + pedited->wavelet.edgs = edgs->getEditedState(); + pedited->wavelet.scale = scale->getEditedState(); pedited->wavelet.gamma = gamma->getEditedState(); pedited->wavelet.sup = sup->getEditedState(); pedited->wavelet.sky = sky->getEditedState(); @@ -1565,51 +1868,66 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.chro = chro->getEditedState(); pedited->wavelet.contrast = contrast->getEditedState(); pedited->wavelet.edgrad = edgrad->getEditedState(); + pedited->wavelet.edgeffect = edgeffect->getEditedState(); pedited->wavelet.edgval = edgval->getEditedState(); pedited->wavelet.thr = thr->getEditedState(); pedited->wavelet.thrH = thrH->getEditedState(); - pedited->wavelet.hueskin = hueskin->getEditedState (); - pedited->wavelet.hueskin2 = hueskin2->getEditedState (); + pedited->wavelet.radius = radius->getEditedState(); + pedited->wavelet.hueskin = hueskin->getEditedState(); + pedited->wavelet.hueskin2 = hueskin2->getEditedState(); pedited->wavelet.skinprotect = skinprotect->getEditedState(); - pedited->wavelet.hllev = hllev->getEditedState (); - pedited->wavelet.ccwcurve = !ccshape->isUnChanged (); - pedited->wavelet.edgcont = edgcont->getEditedState (); - pedited->wavelet.level0noise = level0noise->getEditedState (); - pedited->wavelet.level1noise = level1noise->getEditedState (); - pedited->wavelet.level2noise = level2noise->getEditedState (); - pedited->wavelet.level3noise = level3noise->getEditedState (); - pedited->wavelet.opacityCurveRG = !opacityShapeRG->isUnChanged (); - pedited->wavelet.opacityCurveBY = !opacityShapeBY->isUnChanged (); - pedited->wavelet.opacityCurveW = !opacityShape->isUnChanged (); - pedited->wavelet.opacityCurveWL = !opacityShapeWL->isUnChanged (); - pedited->wavelet.hhcurve = !hhshape->isUnChanged (); - pedited->wavelet.Chcurve = !Chshape->isUnChanged (); - pedited->wavelet.bllev = bllev->getEditedState (); - pedited->wavelet.pastlev = pastlev->getEditedState (); - pedited->wavelet.satlev = satlev->getEditedState (); - pedited->wavelet.strength = strength->getEditedState (); - pedited->wavelet.greenlow = greenlow->getEditedState (); - pedited->wavelet.bluelow = bluelow->getEditedState (); - pedited->wavelet.greenmed = greenmed->getEditedState (); - pedited->wavelet.bluemed = bluemed->getEditedState (); - pedited->wavelet.greenhigh = greenhigh->getEditedState (); - pedited->wavelet.bluehigh = bluehigh->getEditedState (); - pedited->wavelet.balance = balance->getEditedState (); - pedited->wavelet.iter = iter->getEditedState (); - pedited->wavelet.wavclCurve = !clshape->isUnChanged (); + pedited->wavelet.hllev = hllev->getEditedState(); + pedited->wavelet.ccwcurve = !ccshape->isUnChanged(); + pedited->wavelet.blcurve = !blshape->isUnChanged(); + pedited->wavelet.edgcont = edgcont->getEditedState(); + pedited->wavelet.chrwav = chrwav->getEditedState(); + pedited->wavelet.bluwav = bluwav->getEditedState(); + pedited->wavelet.level0noise = level0noise->getEditedState(); + pedited->wavelet.level1noise = level1noise->getEditedState(); + pedited->wavelet.level2noise = level2noise->getEditedState(); + pedited->wavelet.level3noise = level3noise->getEditedState(); + pedited->wavelet.opacityCurveRG = !opacityShapeRG->isUnChanged(); + pedited->wavelet.opacityCurveBY = !opacityShapeBY->isUnChanged(); + pedited->wavelet.opacityCurveW = !opacityShape->isUnChanged(); + pedited->wavelet.opacityCurveWL = !opacityShapeWL->isUnChanged(); + pedited->wavelet.hhcurve = !hhshape->isUnChanged(); + pedited->wavelet.Chcurve = !Chshape->isUnChanged(); + pedited->wavelet.bllev = bllev->getEditedState(); + pedited->wavelet.pastlev = pastlev->getEditedState(); + pedited->wavelet.satlev = satlev->getEditedState(); + pedited->wavelet.strength = strength->getEditedState(); + pedited->wavelet.greenlow = greenlow->getEditedState(); + pedited->wavelet.bluelow = bluelow->getEditedState(); + pedited->wavelet.greenmed = greenmed->getEditedState(); + pedited->wavelet.bluemed = bluemed->getEditedState(); + pedited->wavelet.greenhigh = greenhigh->getEditedState(); + pedited->wavelet.bluehigh = bluehigh->getEditedState(); + pedited->wavelet.ballum = ballum->getEditedState(); + pedited->wavelet.balchrom = balchrom->getEditedState(); + pedited->wavelet.chromfi = chromfi->getEditedState(); + pedited->wavelet.chromco = chromco->getEditedState(); + pedited->wavelet.mergeL = mergeL->getEditedState(); + pedited->wavelet.mergeC = mergeC->getEditedState(); + pedited->wavelet.softrad = softrad->getEditedState(); + pedited->wavelet.softradend = softradend->getEditedState(); + pedited->wavelet.balance = balance->getEditedState(); + pedited->wavelet.iter = iter->getEditedState(); + pedited->wavelet.wavclCurve = !clshape->isUnChanged(); pedited->wavelet.expcontrast = !expcontrast->get_inconsistent(); pedited->wavelet.expchroma = !expchroma->get_inconsistent(); pedited->wavelet.expedge = !expedge->get_inconsistent(); + pedited->wavelet.expbl = !expbl->get_inconsistent(); pedited->wavelet.expresid = !expresid->get_inconsistent(); pedited->wavelet.expfinal = !expfinal->get_inconsistent(); pedited->wavelet.exptoning = !exptoning->get_inconsistent(); pedited->wavelet.expnoise = !expnoise->get_inconsistent(); + pedited->wavelet.expclari = !expclari->get_inconsistent(); - for(int i = 0; i < 9; i++) { + for (int i = 0; i < 9; i++) { pedited->wavelet.c[i] = correction[i]->getEditedState(); } - for(int i = 0; i < 9; i++) { + for (int i = 0; i < 9; i++) { pedited->wavelet.ch[i] = correctionch[i]->getEditedState(); } @@ -1631,6 +1949,15 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) pp->wavelet.Medgreinf = "less"; } +// if (ushamethod->get_active_row_number() == 0) { +// pp->wavelet.ushamethod = "none"; +// } else + if (ushamethod->get_active_row_number() == 0) { + pp->wavelet.ushamethod = "sharp"; + } else if (ushamethod->get_active_row_number() == 1) { + pp->wavelet.ushamethod = "clari"; + } + if (CHSLmethod->get_active_row_number() == 0) { pp->wavelet.CHSLmethod = "SL"; } else if (CHSLmethod->get_active_row_number() == 1) { @@ -1696,8 +2023,8 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) pp->wavelet.Tilesmethod = "full"; } else if (Tilesmethod->get_active_row_number() == 1) { pp->wavelet.Tilesmethod = "big"; - } else if (Tilesmethod->get_active_row_number() == 2) { - pp->wavelet.Tilesmethod = "lit"; +// } else if (Tilesmethod->get_active_row_number() == 2) { +// pp->wavelet.Tilesmethod = "lit"; } if (daubcoeffmethod->get_active_row_number() == 0) { @@ -1725,31 +2052,33 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) pp->wavelet.Lmethod = Lmethod->get_active_row_number() + 1; } -void Wavelet::curveChanged (CurveEditor* ce) +void Wavelet::curveChanged(CurveEditor* ce) { if (listener && getEnabled()) { if (ce == ccshape) { - listener->panelChanged (EvWavCCCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvWavCCCurve, M("HISTORY_CUSTOMCURVE")); + } else if (ce == blshape) { + listener->panelChanged(EvWavblshape, M("HISTORY_CUSTOMCURVE")); } else if (ce == opacityShapeRG) { - listener->panelChanged (EvWavColor, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvWavColor, M("HISTORY_CUSTOMCURVE")); } else if (ce == opacityShapeBY) { - listener->panelChanged (EvWavOpac, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvWavOpac, M("HISTORY_CUSTOMCURVE")); } else if (ce == opacityShape) { - listener->panelChanged (EvWavopacity, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvWavopacity, M("HISTORY_CUSTOMCURVE")); } else if (ce == opacityShapeWL) { - listener->panelChanged (EvWavopacityWL, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvWavopacityWL, M("HISTORY_CUSTOMCURVE")); } else if (ce == hhshape) { - listener->panelChanged (EvWavHHCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvWavHHCurve, M("HISTORY_CUSTOMCURVE")); } else if (ce == Chshape) { - listener->panelChanged (EvWavCHCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvWavCHCurve, M("HISTORY_CUSTOMCURVE")); } else if (ce == clshape) { - listener->panelChanged (EvWavCLCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvWavCLCurve, M("HISTORY_CUSTOMCURVE")); } } } -void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) +void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedited) { for (int i = 0; i < 9; i++) { @@ -1760,32 +2089,41 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi correctionch[i]->setDefault(defParams->wavelet.ch[i]); } - strength->setDefault(defParams->wavelet.strength ); - balance->setDefault(defParams->wavelet.balance ); - iter->setDefault(defParams->wavelet.iter ); - rescon->setDefault (defParams->wavelet.rescon); - resconH->setDefault (defParams->wavelet.resconH); - reschro->setDefault (defParams->wavelet.reschro); - tmrs->setDefault (defParams->wavelet.tmrs); - gamma->setDefault (defParams->wavelet.gamma); - sup->setDefault (defParams->wavelet.sup); - sky->setDefault (defParams->wavelet.sky); - thres->setDefault (defParams->wavelet.thres); - threshold->setDefault (defParams->wavelet.threshold); - threshold2->setDefault (defParams->wavelet.threshold2); - edgedetect->setDefault (defParams->wavelet.edgedetect); - edgedetectthr->setDefault (defParams->wavelet.edgedetectthr); - edgedetectthr2->setDefault (defParams->wavelet.edgedetectthr2); - edgesensi->setDefault (defParams->wavelet.edgesensi); - edgeampli->setDefault (defParams->wavelet.edgeampli); - chroma->setDefault (defParams->wavelet.chroma); - chro->setDefault (defParams->wavelet.chro); - contrast->setDefault (defParams->wavelet.contrast); - edgrad->setDefault (defParams->wavelet.edgrad); - edgval->setDefault (defParams->wavelet.edgval); - edgthresh->setDefault (defParams->wavelet.edgthresh); - thr->setDefault (defParams->wavelet.thr); - thrH->setDefault (defParams->wavelet.thrH); + strength->setDefault(defParams->wavelet.strength); + balance->setDefault(defParams->wavelet.balance); + iter->setDefault(defParams->wavelet.iter); + sigma->setDefault(defParams->wavelet.sigma); + offset->setDefault(defParams->wavelet.offset); + lowthr->setDefault(defParams->wavelet.lowthr); + rescon->setDefault(defParams->wavelet.rescon); + resconH->setDefault(defParams->wavelet.resconH); + reschro->setDefault(defParams->wavelet.reschro); + resblur->setDefault(defParams->wavelet.resblur); + resblurc->setDefault(defParams->wavelet.resblurc); + tmrs->setDefault(defParams->wavelet.tmrs); + edgs->setDefault(defParams->wavelet.edgs); + scale->setDefault(defParams->wavelet.scale); + gamma->setDefault(defParams->wavelet.gamma); + sup->setDefault(defParams->wavelet.sup); + sky->setDefault(defParams->wavelet.sky); + thres->setDefault(defParams->wavelet.thres); + threshold->setDefault(defParams->wavelet.threshold); + threshold2->setDefault(defParams->wavelet.threshold2); + edgedetect->setDefault(defParams->wavelet.edgedetect); + edgedetectthr->setDefault(defParams->wavelet.edgedetectthr); + edgedetectthr2->setDefault(defParams->wavelet.edgedetectthr2); + edgesensi->setDefault(defParams->wavelet.edgesensi); + edgeampli->setDefault(defParams->wavelet.edgeampli); + chroma->setDefault(defParams->wavelet.chroma); + chro->setDefault(defParams->wavelet.chro); + contrast->setDefault(defParams->wavelet.contrast); + edgrad->setDefault(defParams->wavelet.edgrad); + edgeffect->setDefault(defParams->wavelet.edgeffect); + edgval->setDefault(defParams->wavelet.edgval); + edgthresh->setDefault(defParams->wavelet.edgthresh); + thr->setDefault(defParams->wavelet.thr); + thrH->setDefault(defParams->wavelet.thrH); + radius->setDefault(defParams->wavelet.radius); hueskin->setDefault (defParams->wavelet.hueskin); hueskin2->setDefault (defParams->wavelet.hueskin2); hllev->setDefault (defParams->wavelet.hllev); @@ -1793,32 +2131,57 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi pastlev->setDefault (defParams->wavelet.pastlev); satlev->setDefault (defParams->wavelet.satlev); edgcont->setDefault (defParams->wavelet.edgcont); + chrwav->setDefault(defParams->wavelet.chrwav); + bluwav->setDefault(defParams->wavelet.bluwav); level0noise->setDefault (defParams->wavelet.level0noise); level1noise->setDefault (defParams->wavelet.level1noise); level2noise->setDefault (defParams->wavelet.level2noise); level3noise->setDefault (defParams->wavelet.level3noise); + ballum->setDefault(defParams->wavelet.ballum); + balchrom->setDefault(defParams->wavelet.balchrom); + chromfi->setDefault(defParams->wavelet.chromfi); + chromco->setDefault(defParams->wavelet.chromco); - greenlow->setDefault (defParams->wavelet.greenlow); - bluelow->setDefault (defParams->wavelet.bluelow); - greenmed->setDefault (defParams->wavelet.greenmed); - bluemed->setDefault (defParams->wavelet.bluemed); - greenhigh->setDefault (defParams->wavelet.greenhigh); - bluehigh->setDefault (defParams->wavelet.bluehigh); + greenlow->setDefault(defParams->wavelet.greenlow); + bluelow->setDefault(defParams->wavelet.bluelow); + greenmed->setDefault(defParams->wavelet.greenmed); + bluemed->setDefault(defParams->wavelet.bluemed); + greenhigh->setDefault(defParams->wavelet.greenhigh); + bluehigh->setDefault(defParams->wavelet.bluehigh); + mergeL->setDefault(defParams->wavelet.mergeL); + mergeC->setDefault(defParams->wavelet.mergeC); + softrad->setDefault(defParams->wavelet.softrad); + softradend->setDefault(defParams->wavelet.softradend); if (pedited) { - greenlow->setDefaultEditedState (pedited->wavelet.greenlow ? Edited : UnEdited); - bluelow->setDefaultEditedState (pedited->wavelet.bluelow ? Edited : UnEdited); - greenmed->setDefaultEditedState (pedited->wavelet.greenmed ? Edited : UnEdited); - bluemed->setDefaultEditedState (pedited->wavelet.bluemed ? Edited : UnEdited); - greenhigh->setDefaultEditedState (pedited->wavelet.greenhigh ? Edited : UnEdited); - bluehigh->setDefaultEditedState (pedited->wavelet.bluehigh ? Edited : UnEdited); + greenlow->setDefaultEditedState(pedited->wavelet.greenlow ? Edited : UnEdited); + bluelow->setDefaultEditedState(pedited->wavelet.bluelow ? Edited : UnEdited); + greenmed->setDefaultEditedState(pedited->wavelet.greenmed ? Edited : UnEdited); + bluemed->setDefaultEditedState(pedited->wavelet.bluemed ? Edited : UnEdited); + greenhigh->setDefaultEditedState(pedited->wavelet.greenhigh ? Edited : UnEdited); + bluehigh->setDefaultEditedState(pedited->wavelet.bluehigh ? Edited : UnEdited); + mergeL->setDefaultEditedState(pedited->wavelet.mergeL ? Edited : UnEdited); + mergeC->setDefaultEditedState(pedited->wavelet.mergeC ? Edited : UnEdited); + softrad->setDefaultEditedState(pedited->wavelet.softrad ? Edited : UnEdited); + softradend->setDefaultEditedState(pedited->wavelet.softradend ? Edited : UnEdited); + ballum->setDefaultEditedState(pedited->wavelet.ballum ? Edited : UnEdited); + balchrom->setDefaultEditedState(pedited->wavelet.balchrom ? Edited : UnEdited); + chromfi->setDefaultEditedState(pedited->wavelet.chromfi ? Edited : UnEdited); + chromco->setDefaultEditedState(pedited->wavelet.chromco ? Edited : UnEdited); - rescon->setDefault (defParams->wavelet.rescon); - resconH->setDefault (defParams->wavelet.resconH); - reschro->setDefault (defParams->wavelet.reschro); - tmrs->setDefault (defParams->wavelet.tmrs); - gamma->setDefault (defParams->wavelet.gamma); - sup->setDefault (defParams->wavelet.sup); + sigma->setDefault(defParams->wavelet.sigma); + offset->setDefault(defParams->wavelet.offset); + lowthr->setDefault(defParams->wavelet.lowthr); + rescon->setDefault(defParams->wavelet.rescon); + resconH->setDefault(defParams->wavelet.resconH); + reschro->setDefault(defParams->wavelet.reschro); + resblur->setDefault(defParams->wavelet.resblur); + resblurc->setDefault(defParams->wavelet.resblurc); + tmrs->setDefault(defParams->wavelet.tmrs); + edgs->setDefault(defParams->wavelet.edgs); + scale->setDefault(defParams->wavelet.scale); + gamma->setDefault(defParams->wavelet.gamma); + sup->setDefault(defParams->wavelet.sup); sky->setDefaultEditedState(pedited->wavelet.sky ? Edited : UnEdited); thres->setDefaultEditedState(pedited->wavelet.thres ? Edited : UnEdited); threshold->setDefaultEditedState(pedited->wavelet.threshold ? Edited : UnEdited); @@ -1832,10 +2195,12 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi chro->setDefaultEditedState(pedited->wavelet.chro ? Edited : UnEdited); contrast->setDefaultEditedState(pedited->wavelet.contrast ? Edited : UnEdited); edgrad->setDefaultEditedState(pedited->wavelet.edgrad ? Edited : UnEdited); + edgeffect->setDefaultEditedState(pedited->wavelet.edgeffect ? Edited : UnEdited); edgval->setDefaultEditedState(pedited->wavelet.edgval ? Edited : UnEdited); - edgthresh->setDefault (defParams->wavelet.edgthresh); + edgthresh->setDefault(defParams->wavelet.edgthresh); thr->setDefaultEditedState(pedited->wavelet.thr ? Edited : UnEdited); thrH->setDefaultEditedState(pedited->wavelet.thrH ? Edited : UnEdited); + radius->setDefaultEditedState(pedited->wavelet.radius ? Edited : UnEdited); skinprotect->setDefaultEditedState(pedited->wavelet.skinprotect ? Edited : UnEdited); hueskin->setDefaultEditedState(pedited->wavelet.hueskin ? Edited : UnEdited); hueskin2->setDefaultEditedState(pedited->wavelet.hueskin2 ? Edited : UnEdited); @@ -1844,6 +2209,8 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi pastlev->setDefaultEditedState(pedited->wavelet.pastlev ? Edited : UnEdited); satlev->setDefaultEditedState(pedited->wavelet.satlev ? Edited : UnEdited); edgcont->setDefaultEditedState(pedited->wavelet.edgcont ? Edited : UnEdited); + chrwav->setDefaultEditedState(pedited->wavelet.chrwav ? Edited : UnEdited); + bluwav->setDefaultEditedState(pedited->wavelet.bluwav ? Edited : UnEdited); strength->setDefaultEditedState(pedited->wavelet.strength ? Edited : UnEdited); balance->setDefaultEditedState(pedited->wavelet.balance ? Edited : UnEdited); iter->setDefaultEditedState(pedited->wavelet.iter ? Edited : UnEdited); @@ -1860,10 +2227,17 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi correctionch[i]->setDefaultEditedState(pedited->wavelet.ch[i] ? Edited : UnEdited); } } else { + sigma->setDefaultEditedState(Irrelevant); + offset->setDefaultEditedState(Irrelevant); + lowthr->setDefaultEditedState(Irrelevant); rescon->setDefaultEditedState(Irrelevant); resconH->setDefaultEditedState(Irrelevant); reschro->setDefaultEditedState(Irrelevant); + resblur->setDefaultEditedState(Irrelevant); + resblurc->setDefaultEditedState(Irrelevant); tmrs->setDefaultEditedState(Irrelevant); + edgs->setDefaultEditedState(Irrelevant); + scale->setDefaultEditedState(Irrelevant); gamma->setDefaultEditedState(Irrelevant); sup->setDefaultEditedState(Irrelevant); sky->setDefaultEditedState(Irrelevant); @@ -1879,25 +2253,29 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi chro->setDefaultEditedState(Irrelevant); contrast->setDefaultEditedState(Irrelevant); edgrad->setDefaultEditedState(Irrelevant); + edgeffect->setDefaultEditedState(Irrelevant); edgval->setDefaultEditedState(Irrelevant); edgthresh->setDefaultEditedState(Irrelevant); thr->setDefaultEditedState(Irrelevant); thrH->setDefaultEditedState(Irrelevant); + radius->setDefaultEditedState(Irrelevant); skinprotect->setDefaultEditedState(Irrelevant); - hueskin->setDefaultEditedState (Irrelevant); - hueskin2->setDefaultEditedState (Irrelevant); - hllev->setDefaultEditedState (Irrelevant); - bllev->setDefaultEditedState (Irrelevant); - edgcont->setDefaultEditedState (Irrelevant); - level0noise->setDefaultEditedState (Irrelevant); - level1noise->setDefaultEditedState (Irrelevant); - level2noise->setDefaultEditedState (Irrelevant); - level3noise->setDefaultEditedState (Irrelevant); - pastlev->setDefaultEditedState (Irrelevant); - satlev->setDefaultEditedState (Irrelevant); - strength->setDefaultEditedState (Irrelevant); - balance->setDefaultEditedState (Irrelevant); - iter->setDefaultEditedState (Irrelevant); + hueskin->setDefaultEditedState(Irrelevant); + hueskin2->setDefaultEditedState(Irrelevant); + hllev->setDefaultEditedState(Irrelevant); + bllev->setDefaultEditedState(Irrelevant); + edgcont->setDefaultEditedState(Irrelevant); + chrwav->setDefaultEditedState(Irrelevant); + bluwav->setDefaultEditedState(Irrelevant); + level0noise->setDefaultEditedState(Irrelevant); + level1noise->setDefaultEditedState(Irrelevant); + level2noise->setDefaultEditedState(Irrelevant); + level3noise->setDefaultEditedState(Irrelevant); + pastlev->setDefaultEditedState(Irrelevant); + satlev->setDefaultEditedState(Irrelevant); + strength->setDefaultEditedState(Irrelevant); + balance->setDefaultEditedState(Irrelevant); + iter->setDefaultEditedState(Irrelevant); for (int i = 0; i < 9; i++) { correction[i]->setDefaultEditedState(Irrelevant); @@ -1911,19 +2289,19 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi void Wavelet::adjusterChanged(ThresholdAdjuster* a, double newBottom, double newTop) { - if (listener && (multiImage || getEnabled()) ) { - if(a == level0noise) { - listener->panelChanged (EvWavlev0nois, - Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS") + ": %1" + "\n" + M("TP_WAVELET_STREN") + ": %2"), int(newTop), int(newBottom))); - } else if(a == level1noise) { - listener->panelChanged (EvWavlev1nois, - Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS") + ": %1" + "\n" + M("TP_WAVELET_STREN") + ": %2"), int(newTop), int(newBottom))); - } else if(a == level2noise) { - listener->panelChanged (EvWavlev2nois, - Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS") + ": %1" + "\n" + M("TP_WAVELET_STREN") + ": %2"), int(newTop), int(newBottom))); - } else if(a == level3noise) { - listener->panelChanged (EvWavlev3nois, - Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS") + ": %1" + "\n" + M("TP_WAVELET_STREN") + ": %2"), int(newTop), int(newBottom))); + if (listener && (multiImage || getEnabled())) { + if (a == level0noise) { + listener->panelChanged(EvWavlev0nois, + Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS") + ": %1" + "\n" + M("TP_WAVELET_STREN") + ": %2"), int(newTop), int(newBottom))); + } else if (a == level1noise) { + listener->panelChanged(EvWavlev1nois, + Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS") + ": %1" + "\n" + M("TP_WAVELET_STREN") + ": %2"), int(newTop), int(newBottom))); + } else if (a == level2noise) { + listener->panelChanged(EvWavlev2nois, + Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS") + ": %1" + "\n" + M("TP_WAVELET_STREN") + ": %2"), int(newTop), int(newBottom))); + } else if (a == level3noise) { + listener->panelChanged(EvWavlev3nois, + Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS") + ": %1" + "\n" + M("TP_WAVELET_STREN") + ": %2"), int(newTop), int(newBottom))); } } @@ -1943,21 +2321,21 @@ void Wavelet::adjusterChanged(ThresholdAdjuster* a, int newBottomLeft, int newTo void Wavelet::adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) { - if (listener && (multiImage || getEnabled()) ) { - if(a == hueskin) { - listener->panelChanged (EvWavHueskin, hueskin->getHistoryString()); - } else if(a == hueskin2) { - listener->panelChanged (EvWavHueskin2, hueskin2->getHistoryString()); - } else if(a == hllev) { - listener->panelChanged (EvWavlhl, hllev->getHistoryString()); - } else if(a == bllev) { - listener->panelChanged (EvWavlbl, bllev->getHistoryString()); - } else if(a == pastlev) { - listener->panelChanged (EvWavpast, pastlev->getHistoryString()); - } else if(a == satlev) { - listener->panelChanged (EvWavsat, satlev->getHistoryString()); - } else if(a == edgcont) { - listener->panelChanged (EvWavedgcont, edgcont->getHistoryString()); + if (listener && (multiImage || getEnabled())) { + if (a == hueskin) { + listener->panelChanged(EvWavHueskin, hueskin->getHistoryString()); + } else if (a == hueskin2) { + listener->panelChanged(EvWavHueskin2, hueskin2->getHistoryString()); + } else if (a == hllev) { + listener->panelChanged(EvWavlhl, hllev->getHistoryString()); + } else if (a == bllev) { + listener->panelChanged(EvWavlbl, bllev->getHistoryString()); + } else if (a == pastlev) { + listener->panelChanged(EvWavpast, pastlev->getHistoryString()); + } else if (a == satlev) { + listener->panelChanged(EvWavsat, satlev->getHistoryString()); + } else if (a == edgcont) { + listener->panelChanged(EvWavedgcont, edgcont->getHistoryString()); } } } @@ -1965,7 +2343,7 @@ void Wavelet::adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL void Wavelet::HSmethodUpdateUI() { if (!batchMode) { - if(HSmethod->get_active_row_number() == 0) { //without + if (HSmethod->get_active_row_number() == 0) { //without hllev->hide(); bllev->hide(); threshold->hide(); @@ -1983,15 +2361,15 @@ void Wavelet::HSmethodChanged() { HSmethodUpdateUI(); - if (listener && (multiImage || getEnabled()) ) { - listener->panelChanged (EvWavHSmet, HSmethod->get_active_text ()); + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavHSmet, HSmethod->get_active_text()); } } void Wavelet::CHmethodUpdateUI() { if (!batchMode) { - if(CHmethod->get_active_row_number() == 0) { + if (CHmethod->get_active_row_number() == 0) { CHSLmethod->show(); pastlev->hide(); satlev->hide(); @@ -2003,14 +2381,14 @@ void Wavelet::CHmethodUpdateUI() int y = thres->getValue(); int z; - for(z = y; z < 9; z++) { + for (z = y; z < 9; z++) { correctionch[z]->hide(); } - for(z = 0; z < y; z++) { + for (z = 0; z < y; z++) { correctionch[z]->show(); } - } else if(CHmethod->get_active_row_number() == 1) { + } else if (CHmethod->get_active_row_number() == 1) { CHSLmethod->show(); pastlev->show(); satlev->show(); @@ -2022,11 +2400,11 @@ void Wavelet::CHmethodUpdateUI() int y = thres->getValue(); int z; - for(z = y; z < 9; z++) { + for (z = y; z < 9; z++) { correctionch[z]->hide(); } - for(z = 0; z < y; z++) { + for (z = 0; z < y; z++) { correctionch[z]->show(); } } else { @@ -2050,8 +2428,8 @@ void Wavelet::CHmethodChanged() { CHmethodUpdateUI(); - if (listener && (multiImage || getEnabled()) ) { - listener->panelChanged (EvWavCHmet, CHmethod->get_active_text ()); + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavCHmet, CHmethod->get_active_text()); } } @@ -2090,10 +2468,10 @@ void Wavelet::CHSLmethodChanged() void Wavelet::EDmethodUpdateUI() { if (!batchMode) { - if(EDmethod->get_active_row_number() == 0 ) { //SL + if (EDmethod->get_active_row_number() == 0) { //SL CCWcurveEditorG->hide(); edgcont->show(); - } else if(EDmethod->get_active_row_number() == 1) { //CU + } else if (EDmethod->get_active_row_number() == 1) { //CU CCWcurveEditorG->show(); edgcont->hide(); } @@ -2103,8 +2481,8 @@ void Wavelet::EDmethodChanged() { EDmethodUpdateUI(); - if (listener && (multiImage || getEnabled()) ) { - listener->panelChanged (EvWavEDmet, EDmethod->get_active_text ()); + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavEDmet, EDmethod->get_active_text()); } } @@ -2118,8 +2496,8 @@ void Wavelet::NPmethodChanged() { NPmethodUpdateUI(); - if (listener && (multiImage || getEnabled()) ) { - listener->panelChanged (EvWavNPmet, NPmethod->get_active_text ()); + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavNPmet, NPmethod->get_active_text()); } } @@ -2128,16 +2506,16 @@ void Wavelet::NPmethodChanged() void Wavelet::BAmethodUpdateUI() { if (!batchMode) { - if(BAmethod->get_active_row_number() == 0 ) { //none + if (BAmethod->get_active_row_number() == 0) { //none balance->hide(); opacityCurveEditorW->hide(); iter->hide(); - } else if(BAmethod->get_active_row_number() == 1) { //sli + } else if (BAmethod->get_active_row_number() == 1) { //sli opacityCurveEditorW->hide(); balance->show(); iter->show(); - } else if(BAmethod->get_active_row_number() == 2) { //CU + } else if (BAmethod->get_active_row_number() == 2) { //CU opacityCurveEditorW->show(); balance->hide(); iter->show(); @@ -2148,8 +2526,8 @@ void Wavelet::BAmethodChanged() { BAmethodUpdateUI(); - if (listener && (multiImage || getEnabled()) ) { - listener->panelChanged (EvWavBAmet, BAmethod->get_active_text ()); + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavBAmet, BAmethod->get_active_text()); } } @@ -2166,14 +2544,22 @@ void Wavelet::TMmethodUpdateUI() } } */ + if (TMmethod->get_active_row_number() == 1) { + edgs->show(); + scale->show(); + } else if (TMmethod->get_active_row_number() == 0) { + edgs->hide(); + scale->hide(); + } + } void Wavelet::TMmethodChanged() { TMmethodUpdateUI(); - if (listener && (multiImage || getEnabled()) ) { - listener->panelChanged (EvWavTMmet, TMmethod->get_active_text ()); + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavTMmet, TMmethod->get_active_text()); } } @@ -2187,8 +2573,8 @@ void Wavelet::BackmethodUpdateUI() { void Wavelet::BackmethodChanged() { //BackmethodUpdateUI(); - if (listener && (multiImage || getEnabled()) ) { - listener->panelChanged (EvWavBackmet, Backmethod->get_active_text ()); + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavBackmet, Backmethod->get_active_text()); } } @@ -2196,19 +2582,19 @@ void Wavelet::CLmethodUpdateUI() { if (!batchMode) { if (CLmethod->get_active_row_number() == 0) { - CLmethod->set_active (0); + CLmethod->set_active(0); Lmethod->set_sensitive(true); Dirmethod->set_sensitive(true); } else if (CLmethod->get_active_row_number() == 1) { - CLmethod->set_active (1); + CLmethod->set_active(1); Lmethod->set_sensitive(true); Dirmethod->set_sensitive(true); } else if (CLmethod->get_active_row_number() == 2) { - CLmethod->set_active (2); + CLmethod->set_active(2); Lmethod->set_sensitive(true); Dirmethod->set_sensitive(true); } else if (CLmethod->get_active_row_number() == 3) { - CLmethod->set_active (3); + CLmethod->set_active(3); Lmethod->set_sensitive(false); Dirmethod->set_sensitive(false); } @@ -2219,8 +2605,8 @@ void Wavelet::CLmethodChanged() { CLmethodUpdateUI(); - if (listener && (multiImage || getEnabled()) ) { - listener->panelChanged (EvWavCLmet, CLmethod->get_active_text ()); + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavCLmet, CLmethod->get_active_text()); } } @@ -2231,11 +2617,57 @@ void Wavelet::TilesmethodUpdateUI() { } */ + +void Wavelet::ushamethodChanged() +{ + if (ushamethod->get_active_row_number() == 1 && expclari->getEnabled() == true) { + Backmethod->set_active(2); + CLmethod->set_active(2); + Lmethod->set_active(6); + Lmethod->set_sensitive(true); + Dirmethod->set_sensitive(true); + Dirmethod->set_active(3); + CLmethod->set_sensitive(false); + Backmethod->set_sensitive(false); + } else if (ushamethod->get_active_row_number() == 0 && expclari->getEnabled() == true) { + Backmethod->set_active(0); + CLmethod->set_active(1); + Lmethod->set_active(2); + Dirmethod->set_active(3); + Lmethod->set_sensitive(true); + Dirmethod->set_sensitive(true); + CLmethod->set_sensitive(false); + Backmethod->set_sensitive(false); + /* } else if (ushamethod->get_active_row_number() == 0 || expclari->getEnabled() == false) { + Backmethod->set_active(1); + CLmethod->set_active(3); + Lmethod->set_active(3); + Dirmethod->set_active(3); + Lmethod->set_sensitive(false); + Dirmethod->set_sensitive(false); + */ + } else if (expclari->getEnabled() == false) { + Backmethod->set_active(1); + CLmethod->set_active(3); + Lmethod->set_active(3); + Dirmethod->set_active(3); + Lmethod->set_sensitive(false); + Dirmethod->set_sensitive(false); + CLmethod->set_sensitive(true); + Backmethod->set_sensitive(true); + } + + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavushamet, ushamethod->get_active_text()); + } +} + + void Wavelet::TilesmethodChanged() { //TilesmethodUpdateUI(); - if (listener && (multiImage || getEnabled()) ) { - listener->panelChanged (EvWavTilesmet, Tilesmethod->get_active_text ()); + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavTilesmet, Tilesmethod->get_active_text()); } } @@ -2247,8 +2679,8 @@ void Wavelet::daubcoeffmethodUpdateUI() { void Wavelet::daubcoeffmethodChanged() { //daubcoeffmethodUpdateUI(); - if (listener && (multiImage || getEnabled()) ) { - listener->panelChanged (EvWavdaubcoeffmet, daubcoeffmethod->get_active_text ()); + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavdaubcoeffmet, daubcoeffmethod->get_active_text()); } } @@ -2261,8 +2693,8 @@ void Wavelet::MedgreinfUpdateUI() { void Wavelet::MedgreinfChanged() { //MedgreinfUpdateUI(); - if (listener && (multiImage || getEnabled()) ) { - listener->panelChanged (EvWavedgreinf, Medgreinf->get_active_text ()); + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavedgreinf, Medgreinf->get_active_text()); } } @@ -2275,8 +2707,8 @@ void Wavelet::DirmethodUpdateUI() { void Wavelet::DirmethodChanged() { //DirmethodUpdateUI(); - if (listener && (multiImage || getEnabled()) ) { - listener->panelChanged (EvWavDirmeto, Dirmethod->get_active_text ()); + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavDirmeto, Dirmethod->get_active_text()); } } @@ -2289,74 +2721,99 @@ void Wavelet::LmethodUpdateUI() { void Wavelet::LmethodChanged() { //LmethodUpdateUI(); - if (listener && (multiImage || getEnabled()) ) { - listener->panelChanged (EvWavLmet, Lmethod->get_active_text ()); + if (ushamethod->get_active_row_number() == 0 && expclari->getEnabled() == true) { + if (Lmethod->get_active_row_number() > 3) { + Lmethod->set_active(3); + } + } + + if (ushamethod->get_active_row_number() == 1 && expclari->getEnabled() == true) { + if (Lmethod->get_active_row_number() < 4) { + Lmethod->set_active(4); + } + } + + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavLmet, Lmethod->get_active_text()); } } -void Wavelet::setBatchMode (bool batchMode) +void Wavelet::setBatchMode(bool batchMode) { - Lmethod->append (M("GENERAL_UNCHANGED")); - CLmethod->append (M("GENERAL_UNCHANGED")); - Backmethod->append (M("GENERAL_UNCHANGED")); - Tilesmethod->append (M("GENERAL_UNCHANGED")); - daubcoeffmethod->append (M("GENERAL_UNCHANGED")); - CHmethod->append (M("GENERAL_UNCHANGED")); - Medgreinf->append (M("GENERAL_UNCHANGED")); - CHSLmethod->append (M("GENERAL_UNCHANGED")); - EDmethod->append (M("GENERAL_UNCHANGED")); - NPmethod->append (M("GENERAL_UNCHANGED")); - BAmethod->append (M("GENERAL_UNCHANGED")); - TMmethod->append (M("GENERAL_UNCHANGED")); - HSmethod->append (M("GENERAL_UNCHANGED")); - Dirmethod->append (M("GENERAL_UNCHANGED")); - CCWcurveEditorG->setBatchMode (batchMode); - opaCurveEditorG->setBatchMode (batchMode); - opacityCurveEditorG->setBatchMode (batchMode); - opacityCurveEditorW->setBatchMode (batchMode); - opacityCurveEditorWL->setBatchMode (batchMode); - curveEditorRES->setBatchMode (batchMode); - curveEditorGAM->setBatchMode (batchMode); - rescon->showEditedCB (); - resconH->showEditedCB (); - reschro->showEditedCB (); - tmrs->showEditedCB (); - gamma->showEditedCB (); - sup->showEditedCB (); - sky->showEditedCB (); - thres->showEditedCB (); - threshold->showEditedCB (); - threshold2->showEditedCB (); - edgedetect->showEditedCB (); - edgedetectthr->showEditedCB (); - edgedetectthr2->showEditedCB (); - edgesensi->showEditedCB (); - edgeampli->showEditedCB (); - chroma->showEditedCB (); - chro->showEditedCB (); - contrast->showEditedCB (); - edgrad->showEditedCB (); - edgval->showEditedCB (); - edgthresh->showEditedCB (); - thr->showEditedCB (); - thrH->showEditedCB (); + Lmethod->append(M("GENERAL_UNCHANGED")); + CLmethod->append(M("GENERAL_UNCHANGED")); + Backmethod->append(M("GENERAL_UNCHANGED")); + Tilesmethod->append(M("GENERAL_UNCHANGED")); + daubcoeffmethod->append(M("GENERAL_UNCHANGED")); + CHmethod->append(M("GENERAL_UNCHANGED")); + Medgreinf->append(M("GENERAL_UNCHANGED")); + ushamethod->append(M("GENERAL_UNCHANGED")); + CHSLmethod->append(M("GENERAL_UNCHANGED")); + EDmethod->append(M("GENERAL_UNCHANGED")); + NPmethod->append(M("GENERAL_UNCHANGED")); + BAmethod->append(M("GENERAL_UNCHANGED")); + TMmethod->append(M("GENERAL_UNCHANGED")); + HSmethod->append(M("GENERAL_UNCHANGED")); + Dirmethod->append(M("GENERAL_UNCHANGED")); + CCWcurveEditorG->setBatchMode(batchMode); + opaCurveEditorG->setBatchMode(batchMode); + opacityCurveEditorG->setBatchMode(batchMode); + opacityCurveEditorW->setBatchMode(batchMode); + opacityCurveEditorWL->setBatchMode(batchMode); + curveEditorbl->setBatchMode(batchMode); + curveEditorRES->setBatchMode(batchMode); + curveEditorGAM->setBatchMode(batchMode); + sigma->showEditedCB(); + offset->showEditedCB(); + lowthr->showEditedCB(); + rescon->showEditedCB(); + resconH->showEditedCB(); + reschro->showEditedCB(); + resblur->showEditedCB(); + resblurc->showEditedCB(); + tmrs->showEditedCB(); + edgs->showEditedCB(); + scale->showEditedCB(); + gamma->showEditedCB(); + sup->showEditedCB(); + sky->showEditedCB(); + thres->showEditedCB(); + threshold->showEditedCB(); + threshold2->showEditedCB(); + edgedetect->showEditedCB(); + edgedetectthr->showEditedCB(); + edgedetectthr2->showEditedCB(); + edgesensi->showEditedCB(); + edgeampli->showEditedCB(); + chroma->showEditedCB(); + chro->showEditedCB(); + contrast->showEditedCB(); + edgrad->showEditedCB(); + edgeffect->showEditedCB(); + edgval->showEditedCB(); + edgthresh->showEditedCB(); + thr->showEditedCB(); + thrH->showEditedCB(); + radius->showEditedCB(); skinprotect->showEditedCB(); - hueskin->showEditedCB (); - hueskin2->showEditedCB (); - hllev->showEditedCB (); - bllev->showEditedCB (); - pastlev->showEditedCB (); - satlev->showEditedCB (); - edgcont->showEditedCB (); - strength->showEditedCB (); - balance->showEditedCB (); - iter->showEditedCB (); - level0noise->showEditedCB (); - level1noise->showEditedCB (); - level2noise->showEditedCB (); - level3noise->showEditedCB (); + hueskin->showEditedCB(); + hueskin2->showEditedCB(); + hllev->showEditedCB(); + bllev->showEditedCB(); + pastlev->showEditedCB(); + satlev->showEditedCB(); + edgcont->showEditedCB(); + chrwav->showEditedCB(); + bluwav->showEditedCB(); + strength->showEditedCB(); + balance->showEditedCB(); + iter->showEditedCB(); + level0noise->showEditedCB(); + level1noise->showEditedCB(); + level2noise->showEditedCB(); + level3noise->showEditedCB(); - ToolPanel::setBatchMode (batchMode); + ToolPanel::setBatchMode(batchMode); for (int i = 0; i < 9; i++) { correction[i]->showEditedCB(); @@ -2367,170 +2824,218 @@ void Wavelet::setBatchMode (bool batchMode) } } -void Wavelet::adjusterUpdateUI (Adjuster* a) +void Wavelet::adjusterUpdateUI(Adjuster* a) { /* - if (!batchMode) { - if (a == tmrs ) { - float tm; - tm=tmrs->getValue(); - if(tm==0.f) tmr->hide(); - else tmr->show(); - } - else if (a == gamma ) { - float tm; - tm=tmrs->getValue(); - if(tm==0.f) tmr->hide(); - else tmr->show(); - ); - } - } + if (!batchMode) { + if (a == tmrs ) { + float tm; + tm=tmrs->getValue(); + if(tm==0.f) tmr->hide(); + else tmr->show(); + } + else if (a == gamma ) { + float tm; + tm=tmrs->getValue(); + if(tm==0.f) tmr->hide(); + else tmr->show(); + + } + } */ } void Wavelet::adjusterChanged(Adjuster* a, double newval) { - if (listener && (multiImage || getEnabled()) ) { + if (listener && (multiImage || getEnabled())) { if (a == edgthresh) { - listener->panelChanged (EvWavtiles, edgthresh->getTextValue()); - } else if (a == rescon ) { - listener->panelChanged (EvWavrescon, rescon->getTextValue()); - } else if (a == resconH ) { - listener->panelChanged (EvWavresconH, resconH->getTextValue()); - } else if (a == reschro ) { - listener->panelChanged (EvWavreschro, reschro->getTextValue()); - } else if (a == tmrs ) { + listener->panelChanged(EvWavtiles, edgthresh->getTextValue()); + } else if (a == rescon) { + listener->panelChanged(EvWavrescon, rescon->getTextValue()); + } else if (a == sigma) { + listener->panelChanged(EvWavsigma, sigma->getTextValue()); + } else if (a == offset) { + listener->panelChanged(EvWavoffset, offset->getTextValue()); + } else if (a == lowthr) { + listener->panelChanged(EvWavlowthr, lowthr->getTextValue()); + } else if (a == resconH) { + listener->panelChanged(EvWavresconH, resconH->getTextValue()); + } else if (a == reschro) { + listener->panelChanged(EvWavreschro, reschro->getTextValue()); + } else if (a == resblur) { + listener->panelChanged(EvWavresblur, resblur->getTextValue()); + } else if (a == resblurc) { + listener->panelChanged(EvWavresblurc, resblurc->getTextValue()); + } else if (a == tmrs) { adjusterUpdateUI(a); - listener->panelChanged (EvWavtmrs, tmrs->getTextValue()); - } else if (a == gamma ) { + listener->panelChanged(EvWavtmrs, tmrs->getTextValue()); + + if (tmrs->getValue() != 0 && TMmethod->get_active_row_number() == 1) { + edgs->show(); + scale->show(); + } else if (TMmethod->get_active_row_number() == 0) { + edgs->hide(); + scale->hide(); + } + } else if (a == gamma) { adjusterUpdateUI(a); - listener->panelChanged (EvWavgamma, gamma->getTextValue()); - } else if (a == sky ) { - listener->panelChanged (EvWavsky, sky->getTextValue()); - } else if (a == sup ) { - listener->panelChanged (EvWavsup, sup->getTextValue()); - } else if (a == chroma ) { - listener->panelChanged (EvWavchroma, chroma->getTextValue()); - } else if (a == chro ) { - listener->panelChanged (EvWavchro, chro->getTextValue()); - } else if (a == contrast ) { - listener->panelChanged (EvWavunif, contrast->getTextValue()); - } else if (a == thr ) { - listener->panelChanged (EvWavthr, thr->getTextValue()); - } else if (a == thrH ) { - listener->panelChanged (EvWavthrH, thrH->getTextValue()); - } else if (a == threshold ) { - listener->panelChanged (EvWavThreshold, threshold->getTextValue()); - } else if (a == threshold2 ) { - listener->panelChanged (EvWavThreshold2, threshold2->getTextValue()); - } else if (a == edgedetect ) { - listener->panelChanged (EvWavedgedetect, edgedetect->getTextValue()); - } else if (a == edgedetectthr ) { - listener->panelChanged (EvWavedgedetectthr, edgedetectthr->getTextValue()); - } else if (a == edgedetectthr2 ) { - listener->panelChanged (EvWavedgedetectthr2, edgedetectthr2->getTextValue()); - } else if (a == edgesensi ) { - listener->panelChanged (EvWavedgesensi, edgesensi->getTextValue()); - } else if (a == edgeampli ) { - listener->panelChanged (EvWavedgeampli, edgeampli->getTextValue()); - } else if (a == edgrad ) { - listener->panelChanged (EvWavedgrad, edgrad->getTextValue()); - } else if (a == edgval ) { - listener->panelChanged (EvWavedgval, edgval->getTextValue()); - } else if (a == thres ) { + listener->panelChanged(EvWavgamma, gamma->getTextValue()); + } else if (a == edgs) { + adjusterUpdateUI(a); + listener->panelChanged(EvWavedgs, edgs->getTextValue()); + } else if (a == scale) { + adjusterUpdateUI(a); + listener->panelChanged(EvWavscale, scale->getTextValue()); + } else if (a == sky) { + listener->panelChanged(EvWavsky, sky->getTextValue()); + } else if (a == sup) { + listener->panelChanged(EvWavsup, sup->getTextValue()); + } else if (a == chroma) { + listener->panelChanged(EvWavchroma, chroma->getTextValue()); + } else if (a == chro) { + listener->panelChanged(EvWavchro, chro->getTextValue()); + } else if (a == contrast) { + listener->panelChanged(EvWavunif, contrast->getTextValue()); + } else if (a == thr) { + listener->panelChanged(EvWavthr, thr->getTextValue()); + } else if (a == thrH) { + listener->panelChanged(EvWavthrH, thrH->getTextValue()); + } else if (a == radius) { + listener->panelChanged(EvWavradius, radius->getTextValue()); + } else if (a == threshold) { + listener->panelChanged(EvWavThreshold, threshold->getTextValue()); + } else if (a == threshold2) { + listener->panelChanged(EvWavThreshold2, threshold2->getTextValue()); + } else if (a == edgedetect) { + listener->panelChanged(EvWavedgedetect, edgedetect->getTextValue()); + } else if (a == edgedetectthr) { + listener->panelChanged(EvWavedgedetectthr, edgedetectthr->getTextValue()); + } else if (a == edgedetectthr2) { + listener->panelChanged(EvWavedgedetectthr2, edgedetectthr2->getTextValue()); + } else if (a == edgesensi) { + listener->panelChanged(EvWavedgesensi, edgesensi->getTextValue()); + } else if (a == edgeampli) { + listener->panelChanged(EvWavedgeampli, edgeampli->getTextValue()); + } else if (a == edgrad) { + listener->panelChanged(EvWavedgrad, edgrad->getTextValue()); + } else if (a == edgeffect) { + listener->panelChanged(EvWavedgeffect, edgeffect->getTextValue()); + } else if (a == edgval) { + listener->panelChanged(EvWavedgval, edgval->getTextValue()); + } else if (a == thres) { int y = thres->getValue(); int z; - for(z = y; z < 9; z++) { + for (z = y; z < 9; z++) { correction[z]->hide(); } - for(z = 0; z < y; z++) { + for (z = 0; z < y; z++) { correction[z]->show(); } - for(z = y; z < 9; z++) { + for (z = y; z < 9; z++) { correctionch[z]->hide(); } - for(z = 0; z < y; z++) { + for (z = 0; z < y; z++) { correctionch[z]->show(); } - if(z == 9) { + if (z == 9) { sup->show(); } else { sup->hide(); } - listener->panelChanged (EvWavthres, thres->getTextValue()); + listener->panelChanged(EvWavthres, thres->getTextValue()); } else if (a == skinprotect) { - listener->panelChanged (EvWavSkin, skinprotect->getTextValue()); + listener->panelChanged(EvWavSkin, skinprotect->getTextValue()); } else if (a == strength) { - listener->panelChanged (EvWavStrength, strength->getTextValue()); + listener->panelChanged(EvWavStrength, strength->getTextValue()); } else if (a == balance) { - listener->panelChanged (EvWavbalance, balance->getTextValue()); + listener->panelChanged(EvWavbalance, balance->getTextValue()); } else if (a == iter) { - listener->panelChanged (EvWaviter, iter->getTextValue()); - } else if (a == greenhigh ) { - listener->panelChanged (EvWavgreenhigh, greenhigh->getTextValue()); - } else if (a == bluehigh ) { - listener->panelChanged (EvWavbluehigh, bluehigh->getTextValue()); - } else if (a == greenmed ) { - listener->panelChanged (EvWavgreenmed, greenmed->getTextValue()); - } else if (a == bluemed ) { - listener->panelChanged (EvWavbluemed, bluemed->getTextValue()); - } else if (a == greenlow ) { - listener->panelChanged (EvWavgreenlow, greenlow->getTextValue()); - } else if (a == bluelow ) { - listener->panelChanged (EvWavbluelow, bluelow->getTextValue()); + listener->panelChanged(EvWaviter, iter->getTextValue()); + } else if (a == greenhigh) { + listener->panelChanged(EvWavgreenhigh, greenhigh->getTextValue()); + } else if (a == bluehigh) { + listener->panelChanged(EvWavbluehigh, bluehigh->getTextValue()); + } else if (a == ballum) { + listener->panelChanged(EvWavballum, ballum->getTextValue()); + } else if (a == balchrom) { + listener->panelChanged(EvWavbalchrom, balchrom->getTextValue()); + } else if (a == chromfi) { + listener->panelChanged(EvWavchromfi, chromfi->getTextValue()); + } else if (a == chromco) { + listener->panelChanged(EvWavchromco, chromco->getTextValue()); + } else if (a == mergeL) { + listener->panelChanged(EvWavmergeL, mergeL->getTextValue()); + } else if (a == mergeC) { + listener->panelChanged(EvWavmergeC, mergeC->getTextValue()); + } else if (a == softrad) { + listener->panelChanged(EvWavsoftrad, softrad->getTextValue()); + } else if (a == softradend) { + listener->panelChanged(EvWavsoftradend, softradend->getTextValue()); + } else if (a == greenmed) { + listener->panelChanged(EvWavgreenmed, greenmed->getTextValue()); + } else if (a == bluemed) { + listener->panelChanged(EvWavbluemed, bluemed->getTextValue()); + } else if (a == greenlow) { + listener->panelChanged(EvWavgreenlow, greenlow->getTextValue()); + } else if (a == bluelow) { + listener->panelChanged(EvWavbluelow, bluelow->getTextValue()); + } else if (a == chrwav) { + listener->panelChanged(EvWavchrwav, chrwav->getTextValue()); + } else if (a == bluwav) { + listener->panelChanged(EvWavbluwav, bluwav->getTextValue()); } if ((a == correction[0] || a == correction[1] || a == correction[2] || a == correction[3] || a == correction[4] || a == correction[5] || a == correction[6] || a == correction[7] || a == correction[8])) { - listener->panelChanged (EvWavelet, - Glib::ustring::compose("%1, %2, %3, %4, %5, %6, %7, %8, %9", - Glib::ustring::format(std::fixed, std::setprecision(0), correction[0]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correction[1]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correction[2]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correction[3]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correction[4]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correction[5]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correction[6]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correction[7]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correction[8]->getValue())) - ); - } else if (a == correctionch[0] || a == correctionch[1] || a == correctionch[2] || a == correctionch[3] || a == correctionch[4] || a == correctionch[5] || a == correctionch[6] || a == correctionch[7] || a == correctionch[8] ) { - listener->panelChanged (EvWaveletch, - Glib::ustring::compose("%1, %2, %3, %4, %5, %6, %7, %8, %9", - Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[0]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[1]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[2]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[3]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[4]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[5]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[6]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[7]->getValue()), - Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[8]->getValue())) - ); + listener->panelChanged(EvWavelet, + Glib::ustring::compose("%1, %2, %3, %4, %5, %6, %7, %8, %9", + Glib::ustring::format(std::fixed, std::setprecision(0), correction[0]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[1]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[2]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[3]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[4]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[5]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[6]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[7]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[8]->getValue())) + ); + } else if (a == correctionch[0] || a == correctionch[1] || a == correctionch[2] || a == correctionch[3] || a == correctionch[4] || a == correctionch[5] || a == correctionch[6] || a == correctionch[7] || a == correctionch[8]) { + listener->panelChanged(EvWaveletch, + Glib::ustring::compose("%1, %2, %3, %4, %5, %6, %7, %8, %9", + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[0]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[1]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[2]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[3]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[4]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[5]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[6]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[7]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[8]->getValue())) + ); } } } -void Wavelet::enabledUpdateUI () +void Wavelet::enabledUpdateUI() { if (!batchMode) { int y = thres->getValue(); int z; - for(z = y; z < 9; z++) { + for (z = y; z < 9; z++) { correction[z]->hide(); } - for(z = 0; z < y; z++) { + for (z = 0; z < y; z++) { correction[z]->show(); } - if(z == 9) { + if (z == 9) { sup->show(); } else { sup->hide(); @@ -2540,52 +3045,52 @@ void Wavelet::enabledUpdateUI () } } -void Wavelet::enabledChanged () +void Wavelet::enabledChanged() { enabledUpdateUI(); if (listener) { if (get_inconsistent()) { - listener->panelChanged (EvWavEnabled, M("GENERAL_UNCHANGED")); + listener->panelChanged(EvWavEnabled, M("GENERAL_UNCHANGED")); } else if (getEnabled()) { - listener->panelChanged (EvWavEnabled, M("GENERAL_ENABLED")); + listener->panelChanged(EvWavEnabled, M("GENERAL_ENABLED")); } else { - listener->panelChanged (EvWavEnabled, M("GENERAL_DISABLED")); + listener->panelChanged(EvWavEnabled, M("GENERAL_DISABLED")); } } } -void Wavelet::medianToggled () +void Wavelet::medianToggled() { if (multiImage) { if (median->get_inconsistent()) { - median->set_inconsistent (false); - medianConn.block (true); - median->set_active (false); - medianConn.block (false); + median->set_inconsistent(false); + medianConn.block(true); + median->set_active(false); + medianConn.block(false); } else if (lastmedian) { - median->set_inconsistent (true); + median->set_inconsistent(true); } - lastmedian = median->get_active (); + lastmedian = median->get_active(); } - if (listener && (multiImage || getEnabled ())) { + if (listener && (multiImage || getEnabled())) { if (median->get_inconsistent()) { - listener->panelChanged (EvWavmedian, M("GENERAL_UNCHANGED")); - } else if (median->get_active ()) { - listener->panelChanged (EvWavmedian, M("GENERAL_ENABLED")); + listener->panelChanged(EvWavmedian, M("GENERAL_UNCHANGED")); + } else if (median->get_active()) { + listener->panelChanged(EvWavmedian, M("GENERAL_ENABLED")); } else { - listener->panelChanged (EvWavmedian, M("GENERAL_DISABLED")); + listener->panelChanged(EvWavmedian, M("GENERAL_DISABLED")); } } } -void Wavelet::medianlevUpdateUI () +void Wavelet::medianlevUpdateUI() { if (!batchMode) { - if (medianlev->get_active ()) { + if (medianlev->get_active()) { edgedetect->show(); lipst->show(); separatoredge->show(); @@ -2597,7 +3102,7 @@ void Wavelet::medianlevUpdateUI () // edgeampli->show(); // NPmethod->show(); // labmNP->show(); - if (lipst->get_active ()) { + if (lipst->get_active()) { edgesensi->show(); edgeampli->show(); NPmethod->show(); @@ -2625,66 +3130,66 @@ void Wavelet::medianlevUpdateUI () } } -void Wavelet::medianlevToggled () +void Wavelet::medianlevToggled() { if (multiImage) { if (medianlev->get_inconsistent()) { - medianlev->set_inconsistent (false); - medianlevConn.block (true); - medianlev->set_active (false); - medianlevConn.block (false); + medianlev->set_inconsistent(false); + medianlevConn.block(true); + medianlev->set_active(false); + medianlevConn.block(false); } else if (lastmedianlev) { - medianlev->set_inconsistent (true); + medianlev->set_inconsistent(true); } - lastmedianlev = medianlev->get_active (); + lastmedianlev = medianlev->get_active(); } medianlevUpdateUI(); - if (listener && (multiImage || getEnabled ())) { + if (listener && (multiImage || getEnabled())) { if (medianlev->get_inconsistent()) { - listener->panelChanged (EvWavmedianlev, M("GENERAL_UNCHANGED")); - } else if (medianlev->get_active () ) { - listener->panelChanged (EvWavmedianlev, M("GENERAL_ENABLED")); + listener->panelChanged(EvWavmedianlev, M("GENERAL_UNCHANGED")); + } else if (medianlev->get_active()) { + listener->panelChanged(EvWavmedianlev, M("GENERAL_ENABLED")); } else { - listener->panelChanged (EvWavmedianlev, M("GENERAL_DISABLED")); + listener->panelChanged(EvWavmedianlev, M("GENERAL_DISABLED")); } } } -void Wavelet::linkedgToggled () +void Wavelet::linkedgToggled() { if (multiImage) { if (linkedg->get_inconsistent()) { - linkedg->set_inconsistent (false); - linkedgConn.block (true); - linkedg->set_active (false); - linkedgConn.block (false); + linkedg->set_inconsistent(false); + linkedgConn.block(true); + linkedg->set_active(false); + linkedgConn.block(false); } else if (lastlinkedg) { - linkedg->set_inconsistent (true); + linkedg->set_inconsistent(true); } - lastlinkedg = linkedg->get_active (); + lastlinkedg = linkedg->get_active(); } - if (listener && (multiImage || getEnabled ())) { + if (listener && (multiImage || getEnabled())) { if (linkedg->get_inconsistent()) { - listener->panelChanged (EvWavlinkedg, M("GENERAL_UNCHANGED")); - } else if (linkedg->get_active () ) { - listener->panelChanged (EvWavlinkedg, M("GENERAL_ENABLED")); + listener->panelChanged(EvWavlinkedg, M("GENERAL_UNCHANGED")); + } else if (linkedg->get_active()) { + listener->panelChanged(EvWavlinkedg, M("GENERAL_ENABLED")); } else { - listener->panelChanged (EvWavlinkedg, M("GENERAL_DISABLED")); + listener->panelChanged(EvWavlinkedg, M("GENERAL_DISABLED")); } } } -void Wavelet::cbenabUpdateUI () +void Wavelet::cbenabUpdateUI() { if (!batchMode) { - if(cbenab->get_active ()) { + if (cbenab->get_active()) { chanMixerHLFrame->show(); chanMixerMidFrame->show(); chanMixerShadowsFrame->show(); @@ -2698,40 +3203,40 @@ void Wavelet::cbenabUpdateUI () } } -void Wavelet::cbenabToggled () +void Wavelet::cbenabToggled() { if (multiImage) { if (cbenab->get_inconsistent()) { - cbenab->set_inconsistent (false); - cbenabConn.block (true); - cbenab->set_active (false); - cbenabConn.block (false); + cbenab->set_inconsistent(false); + cbenabConn.block(true); + cbenab->set_active(false); + cbenabConn.block(false); } else if (lastcbenab) { - cbenab->set_inconsistent (true); + cbenab->set_inconsistent(true); } - lastcbenab = cbenab->get_active (); + lastcbenab = cbenab->get_active(); } cbenabUpdateUI(); - if (listener && (multiImage || getEnabled ())) { - if (cbenab->get_inconsistent() ) { - listener->panelChanged (EvWavcbenab, M("GENERAL_UNCHANGED")); - } else if (cbenab->get_active () ) { - listener->panelChanged (EvWavcbenab, M("GENERAL_ENABLED")); + if (listener && (multiImage || getEnabled())) { + if (cbenab->get_inconsistent()) { + listener->panelChanged(EvWavcbenab, M("GENERAL_UNCHANGED")); + } else if (cbenab->get_active()) { + listener->panelChanged(EvWavcbenab, M("GENERAL_ENABLED")); } else { - listener->panelChanged (EvWavcbenab, M("GENERAL_DISABLED")); + listener->panelChanged(EvWavcbenab, M("GENERAL_DISABLED")); } } } -void Wavelet::lipstUpdateUI () +void Wavelet::lipstUpdateUI() { if (!batchMode) { - if (lipst->get_active ()) { + if (lipst->get_active()) { NPmethod->show(); edgesensi->show(); edgeampli->show(); @@ -2747,31 +3252,31 @@ void Wavelet::lipstUpdateUI () } -void Wavelet::lipstToggled () +void Wavelet::lipstToggled() { if (multiImage) { if (lipst->get_inconsistent()) { - lipst->set_inconsistent (false); - lipstConn.block (true); - lipst->set_active (false); - lipstConn.block (false); + lipst->set_inconsistent(false); + lipstConn.block(true); + lipst->set_active(false); + lipstConn.block(false); } else if (lastlipst) { - lipst->set_inconsistent (true); + lipst->set_inconsistent(true); } - lastlipst = lipst->get_active (); + lastlipst = lipst->get_active(); } lipstUpdateUI(); - if (listener && (multiImage || getEnabled ())) { + if (listener && (multiImage || getEnabled())) { if (lipst->get_inconsistent()) { - listener->panelChanged (EvWavlipst, M("GENERAL_UNCHANGED")); - } else if (lipst->get_active ()) { - listener->panelChanged (EvWavlipst, M("GENERAL_ENABLED")); + listener->panelChanged(EvWavlipst, M("GENERAL_UNCHANGED")); + } else if (lipst->get_active()) { + listener->panelChanged(EvWavlipst, M("GENERAL_ENABLED")); } else { - listener->panelChanged (EvWavlipst, M("GENERAL_DISABLED")); + listener->panelChanged(EvWavlipst, M("GENERAL_DISABLED")); } } } @@ -2802,62 +3307,120 @@ void Wavelet::edgreinfToggled () { } } */ -void Wavelet::avoidToggled () +void Wavelet::avoidToggled() { if (multiImage) { if (avoid->get_inconsistent()) { - avoid->set_inconsistent (false); - avoidConn.block (true); - avoid->set_active (false); - avoidConn.block (false); + avoid->set_inconsistent(false); + avoidConn.block(true); + avoid->set_active(false); + avoidConn.block(false); } else if (lastavoid) { - avoid->set_inconsistent (true); + avoid->set_inconsistent(true); } - lastavoid = avoid->get_active (); + lastavoid = avoid->get_active(); } - if (listener && (multiImage || getEnabled ())) { + if (listener && (multiImage || getEnabled())) { if (avoid->get_inconsistent()) { - listener->panelChanged (EvWavavoid, M("GENERAL_UNCHANGED")); - } else if (avoid->get_active ()) { - listener->panelChanged (EvWavavoid, M("GENERAL_ENABLED")); + listener->panelChanged(EvWavavoid, M("GENERAL_UNCHANGED")); + } else if (avoid->get_active()) { + listener->panelChanged(EvWavavoid, M("GENERAL_ENABLED")); } else { - listener->panelChanged (EvWavavoid, M("GENERAL_DISABLED")); + listener->panelChanged(EvWavavoid, M("GENERAL_DISABLED")); } } } -void Wavelet::tmrToggled () +void Wavelet::showmaskToggled() +{ + if (multiImage) { + if (showmask->get_inconsistent()) { + showmask->set_inconsistent(false); + showmaskConn.block(true); + showmask->set_active(false); + showmaskConn.block(false); + } else if (lastshowmask) { + showmask->set_inconsistent(true); + } + + lastshowmask = showmask->get_active(); + } + + if (listener && (multiImage || getEnabled())) { + if (showmask->get_inconsistent()) { + listener->panelChanged(EvWavshowmask, M("GENERAL_UNCHANGED")); + } else if (showmask->get_active()) { + listener->panelChanged(EvWavshowmask, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(EvWavshowmask, M("GENERAL_DISABLED")); + } + } +} + +void Wavelet::oldshToggled() +{ + if (oldsh->get_active()) { + radius->hide(); + } else { + radius->show(); + } + + if (multiImage) { + if (oldsh->get_inconsistent()) { + oldsh->set_inconsistent(false); + oldshConn.block(true); + oldsh->set_active(false); + oldshConn.block(false); + } else if (lastoldsh) { + oldsh->set_inconsistent(true); + } + + lastoldsh = oldsh->get_active(); + } + + if (listener && (multiImage || getEnabled())) { + if (oldsh->get_inconsistent()) { + listener->panelChanged(EvWavoldsh, M("GENERAL_UNCHANGED")); + } else if (oldsh->get_active()) { + listener->panelChanged(EvWavoldsh, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(EvWavoldsh, M("GENERAL_DISABLED")); + } + } +} + +void Wavelet::tmrToggled() { if (multiImage) { if (tmr->get_inconsistent()) { - tmr->set_inconsistent (false); - tmrConn.block (true); - tmr->set_active (false); - tmrConn.block (false); + tmr->set_inconsistent(false); + tmrConn.block(true); + tmr->set_active(false); + tmrConn.block(false); } else if (lasttmr) { - tmr->set_inconsistent (true); + tmr->set_inconsistent(true); } - lasttmr = tmr->get_active (); + lasttmr = tmr->get_active(); } - if (listener && (multiImage || getEnabled ())) { + if (listener && (multiImage || getEnabled())) { if (tmr->get_inconsistent()) { - listener->panelChanged (EvWavtmr, M("GENERAL_UNCHANGED")); - } else if (tmr->get_active ()) { - listener->panelChanged (EvWavtmr, M("GENERAL_ENABLED")); + listener->panelChanged(EvWavtmr, M("GENERAL_UNCHANGED")); + } else if (tmr->get_active()) { + listener->panelChanged(EvWavtmr, M("GENERAL_ENABLED")); } else { - listener->panelChanged (EvWavtmr, M("GENERAL_DISABLED")); + listener->panelChanged(EvWavtmr, M("GENERAL_DISABLED")); } } } -void Wavelet::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller) +void Wavelet::colorForValue(double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller) { float R = 0.f, G = 0.f, B = 0.f; @@ -2897,7 +3460,7 @@ void Wavelet::colorForValue (double valX, double valY, enum ColorCaller::ElemTyp caller->ccGreen = double(G); caller->ccBlue = double(B); } -void Wavelet::setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd, bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool tmrsadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd, bool gammaadd, bool edgedetectadd, bool edgedetectthradd , bool edgedetectthr2add) +void Wavelet::setAdjusterBehavior(bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd, bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool tmrsadd, bool edgsadd, bool scaleadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool radiusadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd, bool gammaadd, bool edgedetectadd, bool edgedetectthradd, bool edgedetectthr2add) { for (int i = 0; i < 9; i++) { @@ -2915,8 +3478,11 @@ void Wavelet::setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool t resconH->setAddMode(resconHadd); reschro->setAddMode(reschroadd); tmrs->setAddMode(tmrsadd); + edgs->setAddMode(edgsadd); + scale->setAddMode(scaleadd); thr->setAddMode(thradd); thrH->setAddMode(thrHadd); + radius->setAddMode(radiusadd); sky->setAddMode(skyadd); edgrad->setAddMode(edgradadd); edgval->setAddMode(edgvaladd); @@ -2928,7 +3494,7 @@ void Wavelet::setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool t } -void Wavelet::neutralPressed () +void Wavelet::neutralPressed() { for (int i = 0; i < 9; i++) { correction[i]->setValue(0); @@ -2936,7 +3502,7 @@ void Wavelet::neutralPressed () } } -void Wavelet::neutralchPressed () +void Wavelet::neutralchPressed() { for (int i = 0; i < 9; i++) { @@ -2946,7 +3512,7 @@ void Wavelet::neutralchPressed () } -void Wavelet::contrastPlusPressed () +void Wavelet::contrastPlusPressed() { for (int i = 0; i < 9; i++) { @@ -2957,7 +3523,7 @@ void Wavelet::contrastPlusPressed () } -void Wavelet::contrastMinusPressed () +void Wavelet::contrastMinusPressed() { for (int i = 0; i < 9; i++) { @@ -2967,7 +3533,7 @@ void Wavelet::contrastMinusPressed () } } -void Wavelet::foldAllButMe (GdkEventButton* event, MyExpander *expander) +void Wavelet::foldAllButMe(GdkEventButton* event, MyExpander *expander) { if (event->button == 3) { expsettings->set_expanded(expsettings == expander); @@ -2976,9 +3542,11 @@ void Wavelet::foldAllButMe (GdkEventButton* event, MyExpander *expander) exptoning->set_expanded(exptoning == expander); expnoise->set_expanded(expnoise == expander); expedge->set_expanded(expedge == expander); + expbl->set_expanded(expbl == expander); expgamut->set_expanded(expgamut == expander); expresid->set_expanded(expresid == expander); expfinal->set_expanded(expfinal == expander); + expclari->set_expanded(expclari == expander); } } @@ -2997,10 +3565,46 @@ void Wavelet::enableToggled(MyExpander *expander) event = EvWavenanoise; } else if (expander == expedge) { event = EvWavenaedge; + } else if (expander == expbl) { + event = EvWavenabl; } else if (expander == expresid) { event = EvWavenares; } else if (expander == expfinal) { event = EvWavenafin; + } else if (expander == expclari) { + if (expclari->getEnabled() == false) { + Backmethod->set_active(1); + CLmethod->set_active(3); + Lmethod->set_active(3); + Dirmethod->set_active(3); + Lmethod->set_sensitive(false); + Dirmethod->set_sensitive(false); + CLmethod->set_sensitive(true); + Backmethod->set_sensitive(true); + } else { + + if (ushamethod->get_active_row_number() == 1) { + Backmethod->set_active(2); + CLmethod->set_active(2); + Lmethod->set_active(6); + Lmethod->set_sensitive(true); + Dirmethod->set_sensitive(true); + Dirmethod->set_active(3); + CLmethod->set_sensitive(false); + Backmethod->set_sensitive(false); + } else if (ushamethod->get_active_row_number() == 0) { + Backmethod->set_active(0); + CLmethod->set_active(1); + Lmethod->set_active(2); + Dirmethod->set_active(3); + Lmethod->set_sensitive(true); + Dirmethod->set_sensitive(true); + CLmethod->set_sensitive(false); + Backmethod->set_sensitive(false); + } + } + + event = EvWavenaclari; } else // unknown expander, returning ! { @@ -3008,40 +3612,59 @@ void Wavelet::enableToggled(MyExpander *expander) } if (expander->get_inconsistent()) { - listener->panelChanged (event, M("GENERAL_UNCHANGED")); + listener->panelChanged(event, M("GENERAL_UNCHANGED")); } else if (expander->getEnabled()) { - listener->panelChanged (event, M("GENERAL_ENABLED")); + listener->panelChanged(event, M("GENERAL_ENABLED")); } else { - listener->panelChanged (event, M("GENERAL_DISABLED")); + listener->panelChanged(event, M("GENERAL_DISABLED")); } } } void Wavelet::writeOptions(std::vector &tpOpen) { - tpOpen.push_back (expsettings->get_expanded ()); - tpOpen.push_back (expcontrast->get_expanded ()); - tpOpen.push_back (expchroma->get_expanded ()); - tpOpen.push_back (exptoning->get_expanded ()); - tpOpen.push_back (expnoise->get_expanded ()); - tpOpen.push_back (expedge->get_expanded ()); - tpOpen.push_back (expgamut->get_expanded ()); - tpOpen.push_back (expresid->get_expanded ()); - tpOpen.push_back (expfinal->get_expanded ()); + tpOpen.push_back(expsettings->get_expanded()); + tpOpen.push_back(expcontrast->get_expanded()); + tpOpen.push_back(expchroma->get_expanded()); + tpOpen.push_back(exptoning->get_expanded()); + tpOpen.push_back(expnoise->get_expanded()); + tpOpen.push_back(expedge->get_expanded()); + tpOpen.push_back(expbl->get_expanded()); + tpOpen.push_back(expgamut->get_expanded()); + tpOpen.push_back(expresid->get_expanded()); + tpOpen.push_back(expfinal->get_expanded()); + tpOpen.push_back(expclari->get_expanded()); } -void Wavelet::updateToolState(std::vector &tpOpen) +void Wavelet::updateToolState(const std::vector& tpOpen) { - if(tpOpen.size() >= 9) { - expsettings->set_expanded(tpOpen.at(0)); - expcontrast->set_expanded(tpOpen.at(1)); - expchroma->set_expanded(tpOpen.at(2)); - exptoning->set_expanded(tpOpen.at(3)); - expnoise->set_expanded(tpOpen.at(4)); - expedge->set_expanded(tpOpen.at(5)); - expgamut->set_expanded(tpOpen.at(6)); - expresid->set_expanded(tpOpen.at(7)); - expfinal->set_expanded(tpOpen.at(8)); + if (tpOpen.empty()) { + expsettings->set_expanded(false); + expcontrast->set_expanded(false); + expchroma->set_expanded(false); + exptoning->set_expanded(false); + expnoise->set_expanded(false); + expedge->set_expanded(false); + expbl->set_expanded(false); + expgamut->set_expanded(false); + expresid->set_expanded(false); + expfinal->set_expanded(false); + expclari->set_expanded(false); + return; + } + + if (tpOpen.size() >= 11) { + expsettings->set_expanded(tpOpen[0]); + expcontrast->set_expanded(tpOpen[1]); + expchroma->set_expanded(tpOpen[2]); + exptoning->set_expanded(tpOpen[3]); + expnoise->set_expanded(tpOpen[4]); + expedge->set_expanded(tpOpen[5]); + expbl->set_expanded(tpOpen[6]); + expgamut->set_expanded(tpOpen[7]); + expresid->set_expanded(tpOpen[8]); + expfinal->set_expanded(tpOpen[9]); + expclari->set_expanded(tpOpen[10]); } } diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 6551b58d4..d1b4bb7c3 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -20,12 +20,13 @@ #pragma once #include + #include "adjuster.h" -#include "toolpanel.h" -#include "curvelistener.h" -#include "thresholdadjuster.h" #include "colorprovider.h" +#include "curvelistener.h" #include "guiutils.h" +#include "thresholdadjuster.h" +#include "toolpanel.h" class CurveEditor; class CurveEditorGroup; @@ -43,21 +44,22 @@ class Wavelet final : public FoldableToolPanel { public: - Wavelet (); - ~Wavelet () override; + Wavelet(); + ~Wavelet() override; - bool wavComputed_ (); + bool wavComputed_(); void adjusterChanged(Adjuster* a, double newval) override; - void autoOpenCurve () override; - void curveChanged (CurveEditor* ce) override; - void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; - void setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd, bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool tmrsadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd, bool gammaadd, bool edgedetectadd, bool edgedetectthradd, bool edgedetectthr2add); - void setBatchMode (bool batchMode) override; - void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; - void setEditProvider (EditDataProvider *provider) override; - void updateToolState (std::vector &tpOpen); - void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; - void writeOptions (std::vector &tpOpen); + void autoOpenCurve() override; + void curveChanged(CurveEditor* ce) override; + void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; +// void setAdjusterBehavior(bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd, bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool tmrsadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd, bool gammaadd, bool edgedetectadd, bool edgedetectthradd, bool edgedetectthr2add); + void setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd, bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool tmrsadd, bool edgsadd, bool scaleadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool radiusadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd, bool gammaadd, bool edgedetectadd, bool edgedetectthradd, bool edgedetectthr2add); + void setBatchMode(bool batchMode) override; + void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; + void setEditProvider(EditDataProvider *provider) override; + void updateToolState(const std::vector& tpOpen); + void write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; + void writeOptions(std::vector &tpOpen); void adjusterChanged(ThresholdAdjuster* a, double newBottom, double newTop) override; void adjusterChanged(ThresholdAdjuster* a, double newBottomLeft, double newTopLeft, double newBottomRight, double newTopRight) override; @@ -66,38 +68,67 @@ public: void adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) override; private: - void foldAllButMe (GdkEventButton* event, MyExpander *expander); + rtengine::ProcEvent EvWavenaclari; + rtengine::ProcEvent EvWavushamet; + rtengine::ProcEvent EvWavballum; + rtengine::ProcEvent EvWavbalchrom; + rtengine::ProcEvent EvWavchromfi; + rtengine::ProcEvent EvWavchromco; + rtengine::ProcEvent EvWavmergeL; + rtengine::ProcEvent EvWavmergeC; + rtengine::ProcEvent EvWavsoftrad; + rtengine::ProcEvent EvWavsoftradend; + rtengine::ProcEvent EvWavshowmask; + rtengine::ProcEvent EvWavedgs; + rtengine::ProcEvent EvWavscale; + rtengine::ProcEvent EvWavradius; + rtengine::ProcEvent EvWavsigma; + rtengine::ProcEvent EvWavenabl; + rtengine::ProcEvent EvWavchrwav; + rtengine::ProcEvent EvWavoldsh; + rtengine::ProcEvent EvWavoffset; + rtengine::ProcEvent EvWavlowthr; + rtengine::ProcEvent EvWavbluwav; + rtengine::ProcEvent EvWavblshape; + rtengine::ProcEvent EvWavresblur; + rtengine::ProcEvent EvWavresblurc; + rtengine::ProcEvent EvWavedgeffect; - void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) override; - void BAmethodChanged (); - void NPmethodChanged (); - void BackmethodChanged (); - void CHSLmethodChanged (); - void CHmethodChanged (); - void CLmethodChanged (); - void DirmethodChanged (); - void EDmethodChanged (); - void HSmethodChanged (); - void LmethodChanged (); - void MedgreinfChanged (); - void TMmethodChanged (); - void TilesmethodChanged (); - void avoidToggled (); - void cbenabToggled (); - void contrastMinusPressed (); - void contrastPlusPressed (); - void daubcoeffmethodChanged (); - void enabledChanged () override; - void linkedgToggled (); - void lipstToggled (); - void medianToggled (); - void medianlevToggled (); - void neutralPressed (); - void neutral_pressed (); - void neutralchPressed (); - void tmrToggled (); + void foldAllButMe(GdkEventButton* event, MyExpander *expander); + + void colorForValue(double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) override; + void BAmethodChanged(); + void NPmethodChanged(); + void BackmethodChanged(); + void CHSLmethodChanged(); + void CHmethodChanged(); + void CLmethodChanged(); + void DirmethodChanged(); + void EDmethodChanged(); + void HSmethodChanged(); + void LmethodChanged(); + void MedgreinfChanged(); + void TMmethodChanged(); + void TilesmethodChanged(); + void avoidToggled(); + void showmaskToggled (); + void oldshToggled (); + void cbenabToggled(); + void contrastMinusPressed(); + void contrastPlusPressed(); + void daubcoeffmethodChanged(); + void enabledChanged() override; + void linkedgToggled(); + void lipstToggled(); + void medianToggled(); + void medianlevToggled(); + void neutralPressed(); + void neutral_pressed(); + void neutralchPressed(); + void tmrToggled(); void updatewavLabel (); - void wavChanged (double nlevel) override; + void wavChanged(double nlevel) override; + void ushamethodChanged(); void HSmethodUpdateUI(); void CHmethodUpdateUI(); @@ -113,17 +144,18 @@ private: // void MedgreinfUpdateUI(); // void DirmethodUpdateUI(); // void LmethodUpdateUI(); - void adjusterUpdateUI (Adjuster* a); - void enabledUpdateUI (); - void medianlevUpdateUI (); - void cbenabUpdateUI (); - void lipstUpdateUI (); + void adjusterUpdateUI(Adjuster* a); + void enabledUpdateUI(); + void medianlevUpdateUI(); + void cbenabUpdateUI(); + void lipstUpdateUI(); - void enableToggled(MyExpander *expander); + void enableToggled(MyExpander* expander); CurveEditorGroup* const curveEditorG; CurveEditorGroup* const CCWcurveEditorG; + CurveEditorGroup* const curveEditorbl; CurveEditorGroup* const curveEditorRES; CurveEditorGroup* const curveEditorGAM; Gtk::HSeparator* const separatorNeutral; @@ -142,6 +174,7 @@ private: DiagonalCurveEditor* clshape; FlatCurveEditor* ccshape; + FlatCurveEditor* blshape; Gtk::CheckButton* const median; Gtk::CheckButton* const medianlev; Gtk::CheckButton* const linkedg; @@ -149,14 +182,24 @@ private: Gtk::CheckButton* const lipst; Gtk::CheckButton* const avoid; Gtk::CheckButton* const tmr; + Gtk::CheckButton* const showmask; + Gtk::CheckButton* const oldsh; Gtk::Button* const neutralchButton; Adjuster* correction[9]; Adjuster* correctionch[9]; + Adjuster* const sigma; + Adjuster* const offset; + Adjuster* const lowthr; Adjuster* const rescon; Adjuster* const resconH; Adjuster* const reschro; + Adjuster* const resblur; + Adjuster* const resblurc; + Adjuster* const bluwav; Adjuster* const tmrs; + Adjuster* const edgs; + Adjuster* const scale; Adjuster* const gamma; Adjuster* const sup; Adjuster* const sky; @@ -166,13 +209,16 @@ private: Adjuster* const contrast; Adjuster* const thr; Adjuster* const thrH; + Adjuster* const radius; Adjuster* const skinprotect; Adjuster* const edgrad; + Adjuster* const edgeffect; Adjuster* const edgval; Adjuster* const edgthresh; Adjuster* const strength; Adjuster* const balance; Adjuster* const iter; + Adjuster* greenlow; Adjuster* bluelow; Adjuster* greenmed; @@ -199,6 +245,16 @@ private: Adjuster* const edgedetectthr2; Adjuster* const edgesensi; Adjuster* const edgeampli; + Adjuster* const ballum; + Adjuster* const balchrom; + Adjuster* const chromfi; + Adjuster* const chromco; + Adjuster* const mergeL; + Adjuster* const mergeC; + Adjuster* const softrad; + Adjuster* const softradend; + Adjuster* const chrwav; + MyComboBoxText* const Lmethod; sigc::connection Lmethodconn; MyComboBoxText* const CHmethod; @@ -227,13 +283,22 @@ private: sigc::connection Dirmethodconn; MyComboBoxText* const Medgreinf; sigc::connection MedgreinfConn; + MyComboBoxText* const ushamethod; + sigc::connection ushamethodconn; + Gtk::Frame* const chanMixerHLFrame; Gtk::Frame* const chanMixerMidFrame; Gtk::Frame* const chanMixerShadowsFrame; + Gtk::Frame* const shFrame; + Gtk::Frame* const contFrame; + Gtk::Frame* const blurFrame; + Gtk::Frame* const chromaFrame; + Gtk::Frame* const chroFrame; Gtk::Label* const wavLabels; Gtk::Label* const labmC; Gtk::Label* const labmNP; + Gtk::Label* const usharpLabel; MyExpander* const expchroma; MyExpander* const expcontrast; MyExpander* const expedge; @@ -243,18 +308,21 @@ private: MyExpander* const expresid; MyExpander* const expsettings; MyExpander* const exptoning; + MyExpander* const expclari; + MyExpander* const expbl; Gtk::HBox* const neutrHBox; + Gtk::HBox* const usharpHBox; - sigc::connection enableChromaConn, enableContrastConn, enableEdgeConn, enableFinalConn; + sigc::connection enableChromaConn, enableContrastConn, enableEdgeConn, enabletmConn, enableFinalConn, enableclariConn; sigc::connection enableNoiseConn, enableResidConn, enableToningConn; - sigc::connection medianConn, avoidConn, tmrConn, medianlevConn, linkedgConn, lipstConn, cbenabConn, neutralconn; + sigc::connection medianConn, avoidConn, tmrConn, medianlevConn, linkedgConn, lipstConn, cbenabConn, neutralconn, showmaskConn, oldshConn; sigc::connection neutralPressedConn; sigc::connection contrastPlusPressedConn; sigc::connection contrastMinusPressedConn; sigc::connection neutralchPressedConn; - bool lastmedian, lastmedianlev, lastlinkedg, lastavoid, lastlipst, lasttmr, lastcbenab; + bool lastmedian, lastmedianlev, lastlinkedg, lastavoid, lastlipst, lasttmr, lastcbenab, lastshowmask, lastoldsh; int nextnlevel; IdleRegister idle_register; diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index 2ab09c10a..5d1c907df 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -142,7 +142,7 @@ static double wbTemp2Slider(double temp) return sval; } -WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WBALANCE_LABEL"), false, true), wbp(nullptr), wblistener(nullptr) +WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WBALANCE_LABEL"), true, true), wbp(nullptr), wblistener(nullptr) { Gtk::Grid* methodgrid = Gtk::manage(new Gtk::Grid()); @@ -175,6 +175,14 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB row[methodColumns.colId] = i + 100; } + if (currType == WBEntry::Type::AUTO) { + // Creating the auto category + row = *(refTreeModel->append()); + row[methodColumns.colIcon] = wbPixbufs[toUnderlying(currType)]; + row[methodColumns.colLabel] = M("TP_WBALANCE_AUTO_HEADER"); + row[methodColumns.colId] = i + 100; + } + if (currType == WBEntry::Type::WATER) { // Creating the under water subcategory header row = *(refTreeModel->append()); @@ -213,6 +221,7 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB || currType == WBEntry::Type::WATER || currType == WBEntry::Type::FLASH || currType == WBEntry::Type::LED + || currType == WBEntry::Type::AUTO ) { childrow = *(refTreeModel->append(row.children())); childrow[methodColumns.colIcon] = wbPixbufs[toUnderlying(currType)]; @@ -315,6 +324,9 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB Gtk::Image* itempbiasL = Gtk::manage (new RTImage ("circle-blue-small.png")); Gtk::Image* itempbiasR = Gtk::manage (new RTImage ("circle-yellow-small.png")); + StudLabel = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); + StudLabel->set_tooltip_text(M("TP_WBALANCE_STUDLABEL_TOOLTIP")); + temp = Gtk::manage (new Adjuster (M("TP_WBALANCE_TEMPERATURE"), MINTEMP, MAXTEMP, 5, CENTERTEMP, itempL, itempR, &wbSlider2Temp, &wbTemp2Slider)); green = Gtk::manage (new Adjuster (M("TP_WBALANCE_GREEN"), MINGREEN, MAXGREEN, 0.001, 1.0, igreenL, igreenR)); equal = Gtk::manage (new Adjuster (M("TP_WBALANCE_EQBLUERED"), MINEQUAL, MAXEQUAL, 0.001, 1.0, iblueredL, iblueredR)); @@ -335,6 +347,7 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB boxgreen->pack_start(*igreenL); boxgreen->pack_start(*green); boxgreen->pack_start(*igreenR);*/ + pack_start(*StudLabel); pack_start (*temp); //pack_start (*boxgreen); @@ -448,6 +461,7 @@ void WhiteBalance::optChanged () methconn.block(prevState); return; } + StudLabel->hide(); if (opt != row[methodColumns.colId]) { @@ -463,6 +477,12 @@ void WhiteBalance::optChanged () const WBEntry& currMethod = WBParams::getWbEntries()[methodId]; tempBias->set_sensitive(currMethod.type == WBEntry::Type::AUTO); + bool autit = (currMethod.ppLabel == "autitcgreen"); + if (autit) { + StudLabel->show(); + } else { + StudLabel->hide(); + } switch (currMethod.type) { case WBEntry::Type::CAMERA: @@ -547,6 +567,8 @@ void WhiteBalance::optChanged () void WhiteBalance::spotPressed () { + StudLabel->hide(); + if (wblistener) { wblistener->spotWBRequested (getSize()); } @@ -683,6 +705,13 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) } tempBias->set_sensitive(wbValues.type == WBEntry::Type::AUTO); + bool autit = (wbValues.ppLabel == "autitcgreen"); + if (autit) { + StudLabel->show(); + } else { + StudLabel->hide(); + } + } setEnabled(pp->wb.enabled); @@ -868,7 +897,7 @@ int WhiteBalance::_setActiveMethod(Glib::ustring &label, Gtk::TreeModel::Childre if (row[methodColumns.colLabel] == label) { method->set_active(iter); - found = method->get_active_row_number(); + found = row[methodColumns.colId]; } if (found != -1) { @@ -901,15 +930,19 @@ inline Gtk::TreeRow WhiteBalance::getActiveMethod () return *(method->get_active()); } -void WhiteBalance::WBChanged(double temperature, double greenVal) +void WhiteBalance::WBChanged(double temperature, double greenVal, float studgood) { idle_register.add( - [this, temperature, greenVal]() -> bool + [this, temperature, greenVal, studgood]() -> bool { disableListener(); setEnabled(true); temp->setValue(temperature); green->setValue(greenVal); + StudLabel->set_text( + Glib::ustring::compose(M("TP_WBALANCE_STUDLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(4), studgood)) + ); temp->setDefault(temperature); green->setDefault(greenVal); enableListener(); diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h index b4d09f119..17e45e8bb 100644 --- a/rtgui/whitebalance.h +++ b/rtgui/whitebalance.h @@ -43,6 +43,9 @@ class WhiteBalance final : public ToolParamBlock, public AdjusterListener, publi WBLT_PP }; +private: + Gtk::Label* StudLabel; + protected: class MethodColumns : public Gtk::TreeModel::ColumnRecord { @@ -119,7 +122,7 @@ public: wblistener = l; } void setWB (int temp, double green); - void WBChanged (double temp, double green) override; + void WBChanged (double temp, double green, float studgood) override; void setAdjusterBehavior (bool tempadd, bool greenadd, bool equaladd, bool tempbiasadd); void trimValues (rtengine::procparams::ProcParams* pp) override; diff --git a/tools/generateRtexifUpdates b/tools/generateRtexifUpdates index 72a97862e..b4ace209d 100755 --- a/tools/generateRtexifUpdates +++ b/tools/generateRtexifUpdates @@ -32,7 +32,10 @@ echo #------------------------------------------------------------------------------ # Canon printf '%s\n' "Saving ${tmpdir}/canon_lenses" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='LensType']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -canon:all) | sort -fuV > "${tmpdir}/canon_lenses" +xmlstarlet sel -T -t \ + -m "taginfo/table/tag[@name='LensType']/values/key" \ + -v "concat(@id,' ',val)" \ + -n < <("$et" -listx -canon:all) | sort -fuV > "${tmpdir}/canon_lenses" #In :10.1 Sigma 50mm f/2.8 EX #Out: {10, "Sigma 50mm f/2.8 EX"}, @@ -55,7 +58,11 @@ sed -r -i \ # replace with '] = "' # append '";' printf '%s\n' "Saving ${tmpdir}/canon_cameras" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='CanonModelID']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -canon:all) | sort -fuV > "${tmpdir}/canon_cameras" +xmlstarlet sel -T -t \ + -m "taginfo/table/tag[@name='CanonModelID']/values/key" \ + -v "concat(@id,' ',val)" \ + -n < <("$et" -listx -canon:all) | sort -fuV > "${tmpdir}/canon_cameras" + sed -r -i \ -e 's/^/ choices[/' \ -e 's/\t/] = "/' \ @@ -65,28 +72,84 @@ sed -r -i \ #------------------------------------------------------------------------------ # Nikon LensIDs are composite tags printf '%s\n' "Saving ${tmpdir}/nikon" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='LensID']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -composite:all) > "${tmpdir}/nikon" -sed -r -i -e '/^... /d' -e 's/^/ {"/' -e 's/([A-F0-9]+)[A-F0-9.]*\t/\1", "/' -e 's/$/"},/' -e 's|(.* ")(.*) F([0-9]+)|\1\2 f/\3|' -e 's| F/([0-9]+)| f/\1|' "${tmpdir}/nikon" + +xmlstarlet sel -T -t \ + -m "taginfo/table/tag[@name='LensID']/values/key" \ + -v "concat(@id,' ',val)" \ + -n < <("$et" -listx -composite:all) > "${tmpdir}/nikon" + +sed -r -i \ + -e '/^... /d' \ + -e 's/^/ {"/' \ + -e 's/([A-F0-9]+)[A-F0-9.]*\t/\1", "/' \ + -e 's/$/"},/' \ + -e 's|(.* ")(.*) F([0-9]+)|\1\2 f/\3|' \ + -e 's| F/([0-9]+)| f/\1|' \ + "${tmpdir}/nikon" #------------------------------------------------------------------------------ # Olympus printf '%s\n' "Saving ${tmpdir}/olympus" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='LensType']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -olympus:all) | sort -fuV > "${tmpdir}/olympus" -sed -r -i -e '/0 00 00\tNone/d' -e 's/^/ lenses["0/' -e 's/\t/"] = "/' -e 's/$/";/' -e 's| F([0-9]+)| f/\1|g' "${tmpdir}/olympus" + +xmlstarlet sel -T -t \ + -m "taginfo/table/tag[@name='LensType']/values/key" \ + -v "concat(@id,' ',val)" \ + -n < <("$et" -listx -olympus:all) | sort -fuV > "${tmpdir}/olympus" + +sed -r -i \ + -e '/0 00 00\tNone/d' \ + -e 's/^/ lenses["0/' \ + -e 's/\t/"] = "/' \ + -e 's/$/";/' \ + -e 's| F([0-9]+)| f/\1|g' \ + "${tmpdir}/olympus" #------------------------------------------------------------------------------ # Pentax printf '%s\n' "Saving ${tmpdir}/pentax" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='LensType']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -pentax:all) | sort -fuV > "${tmpdir}/pentax" -sed -r -i -e 's/^/ choices.insert (p_t (256 * /' -e 's/([0-9]+) ([0-9]+)([0-9.]*)/\1 + \2/' -e 's/\t/, "/' -e 's/$/"));/' -e 's| F([0-9]+)| f/\1|' "${tmpdir}/pentax" + +xmlstarlet sel -T -t \ + -m "taginfo/table/tag[@name='LensType']/values/key" \ + -v "concat(@id,' ',val)" \ + -n < <("$et" -listx -pentax:all) | sort -fuV > "${tmpdir}/pentax" + +sed -r -i \ + -e 's/^/ choices.insert (p_t (256 * /' \ + -e 's/([0-9]+) ([0-9]+)([0-9.]*)/\1 + \2/' \ + -e 's/\t/, "/' \ + -e 's/$/"));/' \ + -e 's| F([0-9]+)| f/\1|' \ + "${tmpdir}/pentax" #------------------------------------------------------------------------------ # Sony printf '%s\n' "Saving ${tmpdir}/sony" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='LensType']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -sony:all) | sort -fuV > "${tmpdir}/sony" + +xmlstarlet sel -T -t \ + -m "taginfo/table/tag[@name='LensType']/values/key" \ + -v "concat(@id,' ',val)" \ + -n < <("$et" -listx -sony:all) | sort -fuV > "${tmpdir}/sony" + # Sony has more lenses under the LensType2 tag printf '%s\n' "Saving ${tmpdir}/sony-lenstype2" -xmlstarlet sel -T -t -m "taginfo/table/tag[@name='LensType2']/values/key" -v "concat(@id,' ',val)" -n < <("$et" -listx -sony:all) | sort -fuV > "${tmpdir}/sony-lenstype2" -sed -r -i -e 's/^/ {/' -e 's/([0-9]+)[0-9.]*\t/\1, "/' -e 's/$/"},/' -e 's| F([0-9]+)| f/\1|g' "${tmpdir}/sony" -sed -r -i -e '/255\tTamron Lens (255)/d' -e 's/([0-9]+)[0-9.]*\t/\1, "/' -e 's/^/ choices.insert (p_t (/' -e 's/$/"));/' -e 's| F([0-9]+)| f/\1|g' "${tmpdir}/sony-lenstype2" + +xmlstarlet sel -T -t \ + -m "taginfo/table/tag[@name='LensType2']/values/key" \ + -v "concat(@id,' ',val)" \ + -n < <("$et" -listx -sony:all) | sort -fuV > "${tmpdir}/sony-lenstype2" + +sed -r -i \ + -e 's/^/ {/' \ + -e 's/([0-9]+)[0-9.]*\t/\1, "/' \ + -e 's/$/"},/' \ + -e 's| F([0-9]+)| f/\1|g' \ + "${tmpdir}/sony" + +sed -r -i \ + -e '/255\tTamron Lens (255)/d' \ + -e 's/([0-9]+)[0-9.]*\t/\1, "/' \ + -e 's/^/ choices.insert (p_t (/' \ + -e 's/$/"));/' \ + -e 's| F([0-9]+)| f/\1|g' \ + "${tmpdir}/sony-lenstype2" diff --git a/tools/osx/Info.plist-bin.in b/tools/osx/Info.plist-bin.in deleted file mode 100644 index 33abd4f7a..000000000 --- a/tools/osx/Info.plist-bin.in +++ /dev/null @@ -1,10 +0,0 @@ - - - - - CFBundleName - RawTherapee-bin - CFBundleIdentifier - com.rawtherapee.rawtherapee - - diff --git a/tools/osx/Info.plist.in b/tools/osx/Info.plist.in index eec1ab490..6970ed4da 100644 --- a/tools/osx/Info.plist.in +++ b/tools/osx/Info.plist.in @@ -1,7 +1,45 @@ - + LSEnvironment + + XDG_DATA_DIRS + /Applications/RawTherapee.app/Contents/Resources/share + DYLD_FALLBACK_LIBRARY_PATH + /Applications/RawTherapee.app/Contents/Frameworks + GTK_PATH + /Applications/RawTherapee.app/Contents/Frameworks + GTK_IM_MODULE_FILE + /Applications/RawTherapee.app/Contents/Resources/etc/gtk-3.0/gtk.immodules + GTK_MODULES + /Applications/RawTherapee.app/Contents/Frameworks/im-quartz.so + XDG_DATA_HOME + /Applications/RawTherapee.app/Contents/Resources/share + GSETTINGS_SCHEMA_DIR + /Applications/RawTherapee.app/Contents/Resources/share/glib-2.0/schemas + GDK_PIXBUF_MODULE_FILE + /Applications/RawTherapee.app/Contents/Resources/etc/gtk-3.0/gdk-pixbuf.loaders + GDK_PIXBUF_MODULEDIR + /Applications/RawTherapee.app/Contents/Frameworks + FONTCONFIG_PATH + /Applications/RawTherapee.app/Contents/Resources/etc/fonts + LIBDIR + /Applications/RawTherapee.app/Contents/Frameworks + DATADIR + /Applications/RawTherapee.app/Contents/Resources + GDK_RENDERING + similar + GTK_OVERLAY_SCROLLING + 0 + GDK_NATIVE_WINDOWS + 1 + + ATSApplicationFontsPath + etc/fonts + LSMultipleInstancesProhibited + + LSMinimumSystemVersion + @minimum_macos_version@ CFBundleDevelopmentRegion English CFBundleDisplayName @@ -21,7 +59,7 @@ CFBundleTypeRole Editor LSIsAppleDefaultForType - + LSItemContentTypes com.rawtherapee.pp3 @@ -115,7 +153,7 @@ CFBundleIconFile rawtherapee.icns CFBundleIdentifier - com.rawtherapee.rawtherapee + com.rawtherapee.RawTherapee CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -133,7 +171,7 @@ @arch@ NSHighResolutionCapable - + NSHumanReadableCopyright Copyright © 2004-2010 Gábor Horváth, 2010-2017 RawTherapee Development Team UTExportedTypeDeclarations @@ -164,4 +202,4 @@ - + \ No newline at end of file diff --git a/tools/osx/executable_loader.in b/tools/osx/executable_loader.in deleted file mode 100644 index 5ee609043..000000000 --- a/tools/osx/executable_loader.in +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh - -# GIMP has this next line regarding raising the number-of-open-files limit: -ulimit -n 7000 - -cd "$(dirname "$0")" || exit 1 - -cwd="$(pwd)" -app="/Applications/RawTherapee.app" -lib="${app}/Contents/Frameworks" -resources="${app}/Contents/Resources" -etc="${resources}/etc" -export XDG_DATA_DIRS="${resources}/share" -export DYLD_FALLBACK_LIBRARY_PATH="${lib}" -export GTK_PATH="${lib}/gtk-3.0/3.0.0" -export XDG_DATA_HOME="${resources}/share" -export GSETTINGS_SCHEMA_DIR="${resources}/share/glib-2.0/schemas" -export GDK_PIXBUF_MODULE_FILE="${etc}/gtk-3.0/gdk-pixbuf.loaders" -export GDK_PIXBUF_MODULEDIR="${lib}" - -export RT_SETTINGS="${HOME}/Library/Application Support/RawTherapee/config" -export RT_CACHE="${HOME}/Library/Application Support/RawTherapee/cache" - -# Strip out system argument -case "$1" in - -psn_*) shift ;; -esac - -# Prevent crash when directory name contains special characters -AppleLocale=`defaults read -g AppleLocale` -export LANG=${AppleLocale%@*}.UTF-8 - -exec "${app}/Contents/MacOS/bin/rawtherapee-bin" "$@" diff --git a/tools/osx/libiconv_1.14_rt.patch b/tools/osx/libiconv_1.14_rt.patch deleted file mode 100644 index 7a01b1373..000000000 --- a/tools/osx/libiconv_1.14_rt.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git a/lib/iconv.c b/lib/iconv.c -index 3785296..24a0f07 100644 ---- a/lib/iconv.c -+++ b/lib/iconv.c -@@ -607,4 +607,25 @@ strong_alias (libiconv, iconv) - strong_alias (libiconv_close, iconv_close) - #endif - -+#undef iconv_open -+#undef iconv -+#undef iconv_close -+ -+LIBICONV_DLL_EXPORTED iconv_t iconv_open (const char* tocode, const char* fromcode) -+{ -+ return libiconv_open(tocode, fromcode); -+} -+ -+LIBICONV_DLL_EXPORTED size_t iconv (iconv_t icd, -+ ICONV_CONST char * * inbuf, size_t *inbytesleft, -+ char * * outbuf, size_t *outbytesleft) -+{ -+ return libiconv(icd, inbuf, inbytesleft, outbuf, outbytesleft); -+} -+ -+LIBICONV_DLL_EXPORTED int iconv_close (iconv_t icd) -+{ -+ return libiconv_close(icd); -+} -+ - #endif diff --git a/tools/osx/libiconv_1.15_rt.patch b/tools/osx/libiconv_1.15_rt.patch deleted file mode 100644 index ca434154b..000000000 --- a/tools/osx/libiconv_1.15_rt.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git a/lib/iconv.c b/lib/iconv.c -index 31853a7..630a498 100644 ---- a/lib/iconv.c -+++ b/lib/iconv.c -@@ -611,4 +611,25 @@ strong_alias (libiconv, iconv) - strong_alias (libiconv_close, iconv_close) - #endif - -+#undef iconv_open -+#undef iconv -+#undef iconv_close -+ -+LIBICONV_DLL_EXPORTED iconv_t iconv_open (const char* tocode, const char* fromcode) -+{ -+ return libiconv_open(tocode, fromcode); -+} -+ -+LIBICONV_DLL_EXPORTED size_t iconv (iconv_t icd, -+ ICONV_CONST char * * inbuf, size_t *inbytesleft, -+ char * * outbuf, size_t *outbytesleft) -+{ -+ return libiconv(icd, inbuf, inbytesleft, outbuf, outbytesleft); -+} -+ -+LIBICONV_DLL_EXPORTED int iconv_close (iconv_t icd) -+{ -+ return libiconv_close(icd); -+} -+ - #endif diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index 08740f696..9258810c0 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -34,27 +34,43 @@ function CheckLink { done } +function ModifyInstallNames { + find -E "${CONTENTS}" -type f -regex '.*/(rawtherapee-cli|rawtherapee|.*\.(dylib|so))' | while read -r x; do + msg "Modifying install names: ${x}" + { + # id + if [[ ${x:(-6)} == ".dylib" ]] || [[ f${x:(-3)} == ".so" ]]; then + install_name_tool -id /Applications/"${LIB}"/$(basename ${x}) ${x} + fi + GetDependencies "${x}" | while read -r y + do + install_name_tool -change ${y} /Applications/"${LIB}"/$(basename ${y}) ${x} + done + } | bash -v + done +} + # Source check -if [[ ! -d "${CMAKE_BUILD_TYPE}" ]]; then +if [[ ! -d $CMAKE_BUILD_TYPE ]]; then msgError "${PWD}/${CMAKE_BUILD_TYPE} folder does not exist. Please execute 'make install' first." exit 1 fi # Update project version -if [[ -x "$(which git)" && -d "${PROJECT_SOURCE_DIR}/.git" ]]; then +if [[ -x $(which git) && -d $PROJECT_SOURCE_DIR/.git ]]; then ### This section is copied from tools/generateReleaseInfo # Get version description. # Depending on whether you checked out a branch (dev) or a tag (release), # "git describe" will return "5.0-gtk2-2-g12345678" or "5.0-gtk2", respectively. gitDescribe="$(git describe --tags --always)" - + # Apple requires a numeric version of the form n.n.n # https://goo.gl/eWDQv6 - + # Get number of commits since tagging. This is what gitDescribe uses. # Works when checking out branch, tag or commit. gitCommitsSinceTag="$(git rev-list --count HEAD --not $(git tag --merged HEAD))" - + # Create numeric version. # This version is nonsense, either don't use it at all or use it only where you have no other choice, e.g. Inno Setup's VersionInfoVersion. # Strip everything after hyphen, e.g. "5.0-gtk2" -> "5.0", "5.1-rc1" -> "5.1" (ergo BS). @@ -65,14 +81,13 @@ if [[ -x "$(which git)" && -d "${PROJECT_SOURCE_DIR}/.git" ]]; then gitVersionNumericBS="${gitVersionNumericBS}.${gitCommitsSinceTag}" # Remove everything until after first hyphen: 5.0 fi ### Copy end. - + PROJECT_FULL_VERSION="$gitDescribe" PROJECT_VERSION="$gitVersionNumericBS" - fi MINIMUM_SYSTEM_VERSION="$(otool -l "${CMAKE_BUILD_TYPE}"/MacOS/rawtherapee | grep -A2 'LC_VERSION_MIN_MACOSX' | awk '$1 ~ /version/ { printf $2 }')" -if [[ -z "${MINIMUM_SYSTEM_VERSION}" ]]; then +if [[ -z $MINIMUM_SYSTEM_VERSION ]]; then MINIMUM_SYSTEM_VERSION="$(sw_vers -productVersion | cut -d. -f-2)" fi @@ -89,9 +104,33 @@ GTK_PREFIX: ${GTK_PREFIX} PWD: ${PWD} __EOS__ -LOCAL_PREFIX="$(cmake .. -LA -N | grep "LOCAL_PREFIX" | cut -d "=" -f2)" -EXPATLIB="$(cmake .. -LA -N | grep "pkgcfg_lib_EXPAT_expat" | cut -d "=" -f2)" - +minimum_macos_version=${MINIMUM_SYSTEM_VERSION} + +# Retreive cached values from cmake + +#In: LOCAL_PREFIX:STRING=/opt +#Out: /opt +LOCAL_PREFIX="$(cmake .. -L -N | grep LOCAL_PREFIX)"; LOCAL_PREFIX="${LOCAL_PREFIX#*=}" + +#In: pkgcfg_lib_EXPAT_expat:FILEPATH=/opt/local/lib/libexpat.dylib +#Out: /opt/local/lib/libexpat.dylib +EXPATLIB="$(cmake .. -LA -N | grep pkgcfg_lib_EXPAT_expat)"; pkgcfg_lib_EXPAT_expat="${pkgcfg_lib_EXPAT_expat#*=}" + +#In: CODESIGNID:STRING=Developer ID Application: Doctor Who (1234567890) +#Out: Developer ID Application: Doctor Who (1234567890) +CODESIGNID="$(cmake .. -L -N | grep CODESIGNID)"; CODESIGNID="${CODESIGNID#*=}" + +#In: NOTARY:STRING=--username drwho@bbc.com --password abcd-efgh-hijk-lmno +#Out: --username drwho@bbc.com --password abcd-efgh-hijk-lmno +NOTARY="$(cmake .. -L -N | grep NOTARY)"; NOTARY="${NOTARY#*=}" + +# In: FANCY_DMG:BOOL=ON +# Out: ON +FANCY_DMG="$(cmake .. -L -N | grep FANCY_DMG)"; FANCY_DMG="${FANCY_DMG#*=}" +if [[ -n $FANCY_DMG ]]; then + echo "Fancy .dmg build is ON." +fi + APP="${PROJECT_NAME}.app" CONTENTS="${APP}/Contents" RESOURCES="${CONTENTS}/Resources" @@ -102,17 +141,27 @@ EXECUTABLE="${MACOS}/rawtherapee" GDK_PREFIX="${LOCAL_PREFIX}/local/" msg "Removing old files:" -rm -rf "${APP}" "${PROJECT_NAME}_*.dmg" "*zip" +rm -rf "${APP}" *.dmg *.zip msg "Creating bundle container:" -install -d "${RESOURCES}" \ - "${MACOS}" \ - "${LIB}" \ - "${ETC}" +install -d "${RESOURCES}" +install -d "${MACOS}" +install -d "${LIB}" +install -d "${ETC}" -msg "Copying release files:" +msg "Copying binary executable files." ditto "${CMAKE_BUILD_TYPE}/MacOS" "${MACOS}" -ditto "Resources" "${RESOURCES}" + +msg "Copying Resources directory." +cp AboutThisBuild.txt "${RESOURCES}" +ditto "${CMAKE_BUILD_TYPE}/Resources" "${RESOURCES}" + +echo "\n--------\n" >> "${RESOURCES}/AboutThisBuild.txt" +echo "Bundle system: $(sysctl -n machdep.cpu.brand_string)" >> "${RESOURCES}/AboutThisBuild.txt" +echo "Bundle OS: $(sw_vers -productName) $(sw_vers -productVersion) $(sw_vers -buildVersion) $(uname -mrs)" >> "${RESOURCES}/AboutThisBuild.txt" +echo "Bundle date: $(date -Ru) UTC" >> "${RESOURCES}/AboutThisBuild.txt" +echo "Bundle epoch: $(date +%s)" >> "${RESOURCES}/AboutThisBuild.txt" +echo "Bundle UUID: $(uuidgen|tr 'A-Z' 'a-z')" >> "${RESOURCES}/AboutThisBuild.txt" # Copy the Lensfun database into the app bundle mkdir -p "${RESOURCES}/share/lensfun" @@ -124,9 +173,12 @@ ditto ${LOCAL_PREFIX}/local/lib/liblensfun.2.dylib "${CONTENTS}/Frameworks/lible # Copy libomp to Frameworks ditto ${LOCAL_PREFIX}/local/lib/libomp.dylib "${CONTENTS}/Frameworks" -msg "Copying dependencies from ${GTK_PREFIX}:" +msg "Copying dependencies from ${GTK_PREFIX}." CheckLink "${EXECUTABLE}" +# dylib install names +ModifyInstallNames + # Copy libjpeg-turbo ("62") into the app bundle ditto ${LOCAL_PREFIX}/local/lib/libjpeg.62.dylib "${CONTENTS}/Frameworks/libjpeg.62.dylib" @@ -168,11 +220,6 @@ ditto "${LIB}"/gtk-3.0/3*/immodules/*.{dylib,so} "${LIB}" rm -r "${LIB}"/gtk-3.0 rm -r "${LIB}"/gdk-pixbuf-2.0 -msg "Build glib database:" -mkdir -p ${RESOURCES}/share/glib-2.0 -ditto {"${LOCAL_PREFIX}/local","${RESOURCES}"}/share/glib-2.0/schemas -"${LOCAL_PREFIX}/local/bin/glib-compile-schemas" "${RESOURCES}/share/glib-2.0/schemas" - # GTK+3 themes msg "Copy GTK+3 theme and icon resources:" ditto {"${LOCAL_PREFIX}/local","${RESOURCES}"}/share/themes/Mac/gtk-3.0/gtk-keys.css @@ -189,32 +236,15 @@ ditto {"${LOCAL_PREFIX}/local","${RESOURCES}"}/share/icons/Adwaita/index.theme "${LOCAL_PREFIX}/local/bin/gtk-update-icon-cache" "${RESOURCES}/share/icons/Adwaita" ditto "${LOCAL_PREFIX}/local/share/icons/hicolor" "${RESOURCES}/share/icons/hicolor" -# Install names -find -E "${CONTENTS}" -type f -regex '.*/(rawtherapee-cli|rawtherapee|.*\.(dylib|so))' | while read -r x; do - msg "Modifying install names: ${x}" - { - # id - case ${x} in *.dylib) echo " install_name_tool -id '@rpath/$(basename "${x}")' '${x}'";; esac - # names - GetDependencies "${x}" | while read -r y; do - echo " install_name_tool -change '${y}' '@rpath/$(basename "${y}")' '${x}'" - done - } | bash -v -done - -# fix @rpath in Frameworks -msg "Registering @rpath in Frameworks folder:" -for frameworklibs in ${CONTENTS}/Frameworks/* ; do - echo " install_name_tool -delete_rpath /opt/local/lib '${frameworklibs}'" | bash -v - echo " install_name_tool -add_rpath /Applications/RawTherapee.app/Contents/Frameworks '${frameworklibs}'" | bash -v -done - # pixbuf loaders & immodules msg "Build GTK3 databases:" "${LOCAL_PREFIX}"/local/bin/gdk-pixbuf-query-loaders "${LIB}"/libpix*.so > "${ETC}"/gtk-3.0/gdk-pixbuf.loaders "${LOCAL_PREFIX}"/local/bin/gtk-query-immodules-3.0 "${LIB}"/im-* > "${ETC}"/gtk-3.0/gtk.immodules sed -i "" -e "s|${PWD}/RawTherapee.app/Contents/|/Applications/RawTherapee.app/Contents/|" "${ETC}/gtk-3.0/gdk-pixbuf.loaders" "${ETC}/gtk-3.0/gtk.immodules" -sed -i "" -e "s|/opt/local/|/usr/|" "${ETC}/gtk-3.0/gtk.immodules" +sed -i "" -e "s|/opt/local/|/Applications/RawTherapee.app/Contents/Frameworks/|" "${ETC}/gtk-3.0/gtk.immodules" + +# Install names +ModifyInstallNames # Mime directory msg "Copying shared files from ${GTK_PREFIX}:" @@ -222,65 +252,70 @@ ditto {"${LOCAL_PREFIX}/local","${RESOURCES}"}/share/mime msg "Installing required application bundle files:" PROJECT_SOURCE_DATA_DIR="${PROJECT_SOURCE_DIR}/tools/osx" -ditto "${PROJECT_SOURCE_DIR}/build/Resources" "${RESOURCES}" -# Executable loader -# Note: executable is renamed to 'rawtherapee-bin'. -mkdir "${MACOS}/bin" -ditto "${MACOS}/rawtherapee" "${MACOS}/bin/rawtherapee-bin" -rm "${MACOS}/rawtherapee" -install -m 0755 "${PROJECT_SOURCE_DATA_DIR}/executable_loader.in" "${MACOS}/rawtherapee" +ditto "${CMAKE_BUILD_TYPE}/Resources" "${RESOURCES}" +ditto "${PROJECT_SOURCE_DIR}/rtdata/fonts" "${ETC}/fonts" + # App bundle resources ditto "${PROJECT_SOURCE_DATA_DIR}/"{rawtherapee,profile}.icns "${RESOURCES}" ditto "${PROJECT_SOURCE_DATA_DIR}/PkgInfo" "${CONTENTS}" install -m 0644 "${PROJECT_SOURCE_DATA_DIR}/Info.plist.in" "${CONTENTS}/Info.plist" -install -m 0644 "${PROJECT_SOURCE_DATA_DIR}/Info.plist-bin.in" "${CONTENTS}/MacOS/bin/Info.plist" sed -i "" -e "s|@version@|${PROJECT_FULL_VERSION}| s|@shortVersion@|${PROJECT_VERSION}| s|@arch@|${arch}|" \ - "${CONTENTS}/Info.plist" -plutil -convert xml1 "${CONTENTS}/Info.plist" -plutil -convert xml1 "${CONTENTS}/MacOS/bin/Info.plist" -update-mime-database -V "${CONTENTS}/Resources/share/mime" +"${CONTENTS}/Info.plist" +plutil -convert binary1 "${CONTENTS}/Info.plist" +update-mime-database -V "${RESOURCES}/share/mime" + +msg "Build glib database:" +mkdir -p ${RESOURCES}/share/glib-2.0 +ditto {"${LOCAL_PREFIX}/local","${RESOURCES}"}/share/glib-2.0/schemas +"${LOCAL_PREFIX}/local/bin/glib-compile-schemas" "${RESOURCES}/share/glib-2.0/schemas" # Append an LC_RPATH -msg "Registering @rpath into the executable:" -echo " install_name_tool -add_rpath /Applications/RawTherapee.app/Contents/Frameworks '${MACOS}/bin/rawtherapee-bin'" | bash -v -echo " install_name_tool -add_rpath /Applications/RawTherapee.app/Contents/Frameworks '${EXECUTABLE}-cli'" | bash -v +msg "Registering @rpath into the main executable." +install_name_tool -add_rpath /Applications/"${LIB}" "${EXECUTABLE}" -# Sign the app -msg "Codesigning:" -CODESIGNID="$(cmake .. -LA -N | grep "CODESIGNID" | cut -d "=" -f2)" -if ! test -z "$CODESIGNID" ; then -install -m 0644 "${PROJECT_SOURCE_DATA_DIR}/rt.entitlements" "${CONTENTS}/Entitlements.plist" -plutil -convert xml1 "${CONTENTS}/Entitlements.plist" -install -m 0644 "${PROJECT_SOURCE_DATA_DIR}/rt-bin.entitlements" "${CONTENTS}/MacOS/bin/Entitlements.plist" -plutil -convert xml1 "${CONTENTS}/MacOS/bin/Entitlements.plist" -codesign -v -s "${CODESIGNID}" -i "com.rawtherapee.rawtherapee-bin" -o runtime --timestamp --entitlements "${APP}/Contents/MacOS/bin/Entitlements.plist" "${APP}/Contents/MacOS/bin/rawtherapee-bin" -for frameworklibs in ${CONTENTS}/Frameworks/* ; do - codesign -v -s "${CODESIGNID}" -i "com.rawtherapee.rawtherapee-bin" -o runtime --timestamp "${frameworklibs}" +ModifyInstallNames + +# fix @rpath in Frameworks +msg "Registering @rpath in Frameworks folder." +for frameworklibs in "${LIB}"/*{dylib,so}; do + install_name_tool -delete_rpath ${LOCAL_PREFIX}/local/lib "${frameworklibs}" + install_name_tool -add_rpath /Applications/"${LIB}" "${frameworklibs}" done -codesign --deep --preserve-metadata=identifier,entitlements,runtime --timestamp --strict -v -s "${CODESIGNID}" -i "com.rawtherapee.RawTherapee" -o runtime --entitlements "${CONTENTS}/Entitlements.plist" "${APP}" -spctl -a -vvvv "${APP}" +install_name_tool -delete_rpath RawTherapee.app/Contents/Frameworks "${EXECUTABLE}"-cli +install_name_tool -add_rpath @executable_path "${EXECUTABLE}"-cli + +# Codesign the app +if [[ -n $CODESIGNID ]]; then + msg "Codesigning Application." + install -m 0644 "${PROJECT_SOURCE_DATA_DIR}"/rt.entitlements "${CMAKE_BUILD_TYPE}"/rt.entitlements + plutil -convert binary1 "${CMAKE_BUILD_TYPE}"/rt.entitlements + mv "${EXECUTABLE}"-cli "${LIB}" + for frameworklibs in "${LIB}"/*; do + codesign -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee --force --verbose -o runtime --timestamp "${frameworklibs}" + done + codesign --timestamp --strict -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee -o runtime --entitlements "${CMAKE_BUILD_TYPE}"/rt.entitlements "${APP}" + spctl -a -vvvv "${APP}" fi # Notarize the app -NOTARY="$(cmake .. -LA -N | grep "NOTARY" | cut -d "=" -f2)" -if ! test -z "$NOTARY" ; then +if [[ -n $NOTARY ]]; then msg "Notarizing the application:" ditto -c -k --sequesterRsrc --keepParent "${APP}" "${APP}.zip" uuid=`xcrun altool --notarize-app --primary-bundle-id "com.rawtherapee.RawTherapee" ${NOTARY} --file "${APP}.zip" 2>&1 | grep 'RequestUUID' | awk '{ print $3 }'` echo "Result= $uuid" # Display identifier string sleep 15 while : - do + do fullstatus=`xcrun altool --notarization-info "$uuid" ${NOTARY} 2>&1` # get the status status1=`echo "$fullstatus" | grep 'Status\:' | awk '{ print $2 }'` - if [ "$status1" = "success" ]; then + if [[ $status1 = "success" ]]; then xcrun stapler staple *app # staple the ticket xcrun stapler validate -v *app echo "Notarization success" break - elif [ "$status1" = "in" ]; then + elif [[ $status1 = "in" ]]; then echo "Notarization still in progress, sleeping for 15 seconds and trying again" sleep 15 else @@ -293,38 +328,55 @@ fi function CreateDmg { local srcDir="$(mktemp -dt $$)" - + msg "Preparing disk image sources at ${srcDir}:" cp -R "${APP}" "${srcDir}" - ditto AboutThisBuild.txt "${srcDir}" + cp "${RESOURCES}"/share/LICENSE.txt "${srcDir}" ln -s /Applications "${srcDir}" - + # Web bookmarks function CreateWebloc { defaults write "${srcDir}/$1" URL "$2" mv "${srcDir}/$1".{plist,webloc} } - CreateWebloc 'Website' 'http://www.rawtherapee.com/' - CreateWebloc 'Manual' 'http://rawpedia.rawtherapee.com/' - + CreateWebloc 'Website' 'https://www.rawtherapee.com/' + CreateWebloc 'Documentation' 'https://rawpedia.rawtherapee.com/' + CreateWebloc 'Forum' 'https://discuss.pixls.us/c/software/rawtherapee' + CreateWebloc 'Report Bug' 'https://github.com/Beep6581/RawTherapee/issues/new' + # Disk image name dmg_name="${PROJECT_NAME// /_}_OSX_${MINIMUM_SYSTEM_VERSION}_${PROC_BIT_DEPTH}_${PROJECT_FULL_VERSION}" lower_build_type="$(tr '[:upper:]' '[:lower:]' <<< "$CMAKE_BUILD_TYPE")" - if [[ ${lower_build_type} != release ]]; then + if [[ $lower_build_type != release ]]; then dmg_name="${dmg_name}_${lower_build_type}" fi - + msg "Creating disk image:" - hdiutil create -format UDBZ -fs HFS+ -srcdir "${srcDir}" -volname "${PROJECT_NAME}_${PROJECT_FULL_VERSION}" "${dmg_name}.dmg" - + if [[ ! -z $FANCY_DMG ]]; then + echo "Building Fancy .dmg" + mkdir "${srcDir}/.background" + cp -R "${PROJECT_SOURCE_DATA_DIR}/rtdmg.icns" "${srcDir}/.VolumeIcon.icns" + cp -R "${PROJECT_SOURCE_DATA_DIR}/rtdmg-bkgd.png" "${srcDir}/.background/background.png" + SetFile -c incC "${srcDir}/.VolumeIcon.icns" + create-dmg "${dmg_name}.dmg" "${srcDir}" \ + --volname "${PROJECT_NAME}_${PROJECT_FULL_VERSION}" \ + --volicon "${srcDir}/.VolumeIcon.icns" \ + --sandbox-safe \ + --no-internet-enable \ + --eula LICENSE.txt \ + --hdiutil-verbose \ + --rez /Library/Developer/CommandLineTools/usr/bin/Rez + else + hdiutil create -format UDBZ -fs HFS+ -srcdir "${srcDir}" -volname "${PROJECT_NAME}_${PROJECT_FULL_VERSION}" "${dmg_name}.dmg" + fi + # Sign disk image - if ! test -z "$CODESIGNID" ; then - codesign --deep --force -v -s "${CODESIGNID}" --timestamp "${dmg_name}.dmg" - fi - + if [[ -n $CODESIGNID ]]; then + codesign --deep --force -v -s "${CODESIGNID}" --timestamp "${dmg_name}.dmg" + fi + # Notarize the dmg - - if ! test -z "$NOTARY" ; then + if ! test -z "$NOTARY"; then msg "Notarizing the dmg:" zip "${dmg_name}.dmg.zip" "${dmg_name}.dmg" uuid=`xcrun altool --notarize-app --primary-bundle-id "com.rawtherapee" ${NOTARY} --file "${dmg_name}.dmg.zip" 2>&1 | grep 'RequestUUID' | awk '{ print $3 }'` @@ -334,31 +386,31 @@ function CreateDmg { do fullstatus=`xcrun altool --notarization-info "$uuid" ${NOTARY} 2>&1` # get the status status1=`echo "$fullstatus" | grep 'Status\:' | awk '{ print $2 }'` - if [ "$status1" = "success" ]; then + if [[ $status1 = "success" ]]; then xcrun stapler staple "${dmg_name}.dmg" # staple the ticket xcrun stapler validate -v "${dmg_name}.dmg" echo "dmg Notarization success" break - elif [ "$status1" = "in" ]; then + elif [[ $status1 = "in" ]]; then echo "dmg Notarization still in progress, sleeping for 15 seconds and trying again" sleep 15 else echo "dmg Notarization failed fullstatus below" echo "$fullstatus" - exit 1 + exit 1 fi done fi -# Zip disk image for redistribution + # Zip disk image for redistribution msg "Zipping disk image for redistribution:" - - zip "${dmg_name}.zip" "${dmg_name}.dmg" AboutThisBuild.txt + zip "${dmg_name}.zip" "${dmg_name}.dmg" rm "${dmg_name}.dmg" - msg "Removing disk image caches:" rm -rf "${srcDir}" } CreateDmg msg "Finishing build:" echo "Script complete." +# +# TODO filter out the benign errors diff --git a/tools/osx/rt-bin.entitlements b/tools/osx/rt-bin.entitlements deleted file mode 100644 index 9e5e269cb..000000000 --- a/tools/osx/rt-bin.entitlements +++ /dev/null @@ -1,8 +0,0 @@ - - - - -com.apple.security.inherit - - - \ No newline at end of file diff --git a/tools/osx/rt.entitlements b/tools/osx/rt.entitlements index 082661401..c571f1f41 100644 --- a/tools/osx/rt.entitlements +++ b/tools/osx/rt.entitlements @@ -1,20 +1,19 @@ - application-identifier - com.rawtherapee.rawtherapee + com.rawtherapee.RawTherapee com.apple.security.temporary-exception.files.absolute-path.read-write - "/" + / com.apple.security.cs.allow-dyld-environment-variables - + com.apple.security.files.user-selected.read-write - + com.apple.security.app-sandbox - + com.apple.security.files.downloads.read-write - + - + \ No newline at end of file diff --git a/tools/osx/rtdmg-bkgd.png b/tools/osx/rtdmg-bkgd.png new file mode 100644 index 000000000..ecd9b9d42 Binary files /dev/null and b/tools/osx/rtdmg-bkgd.png differ diff --git a/tools/osx/rtdmg.icns b/tools/osx/rtdmg.icns new file mode 100644 index 000000000..31b53c8ab Binary files /dev/null and b/tools/osx/rtdmg.icns differ